掲示板
Handling asynchronous requests
13年前 に Jakub Liska によって更新されました。
Handling asynchronous requests
Regular Member 投稿: 187 参加年月日: 10/03/25 最新の投稿
Hey,
could please anybody tell me, what is the proper way of handling http requests, that are not supposed to be ActionRequest because of their asynchronous nature ? Especially Multipart http requests. According to JSR 286 it seems like Mutlipart http requests should be handled either in Action phase or as a servlet requests outside of portal.
For instance, Ajax Multipart requests from flash uploaders. They are not meant to be Action requests because Action phase is followed by render phase right ? As it would be convenient in case of html form.
Some frameworks like Spring are using ResourceRequests for handling common Ajax requests, but there isn't mentioned anything about it handling Multipart requests (in JSR 286).
Then what remains is Render phase, which could be used for that, but it doesn't seem to be right. In spring-portlet-mvc there is practically no way to do that in some cases, because render phase is expected to render a view, not handle requests asynchronously.
In spring framework there are then these issues that I don't know how to deal with
SPR-7662
SPR-7910
My final though is, that Asynchronous requests should be handled by a servlet and not pointed to portal servlet to become a portlet requests, which is quite annoying and it causes lot of extra work. Or, as it is in Spring-portlet-mvc, use ResourceRequests as a workaround.
could please anybody tell me, what is the proper way of handling http requests, that are not supposed to be ActionRequest because of their asynchronous nature ? Especially Multipart http requests. According to JSR 286 it seems like Mutlipart http requests should be handled either in Action phase or as a servlet requests outside of portal.
For instance, Ajax Multipart requests from flash uploaders. They are not meant to be Action requests because Action phase is followed by render phase right ? As it would be convenient in case of html form.
Some frameworks like Spring are using ResourceRequests for handling common Ajax requests, but there isn't mentioned anything about it handling Multipart requests (in JSR 286).
Then what remains is Render phase, which could be used for that, but it doesn't seem to be right. In spring-portlet-mvc there is practically no way to do that in some cases, because render phase is expected to render a view, not handle requests asynchronously.
In spring framework there are then these issues that I don't know how to deal with
SPR-7662
SPR-7910
My final though is, that Asynchronous requests should be handled by a servlet and not pointed to portal servlet to become a portlet requests, which is quite annoying and it causes lot of extra work. Or, as it is in Spring-portlet-mvc, use ResourceRequests as a workaround.
13年前 に jelmer kuperus によって更新されました。
RE: Handling asynchronous requests
Liferay Legend 投稿: 1191 参加年月日: 10/03/10 最新の投稿
We specify windowState="exclusive" on the upload action url then set a render parameter that points to a json view, so the render result would actually return the success message to the upload component
13年前 に Jakub Liska によって更新されました。
RE: Handling asynchronous requests
Regular Member 投稿: 187 参加年月日: 10/03/25 最新の投稿
And you are talking about spring-portlet-mvc , or in general terms ?
I'm not sure I understand, you create an Action Request (as it is in document library uploader), set windowState="exclusive" so that portal doesn't create the html wrapper around the response.
And then, if you are using spring-portlet-mvc :
Without it it is really hard resolving for isntance JSPs and JSON views within a portlet / application context.
I'm not sure I understand, you create an Action Request (as it is in document library uploader), set windowState="exclusive" so that portal doesn't create the html wrapper around the response.
And then, if you are using spring-portlet-mvc :
- You can easily get Files from MultipartActionRequest
- But ActionResponse doesn't have a writer as ResourceResonse does, so that you can't do something like this
@ResourceMapping(value="sample")
protected void getJsonData(ResourceRequest request, ResourceResponse response) throws JsonGenerationException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
Map<string, string> numbers = new HashMap<string, string>();
nameStruct.put("one", "1");
nameStruct.put("two", "2");
Map<string, object> data = new HashMap<string, object>();
userData.put("numbers", number);
userData.put("etc", "etc");
response.setContentType(MediaType.APPLICATION_JSON.toString());
mapper.writeValue(response.getWriter(), data);
}</string,></string,></string,></string,>
- hence you must have some viewResolver that would take care of various resolving strategies (jsp, json) and ideally MappingJacksonJsonView, but it currently exists for spring-web-mvc only
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="ignoreAcceptHeader" value="true" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="jaxbMarshaller" />
</bean>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="objectMapper" ref="jaxbJacksonObjectMapper" />
</bean>
</list>
</property>
</bean>
Without it it is really hard resolving for isntance JSPs and JSON views within a portlet / application context.
13年前 に jelmer kuperus によって更新されました。
RE: Handling asynchronous requests
Liferay Legend 投稿: 1191 参加年月日: 10/03/10 最新の投稿But ActionResponse doesn't have a writer as ResourceResonse does, so that you can't do something like this
No I do something like this
@ActionMapping
public void upload(ActionResponse actionResponse, ...) {
// get your MultipartFile and do funky stuff with it
actionResponse.setRenderParameter("view", "success");
}
@RenderMapping(params = "view=success")
public String success() throws Exception {
return "someViewNameThatIsResolvedByABeanNameViewResolver";
}
Remember the render phase follows the action phase. So by setting the render parameter view to success at the end of the action i know that the success render method will be called next. Because the exclusive windowmode is used , the portal does not decorate the response this method will generate. So you have full control over the output and you can write your json
In my case return a string that points to a view thats picked up by a component scan element that looks somewhat like this
@Component("someViewNameThatIsResolvedByABeanNameViewResolver")
public class BindingResultJsonView extends AbstractView {
@Override
protected void renderMergedOutputModel(Map<string, object> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
JSONObject json = JSONFactoryUtil.createJSONObject();
// add stuff to the json
PrintWriter writer = response.getWriter();
writer.println(json.toString());
}
}</string,>
My view application context looks somewhat like this
<context:annotation-config />
<context:component-scan base-package="...." />
<bean id="portletMultipartResolver" class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver" />
<bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="1" />
</bean>
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="false" />
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/path/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>
13年前 に Jakub Liska によって更新されました。
RE: Handling asynchronous requests
Regular Member 投稿: 187 参加年月日: 10/03/25 最新の投稿
Thank you Jelmer,
I did exactly the same yesterday, but I ended up when ViewRendererServlet was trying to render my AjaxView. They were both in the same app context and I let spring instantiate it...so I don't know what the hell was that... But now I tried BeanNameViewResolver as you mentioned and it works like a charm...
Yesterday's code :
Strange errors
I did exactly the same yesterday, but I ended up when ViewRendererServlet was trying to render my AjaxView. They were both in the same app context and I let spring instantiate it...so I don't know what the hell was that... But now I tried BeanNameViewResolver as you mentioned and it works like a charm...
Yesterday's code :
public class AjaxView extends AbstractView {
private Logger logger = Logger.getLogger(AjaxView.class);
public AjaxView() {
super();
setContentType("application/json");
}
@Override
protected void renderMergedOutputModel(Map map, HttpServletRequest request, HttpServletResponse response)
throws Exception {
logger.info("Resolving ajax request view - " + map);
JSONObject jsonObj = new JSONObject(map);
logger.info("content Type = " + getContentType());
// response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(jsonObj.toString());
response.getWriter().flush();
}
<import resource="common.xml" />
<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<bean class="org.springframework.web.portlet.handler.ParameterMappingInterceptor" />
</property>
</bean>
<bean id="ajaxView" class="...spring.AjaxView" />
<bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean id="portletMultipartResolver" class="cz.instance.transl.util.LiferayMultipartNamespacesResolver" p:maxUploadSize="200480" p:portletNamespace="_2_WAR_brokerageportlet_" />
<bean id="validator" class="....DocFormValidator" />
<bean id="fileService" class="....FileService" />
<bean id="validateService" class="....ValidateService" />
<bean class="....UploadFormController" />
<bean class="....PostUploadFormController" />
<bean class="....AjaxUploadFormController">
<property name="ajaxView" ref="ajaxView" />
</bean>
@ActionMapping(params = "javax.portlet.action=test")
public void response(MultipartActionRequest request, ActionResponse response) {
response.setRenderParameter("javax.portlet.action", "test2");
List<multipartfile> fileList = request.getFiles("file");
}
@RequestMapping(params = "javax.portlet.action=example22")
public ModelAndView process(RenderRequest request, Model model) throws IOException {
Map map = new HashMap();
map.put("test", new Integer(2));
return new ModelAndView(ajaxView, map);
}
</multipartfile>
Strange errors
Caused by: java.lang.IllegalStateException: WebApplicationObjectSupport instance [cz.instance.transl.spring.AjaxView: name 'ajaxView'] does not run within a ServletContext. Make sure the object is fully configured!
at org.springframework.web.context.support.WebApplicationObjectSupport.getServletContext(WebApplicationObjectSupport.java:126)
at org.springframework.web.servlet.view.AbstractView.createRequestContext(AbstractView.java:267)
12年前 に SZ khan によって更新されました。
RE: Handling asynchronous requests
Regular Member 投稿: 145 参加年月日: 09/10/31 最新の投稿
Hi Jakub,
Did you solve this problem of yours
as I am getting the same problem using
org.springframework.web.servlet.view.ResourceBundleViewResolver
Thanks,
Sultee
Did you solve this problem of yours
does not run within a ServletContext. Make sure the object is fully configured!
as I am getting the same problem using
org.springframework.web.servlet.view.ResourceBundleViewResolver
Thanks,
Sultee
12年前 に Jakub Liska によって更新されました。
RE: Handling asynchronous requests
Regular Member 投稿: 187 参加年月日: 10/03/25 最新の投稿
I just used BeanNameViewResolver as Jelmer suggested and it worked.
11年前 に sona sun によって更新されました。
RE: Handling asynchronous requests
New Member 投稿: 1 参加年月日: 12/07/26 最新の投稿
Hi I am facing same issue,
How does your jsp looks like , I am trying to submit a form which I do not want to.
So the approach which you are following does that submits form
How does your jsp looks like , I am trying to submit a form which I do not want to.
So the approach which you are following does that submits form
9年前 に TyFiJC TY によって更新されました。
RE: Handling asynchronous requests
New Member 投稿: 1 参加年月日: 15/03/11 最新の投稿
Hello there - would you help me with the below:
I ran into the same issue and followed the way suggested above, so after the rendering phase, it suppose to component scan and find the view for e.g. AjaxView.java, but instead it looking for the view /WEB-INF/jsp/ajaxView.jsp to delegate to. below is the exception stack trace, any idea what is going on here? using Spring MVC Portlet v4.1.5 in WebSphere Portal v8
Caused by: java.lang.IllegalArgumentException: application/json not valid compared to [text/html]
at com.ibm.ws.portletcontainer.core.impl.PortletResponseImpl.setContentType(PortletResponseImpl.java:579)
at com.ibm.ws.portletcontainer.core.impl.RenderResponseImpl.setContentType(RenderResponseImpl.java:113)
at javax.portlet.filter.RenderResponseWrapper.setContentType(RenderResponseWrapper.java:139)
at javax.portlet.filter.RenderResponseWrapper.setContentType(RenderResponseWrapper.java:139)
at org.springframework.web.portlet.DispatcherPortlet.render(DispatcherPortlet.java:1126)
at org.springframework.web.portlet.DispatcherPortlet.doRenderService(DispatcherPortlet.java:789)
at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:536)
I ran into the same issue and followed the way suggested above, so after the rendering phase, it suppose to component scan and find the view for e.g. AjaxView.java, but instead it looking for the view /WEB-INF/jsp/ajaxView.jsp to delegate to. below is the exception stack trace, any idea what is going on here? using Spring MVC Portlet v4.1.5 in WebSphere Portal v8
Caused by: java.lang.IllegalArgumentException: application/json not valid compared to [text/html]
at com.ibm.ws.portletcontainer.core.impl.PortletResponseImpl.setContentType(PortletResponseImpl.java:579)
at com.ibm.ws.portletcontainer.core.impl.RenderResponseImpl.setContentType(RenderResponseImpl.java:113)
at javax.portlet.filter.RenderResponseWrapper.setContentType(RenderResponseWrapper.java:139)
at javax.portlet.filter.RenderResponseWrapper.setContentType(RenderResponseWrapper.java:139)
at org.springframework.web.portlet.DispatcherPortlet.render(DispatcherPortlet.java:1126)
at org.springframework.web.portlet.DispatcherPortlet.doRenderService(DispatcherPortlet.java:789)
at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:536)