Redirection to another portlet with ActionMapping - java

I am using Liferay and Spring MVC and I want to redirect to another portlet and pass it a parameter, but when I try to set render parameters I get this error:
15:20:24,859 ERROR [portal-web.docroot.html.portal.render_portlet_jsp] (http-foo-10.23.243.3-8080-7) java.lang.IllegalStateException: Set render parameter has already been called
at com.liferay.portlet.ActionResponseImpl.sendRedirect(ActionResponseImpl.java:48)
at sk.foo.showcasePortlet.ShowcaseController.redirect(ShowcaseController.java:65)
The showcaseController's method which is being resolved contains just the assignement and the redirect:
#ActionMapping(params = { "action=redirect" })
public void redirect(ActionRequest request, ActionResponse response)
throws IOException {
response.setRenderParameter("path", request.getParameter("path"));
response.sendRedirect("/path/to/portlet");
}
Why can't I assign that parameter? When I remove the line the redirection works, but the problem is that the portlet which the user is being redirected to expects a string parameter "path":
#RenderMapping
public String barBaz(RenderRequest request, #RequestParam String path){
// ...
return "some/jsp";
}
How can I pass the parameter to the barBaz method in another portlet, please?

You exception says this IllegalStateException: Set render parameter has already been called
Be aware that this interceptor is calling setRenderParameter on the ActionResponse, which means that you cannot call sendRedirect in your handler when using this interceptor. If you need to do external redirects then you will either need to forward the mapping parameter manually or write a different interceptor to handle this for you
DOC

Related

Weird Behavior When Dealing With POST Request Parameters

I'm working on a RESTful API, using Apache CXF as my JAX-RS implementation. I have a POST endpoint that's supposed to receive a request with three parameters. Here's a snippet of my code (modified and shortened):
#Path("endpoint_path")
public class MyResource {
#Context
private HttpServletRequest request;
#POST
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response postEndpoint(#QueryParam("param1") String param1,
#FormParam("param2") String param2,
#FormParam("param3") String param3) {
(use request as input for some library)
}
}
Inside that method, param2 and param3 both have the expected values, but if I check the request object's parameters (by using request.getParameterNames()), I only get one parameter -param1- instead of all three. I know for sure that I'm receiving all 3 parameters, param1 as a query parameter, and param2 and param3 as form parameters, because as I just said, I get their values passed as method parameters. They just don't seem to exists inside the request object.
This puzzled me so much, that I created a Filter that only does one thing, it peeks inside the request for the parameter names and does nothing else:
public class TestCXFPostParamsFilter implements Filter {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
servletRequest.getParameterNames();
filterChain.doFilter(servletRequest, servletResponse);
}
(init() and destroy() empty methods)
}
and in my web.xml file, I set the filter to apply to every request to my endpoint. Now here's where things get weird - for some reason, that makes everything work, by which I mean, if I check the request object back in the endpoint method, it'll contain all three expected parameters. What sorcery is this?
As a side note, some of you may be wondering why would I bother to check the request object, when I just said I have access to the parameter values that are passed to the method by CXF's servlet? The answer is that I'm using a library that expects you to pass the request object to it, instead of just the necessary values. So I really need the request to keep its parameters inside (like I always assumed it would).
Finally, I'm using Java 6, and CXF 2.7.10 (which comes with Apache Camel CXF 2.13.0). And yes, those are more or less set in stone for all intents and purposes, so if the reason all of this is happening is because of a bug in one of these pieces, I'm stuck with an useless filter as a "solution".

Spring MVC: How to set body parameter in request browser and how to get this body parameters in controller in Spring MVC?

I followed may links and found I need to use #Requestbody annotation and I need to set Content-Type=application/x-www-form-urlencoded in header under #RequestMapping annotation. But I did not find any example like how can I set these body parameters in browser and get in controller
#RequestMapping(value = "/login", headers="application/x-www-form-urlencoded" , method = RequestMethod.GET)
public void login(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServiceException {
// I need username and password body parameters value in controller
}
You would need something like Postman client in the browser.
You can install it from here. After installation, you can refer to answer to this question to know how to use it.

Returning JSON with spring on 404 in XML free project

I am currently setting up a Spring MVC application (version 4.1.4.RELEASE) and I want the application to return a JSON string on a 404 error rather than the default html response. I am using Tomcat 8 as my server. I have what I think should be correct, however it isn't behaving in the manner that I expect. What I'm trying to do is based off of this answer.
public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
...
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration){
registration.setInitParameter("throwExceptionIfNoHandlerFound","true");
}
}
and then I have an exception controller (which is different than the question I based my solution off of, however I don't believe that is an issue as I am under the impression that #ControllerAdvice is an acceptable way to manage this based off of the Spring Docs. It looks something like:
#ControllerAdvice
public class GlobalExceptionController{
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Message handleMethodNotSupported(HttpServletRequest request){
...
}
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ExceptionHandler(NoSuchRequestHandlingMethodException.class)
public Message handleBadRequest(HttpServletRequest request){
...
}
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ExceptionHandler(NoHandlerFoundException.class)
public Message requestHandlingNoHandlerFound(HttpServletRequest request){
...
}
...
}
It continues to send back the default response. I know for a fact that it is hitting my customizeRegistration() function because breakpoints stop it, however, any breakpoints that I have in my GlobalException class are not hit. Also, the GlobalException class is within a package that is hit by a #ComponentScan() annotation, so I am fairly confident that it is also being handled by spring.
I assume I'm missing something obvious, any help would be greatly appreciated.
I don't think the return type you're trying to use is supported. Have you tried changing your return value to ResponseEntity or adding a #ResponseBody annotation?
From the docs:
A ModelAndView object (Servlet MVC or Portlet MVC).
A Model object, with the view name implicitly determined through a RequestToViewNameTranslator.
A Map object for exposing a model, with the view name implicitly determined through a RequestToViewNameTranslator.
A View object.
A String value which is interpreted as view name.
#ResponseBody annotated methods (Servlet-only) to set the response content. The return value will be converted to the response stream
using message converters.
An HttpEntity or ResponseEntity object (Servlet-only) to set response headers and content. The ResponseEntity body will be
converted and written to the response stream using message converters.
void if the method handles the response itself (by writing the response content directly, declaring an argument of type
ServletResponse / HttpServletResponse / RenderResponse for that
purpose) or if the view name is supposed to be implicitly determined
through a RequestToViewNameTranslator (not declaring a response
argument in the handler method signature; only applicable in a Servlet
environment).

forwarding from spring controller to a jsp file

I am trying to forward my request from a Spring-MVC controller method - to a JSP page.
My controller method is supposed to handle an Ajax request. By forwarding the request to the JSP file, I want the response to the Ajax request to be the (dynamic) HTML output of the JSP file.
What I have tried:
public ModelAndView ajaxResponse(HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("command", "hello world");
request.getRequestDispatcher("jspfile").forward(request, response);
return null;
}
This fails and I get "HTTP Status 404"
"jspfiles" is defined in a tiles config file to be directed to the actual jsp file. When I run the following method:
public String ajaxResponse(HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("command", "hello world");
return "jspfile";
}
... I get the content of the file as my Ajax response - but JSP tags in that file are not parsed) - hence I conclude that my tiles definition is correct (???).
My JSP file looks like this:
<%=command%>
So I want to get as my Ajax response the string "hello world".
Could you show me an example code of how to achieve my purpose?
Specifically I need to know:
What should be the controller method return type?
What should be the controller method actual return value (if it matters)?
How should I set the jsp file path in the request.getRequestDispatcher(...) so it would be recognized?
Have a look at the controller example here:
http://maestric.com/doc/java/spring/mvc
It's a bit out of date, but the concept of what you must do remains the same. Spring 3 has annotation-based ways to do a lot of what is in that example.

servlet which can call a method and pass the value extracted from the web request

i have a question on how a servlet call a method and pass the value extracted from the web request. A scenario in which a web request is processed in a web request, i need to call a method and pass in the values extracted from the web request. When the method returns a value, send the value in the web response. thanks
If I understand you right you need something like this:
public class MyNewServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String param = request.getParameter("paramname");
String result = MyBusinessClass.myBusinessMethod(param);
response.getWriter().append("The answer is: " + result);
}
}
When request comes from browser, it will first read web.xml and call service method of appropriate servlet. Then service method decide to call doPost or doGet method on the basis of request. Once you get parameter , you need to create object of requestDispatcher and call forward method which will send your response.

Categories