DeferredResult is not polling - spring

I am trying to create a multi user chat environment using the base example from https://github.com/rstoyanchev/spring-mvc-chat
I am not able to find what exactly is wrong with my code. The request is not polling it just keeps on firing request continuously to the server.
Following are my code snipets
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
applicationContext.xml
<mvc:annotation-driven>
<mvc:async-support default-timeout="30000" />
<mvc:message-converters register-defaults="false">
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
Controller
#Controller
#RequestMapping("/chat")
public class ChatController
{
#RequestMapping("messages")
#ResponseBody
public DeferredResult<List<String>> getMessages()
{
final DeferredResult<List<String>> deferredResult = new DeferredResult<List<String>>(30000l, Collections.emptyList());
this.chatRequests.put(deferredResult, 0);
deferredResult.onCompletion(new Runnable()
{
#Override
public void run()
{
chatRequests.remove(deferredResult);
}
});
List<String> messages = new ArrayList<String>();
messages.add("first");
if (!messages.isEmpty())
{
deferredResult.setResult(messages);
}
return deferredResult;
}
}
javascript
function chatModel(){
var started = false;
var that = this;
that.activePollingXhr = ko.observable(null);
function pollForMessages() {
that.activePollingXhr($.ajax({
url : contextPath + '/chat/messages',
type : "GET",
cache : false,
success : function(messages) {
console.log(messages);
},
error : function(xhr) {
if (xhr.statusText != "abort" && xhr.status != 503) {
console.log('Unable to Connect');
}
},
complete : pollForMessages
}));
}

Got the issue.
if we set results
deferredResult.setResult();
it dont wait so goes into recursive calling.

Related

Error Code 500 on Embedded Glassfish 4.1.1 with Arquillian

I am quite new to Java EE and Arquillian. I am getting problems if I want to deploy my simple project into the embedded glassfish 4.1.1 server. I can succesfully pass the deployment, but I can not access the methods that i implemented. I am getting error code 500, while i expect 200.
my deployment:
public class AuthTest
{
#Deployment(testable = false)
public static WebArchive createDeployment()
{
System.out.println("\nin createDeployment");
// File[] libs = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeAndTestDependencies().asFile();
WebArchive archive = ShrinkWrap.create(WebArchive.class, "ArquillianHepInterface.war")
.addClasses(AuthEndpoint.class)
.addPackage(Database.class.getPackage())
.addPackage(DeviceAccessDBEntry.class.getPackage())
.addPackage(WebsiteAccessDBEntry.class.getPackage())
.addPackage(DeviceInfo.class.getPackage())
.addPackage(LoginInfo.class.getPackage())
.addPackage(ResponseBoolean.class.getPackage())
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource(new File("src/main/webapp", "WEB-INF/web.xml"))
.addAsWebInfResource(new File("src/main/webapp", "WEB-INF/glassfish-web.xml"))
.addAsResource("META-INF/persistence.xml")
// .addAsLibraries(libs)
;
System.out.println("\nende createDeployment");
return archive;
}
#ArquillianResource
protected URL contextPath;
#Test
public void registerUUIDTest()
{
DeviceInfo newUser = new DeviceInfo();
newUser.setDate("2014-12-12");
newUser.setUuid("xyz");
Response i = expect().statusCode(200).when().given().
contentType("application/json").body(newUser)
.post(this.contextPath + "AUTHENTICATION/CREATEMOBILELOGIN")
;
}
my AuthEndpoint class:
#Path("/AUTHENTICATION")
public class AuthEndpoint
{
#Inject
private DatabaseInterface database;
#POST
#Produces({ "application/json" })
#Consumes({ "application/json" })
#Path("CREATEMOBILELOGIN")
public LoginInfo createMobileLogin(DeviceInfo info)
{
System.out.println("RICHTIGES FILE");
System.err.println();
LoginInfo response = null;
if (info != null && info.getUuid() != null)
{
String password = this.database.registerDevice(info.getUuid());
if (password != null)
{
response = new LoginInfo();
response.setPw(password);
response.setUuid(info.getUuid());
}
}
return response;
}
}
I am getting:
SEVERE: WebModule[/ArquillianHepInterface]StandardWrapper.Throwable
Why is that happening? I do not understand where my problem is...
I supposed that I have problems while I am using glassfish 4.1.1...? I want simply to call the Methods in the AuthEndpoint class throught the Arquillian TestClass to verify that a single have been created...
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Arquillian Rest Demo</display-name>
<servlet>
<display-name>JAX-RS REST Servlet</display-name>
<servlet-name>REST-Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>REST-Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
glassfish-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
<context-root>/ArquillianHepInterface</context-root>
<class-loader delegate="true" />
</glassfish-web-app>
My beans.xml file is empty.
The methods that AuthEndpoint uses are in another maven project that I have compiled and added in the maven dependencies...
I would appreciate any help...

Difference between Spring request scope and JSF request scope?

I am working on a JSR-286 portlet application that uses JSF 1.2. I am working on moving my JSF managed beans to Spring beans, and I noticed what appears to a difference between how Spring is treating request scope from how JSF is treating request scope.
In my portlet application, I have two portlets that live on the same page and both use the same starting JSF portlet page view. When I use JSF managed request beans, there is an individual request bean created for each portlet, which is the behavior I am looking for. When I use Spring beans, only one request bean is created and is shared among both portlets. Is this normal behavior? Is there any way I can stop it from doing this?
My original faces-config.xml file, before moving my beans to Spring:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<application>
<state-manager>com.ibm.faces.application.DevelopmentStateManager</state-manager>
<variable-resolver>com.ibm.faces.portlet.PortletVariableResolver</variable-resolver>
</application>
<factory>
<faces-context-factory>com.ibm.faces.context.AjaxFacesContextFactory</faces-context-factory>
<render-kit-factory>com.ibm.faces.renderkit.AjaxRenderKitFactory</render-kit-factory>
</factory>
<managed-bean>
<managed-bean-name>sessionBean</managed-bean-name>
<managed-bean-class>sanitycheck.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>pc_SanityCheckProjectView</managed-bean-name>
<managed-bean-class>sanitycheck.SanityCheckProjectView</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>sessionBean</property-name>
<value>#{sessionBean}</value>
</managed-property>
</managed-bean>
<lifecycle>
<phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener>
</lifecycle>
</faces-config>
My faces-config.xml file after moving beans to Spring:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<application>
<state-manager>com.ibm.faces.application.DevelopmentStateManager</state-manager>
<variable-resolver>com.ibm.faces.portlet.PortletVariableResolver</variable-resolver>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
<factory>
<faces-context-factory>com.ibm.faces.context.AjaxFacesContextFactory</faces-context-factory>
<render-kit-factory>com.ibm.faces.renderkit.AjaxRenderKitFactory</render-kit-factory>
</factory>
<lifecycle>
<phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener>
</lifecycle>
</faces-config>
And my spring-web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="sessionBean" class="sanitycheck.SessionBean" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="pc_SanityCheckProjectView" class="pagecode.SanityCheckProjectView" scope="request" init-method="init">
<aop:scoped-proxy/>
<property name="sessionBean" ref="sessionBean"/>
</bean>
</beans>
I can provide my other files if necessary, just let me know. Thanks!
Edit: Added aop:scoped-proxy to the Spring beans.
Edit: Adding portlet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" id="com.ibm.faces.portlet.FacesPortlet.3a22ca3014">
<portlet>
<portlet-name>SanityCheckProject</portlet-name>
<display-name xml:lang="en">SanityCheckProject</display-name>
<display-name>SanityCheckProject</display-name>
<portlet-class>com.ibm.faces.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/SanityCheckProjectView.jsp</value>
</init-param>
<init-param>
<name>whichOne</name>
<value>Portlet1</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.ibm.sanitycheckproject.nl.SanityCheckProjectPortletResource</resource-bundle>
<portlet-info>
<title>SanityCheckProject</title>
<short-title>SanityCheckProject</short-title>
<keywords>SanityCheckProject</keywords>
</portlet-info>
</portlet>
<portlet>
<portlet-name>SanityCheckPortlet2</portlet-name>
<display-name xml:lang="en">SanityCheckPortlet2</display-name>
<display-name>SanityCheckPortlet2</display-name>
<portlet-class>com.ibm.faces.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/SanityCheckProjectView.jsp</value>
</init-param>
<init-param>
<name>whichOne</name>
<value>Portlet2</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.ibm.sanitycheckproject.nl.SanityCheckPortlet2PortletResource</resource-bundle>
<portlet-info>
<title>SanityCheckPortlet2</title>
<short-title>SanityCheckPortlet2</short-title>
<keywords>SanityCheckPortlet2</keywords>
</portlet-info>
</portlet>
<default-namespace>http://SanityCheckProject/</default-namespace>
</portlet-app>
In Spring XML config, you must use the <aop:scoped-proxy/> tag.
http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes-other-injection
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- this next element effects the proxying of the surrounding bean -->
<aop:scoped-proxy/>
</bean>
I don't know if this was the best or even a very good solution, but what I eventually did was create two custom portlet scopes, one for request scope, and one for session scope. Essentially what my custom scopes do is that they prefix the name of the object requested with the portlet's namespace, which seems to keep everything separated.
Here is the code I used for my scopes:
Request Scope:
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.web.context.request.RequestScope;
import com.ibm.faces.portlet.httpbridge.ActionResponseWrapper;
import javax.portlet.RenderResponse;
import javax.portlet.filter.RenderResponseWrapper;
public class PortletRequestScope extends RequestScope {
#Override
public Object get(String name, ObjectFactory objectFactory) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else {
writeError(response);
}
return super.get(name, objectFactory);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else {
writeError(response);
}
super.registerDestructionCallback(name, callback);
}
#Override
public Object remove(String name) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else {
writeError(response);
}
return super.remove(name);
}
protected void writeError(Object response) {
System.err.println("Error in PortletRequestScope");
System.err.println("Response is unrecognized class: " + response.getClass().getCanonicalName());
System.err.println("Please modify code to handle class");
}
}
Session Scope:
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.web.context.request.SessionScope;
import com.ibm.faces.portlet.httpbridge.ActionResponseWrapper;
import javax.portlet.RenderResponse;
import javax.portlet.filter.RenderResponseWrapper;
public class PortletSessionScope extends SessionScope {
#Override
public Object get(String name, ObjectFactory objectFactory) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else {
writeError(response);
}
return super.get(name, objectFactory);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else {
writeError(response);
}
super.registerDestructionCallback(name, callback);
}
#Override
public Object remove(String name) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else {
writeError(response);
}
return super.remove(name);
}
protected void writeError(Object response) {
System.err.println("Error in PortletSessionScope");
System.err.println("Response is unrecognized class: " + response.getClass().getCanonicalName());
System.err.println("Please modify code to handle class");
}
}
Then, in my spring-web.xml, I defined my custom scopes:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="portletRequestScope">
<bean class="com.test.scope.PortletRequestScope"/>
</entry>
<entry key="portletSessionScope">
<bean class="com.test.portlet.scope.PortletSessionScope"/>
</entry>
</map>
</property>
</bean>
And when I defined my actual Spring beans, I used my custom scopes instead of the regular scope -- for example:
<bean id="sessionBean" class="com.test.managedbeans.SessionBean"
scope="portletSessionScope" lazy-init="true"/>
At the very least, doing this seemed to work in my specific situation of JSF + Spring on WebSphere Portal, and hopefully this will be useful to someone else.

Spring #Secured method is not working when called through a filter that uses a Flying Saucer (Itext) ReplacedElementFactory implementation

When I call a Spring #Secured method that is found on a #Service class, through a normal #Controller class, the authentication is working correctly.
When I call the same method through an IText PDF filter, using a org.xhtmlrenderer.extend.ReplacedElementFactory implementation, I get the following stack trace:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:325)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:196)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
The security is obviously working because users without the required roles receive an Access Denied Exception, while other users with the correct roles have no issues at all.
Here is a snippet from my web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>pdfFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>pdfFilter</filter-name>
<url-pattern>/reports/pdf/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Here is a snippet of the ReplacedElementFactory implementation:
#Inject private ImageService imageService;
#Override
public ReplacedElement createReplacedElement(LayoutContext ctx, BlockBox box, UserAgentCallback uac, int width, int height) {
Element el = box.getElement();
if (el == null) {
return null;
}
String nodeName = el.getNodeName();
if (nodeName.equalsIgnoreCase("img")) {
String srcAttr = el.getAttribute("src");
FSImage fsImage;
try {
fsImage = getImage(srcAttr, uac);
}catch(BadElementException ex) {
fsImage = null;
}catch(IOException ex) {
fsImage = null;
}catch(NullPointerException ex) {
fsImage = null;
}
if (fsImage != null) {
if (width != -1 || height != -1) {
fsImage.scale(width, height);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
private FSImage getImage(String src, UserAgentCallback uac) throws IOException, BadElementException, NullPointerException {
FSImage fsImage;
String[] split = src.split("/");
if (src.contains("image/person/")) {
Long id = Long.valueOf( split[split.length - 1] );
Image img = imageService.getPersonImageByImageId(id);
fsImage = new ITextFSImage(com.lowagie.text.Image.getInstance(img.getImage()));
return fsImage;
}
Here is my ImageService class method:
#Secured({"ROLE_MY_ROLE_READ"})
public Image getPersonImageByImageId(Long imageId) {
return imageDao.findOne(imageId);
}
The failure happens on the call to the image service method, assumably because it is Secured and the ReplacedElementFactory implementation does not have access to the security context, but how do I authenticate?
I am new to posting, so please let me know if there is anything else required.
Not sure how you have configured your security to kick in. but if you have used for that also then check the ordering of the filter. The security filter should be before your pdffilter.

HttpInvokerServiceExporter + HttpInvokerProxyFactoryBean - Could not access HTTP invoker remote service

I'm trying to use HttpInvokerServiceExporter + HttpInvokerProxyFactoryBean, but whatever I do I get an exception:
org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [http://localhost:9999/testcaseapp/testcaseservice]; nested exception is java.io.IOException: Did not receive successful HTTP response: status code = 404, status message = [Not Found]
For the simplicity, I've created a test case.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class RemoteTest {
private static final Logger logger = LoggerFactory.getLogger("TestsLogger");
static interface TestCaseService {
public Integer add(Integer arg1, Integer arg2);
}
static class TestCaseServiceImpl implements TestCaseService {
public Integer add(Integer arg1, Integer arg2) {
return (arg1 != null ? arg1.intValue() : 0) + (arg2 != null ? arg2.intValue() : 0);
}
}
#Configuration
static class Config {
#Bean
public HttpInvokerServiceExporter httpInvokerServiceExporter() {
HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
httpInvokerServiceExporter.setService(new TestCaseServiceImpl());
httpInvokerServiceExporter.setServiceInterface(TestCaseService.class);
return httpInvokerServiceExporter;
}
#Bean
public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean = new HttpInvokerProxyFactoryBean();
httpInvokerProxyFactoryBean.setServiceInterface(TestCaseService.class);
httpInvokerProxyFactoryBean.setServiceUrl("http://localhost:9999/testcaseapp/testcaseservice");
httpInvokerProxyFactoryBean.afterPropertiesSet();
return httpInvokerProxyFactoryBean;
}
}
#Autowired
private TestCaseService[] testCaseServices;
private static Server server;
#BeforeClass
public static void setUp() {
try {
server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(9999);
server.addConnector(connector);
//
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/testcaseapp");
webAppContext.setWar("src/test/java/" + RemotingTest.class.getPackage().getName().replace('.', '/'));
server.setHandler(webAppContext);
//
server.start();
} catch (Exception ex) {
logger.info("Could not permorm the set up: {}", ex.toString());
}
}
#AfterClass
public static void destroy() {
try {
server.stop();
} catch (Exception e) {
}
}
#Test
public void addTest() {
for (TestCaseService testCaseService : testCaseServices) {
Integer sum = testCaseService.add(10, 5);
Assert.assertNotNull(sum);
Assert.assertEquals(15, sum.intValue());
}
}
}
I've also tried to create a TestCaseService bean
#Bean public TestCaseService testCaseService() ...
and provide it as a httpInvokerServiceExporter argument
#Bean public HttpInvokerServiceExporter httpInvokerServiceExporter(TestCaseService testCaseService)
...
httpInvokerServiceExporter.setService(testCaseService);
but the result is still the same.
What am I doing wrong? Thanks!
I think the problem is that the Servlet is not accesible.
SERVER SIDE
Make sure you have in your WEB-INF/web.xml (on the app that is exposing the methods -SERVER-) this code:
<web-app>
...
<servlet>
<servlet-name>remoting</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>remoting</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
...
</web-app>
Here, the remote methods are served under "services", that is, for calling the method, the URL should be:
http://localhost:8080/sample/services/list
And you have to define this Servlet as accesible, by creating a bean (in my case under WEB-INF/remoting-servlet.xml):
<bean name="/list" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="myObjectQueryService" />
<property name="serviceInterface" value="com.kategor.myapp.sample.service.ObjectQueryService" />
</bean>
CLIENT SIDE
If your using Spring under the client (not as in your example), you must define a bean for accessing the remote resources, defining some beans (one for each public resource):
In this case, it would be:
<bean id="listService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/sample/services/list" />
<property name="serviceInterface" value="com.kategor.myapp.sample.service.ObjectQueryService" />
</bean>
In your example is right.
This way, calling the Service "listService", you would have all the methods available in the class com.kategor.myapp.sample.service.ObjectQueryService
#Controller
public class HomeController {
// This is the remote service definition
#Autowired
private ObjectQueryService<MyObject, Long> objectQueryService;
/* .... */
/**
* List all Objects retrieved through Web Service from a remote Server
*/
#RequestMapping(value = "listRemoteWS", method = RequestMethod.GET)
public String listRemoteWS(Locale locale, Model model) {
StringBuilder result = new StringBuilder();
try {
// The Remote Service is called
List objs = objectQueryService.findAll(0, 10);
result.append(objs.size() + " objs found");
for (MyObject o : objs) {
result.append("<br>* ").append(o.getId()).append(" = ").append(o.getName());
}
} catch (Exception e) {
result.append("No objs have been found");
e.printStackTrace();
}
model.addAttribute("result", result);
return "index";
}
}
So I think the problem comes from the URL: maybe the service is not visible or this is not the correct path to it.
For more information, check this links (the first is really useful):
https://github.com/JamesEarlDouglas/barebones-spring-mvc/tree/master/reference/spring-remoting
http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html
For me the problem was tomcat picked up two versions of the same applications. This raised the above error on running the client from STS in debug mode.
So solution is to clean up all the expanded webapp folders in tomcat for the application. Then redeploy the application.

Primefaces fileupload works only for the first file to be uploaded

I am using Primefaces and I have an issue with the fileuploader. The problem is that it works fine with the first file I upload (the fileUploadListener is called and the java method uploads the file), but then if I try to upload another file, the listener is not called anymore and the java method is never triggered. If I refresh the page, I can upload another file but again if I try to upload a second one the same thing happens.
code within the xhtml file:
<p:tab id="eConsentTabPanel" title="Informed Consent" disabled="#{patientHandlerAction.patientTabsStatus}">
<h:form id="eConsentForm" enctype="multipart/form-data">
<h:panelGrid id="eConsentPanelGrid">
<p:fileUpload fileUploadListener="#{patientHandlerAction.handleFileUpload}"
mode="advanced"
update="messages"
multiple="true"
auto="true"
sizeLimit="20971520"
label="Select File"
allowTypes="/(\.|\/)(gif|jpe?g|png|pdf|doc?x)$/"/>
<p:growl id="messages" showDetail="true"/>
</h:panelGrid>
</h:form>
</p:tab>
code within the java bean file:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext=FacesContext.getCurrentInstance().getExternalContext();
String filename = FilenameUtils.getName(event.getFile().getFileName());
File result = new File(extContext.getRealPath("//uploaded//" + filename));
try {
FileOutputStream fileOutputStream = new FileOutputStream(result);
byte[] buffer = new byte[6124];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
messageTitle = "Message";
messageBody = "The file" + event.getFile().getFileName() + " was succesfully uploaded!";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, messageTitle, messageBody));
}
catch (IOException e) {
e.printStackTrace();
messageTitle = "Message";
messageBody = "The file was not uploaded";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, messageTitle, messageBody));
FacesMessage error = new FacesMessage(FacesMessage.SEVERITY_ERROR, "The files were not uploaded!", "");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
code within the web.xml file:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>
org.primefaces.webapp.filter.FileUploadFilter
</filter-class>
<init-param>
<param-name>uploadDirectory</param-name>
<param-value>/HerEhrUploaded/temp</param-value>
</init-param>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>20971520</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
I added :
event.getComponent().setTransient(false);
Inside file upload listener method,
public void handleUpload(FileUploadEvent event) {
....
}
It's works fine.
I had the same problem and I found a solution (more workaround than a solution) here:
http://code.google.com/p/primefaces/issues/detail?id=6157
It seems to be a problem with isTransient() method in the FileUpload component.
Hope it helps.
I think I have found what's wrong but I am not sure of what is causing this issue.
The xhtml page that I use to display the fileUpload component, has many tabs and each tab has it's own h:form. I created a new page that has only one form and the fileUpload component seems to work fine there.

Resources