I'm new to Spring and Portlet development.
I'm using the spring-webmvc-portlet but I think the workflow is almost the same with servlets.
My use case is pretty common but it's still a bit of a struggle to make everything work the way i would like to.
I got a controller like this :
@Controller
@RequestMapping(value = "VIEW")
@SessionAttributes(value = "persons")
public class MyController
// Display a list of person in personList.jsp
@RenderMapping(params = "actionPerson=query")
public String showList() {
return "personList";
}
@ActionMapping(params = "actionPerson=query"){
// Here is a trick I use to avoid the MissingPortletRequestParameterException
// to be raised
response.setRenderParameter("query","")
response.setRenderParameter("actionPerson","query");
}
// Return a list of person and store it in the model
@ModelAttribute("persons")
public List<Person> getPersons(@RequestParam(value="query") String query) {
List<Person> personList = personService.SearchByName(query);
return personList;
}
So far i understand that methods annoted with @ModelAttribute are invoked every time to generate the model before any rendering process.
I don't want this method to invoked every time. I tried to use the annotation @SessionAttributes to store my list of person in the handler’s conversational state.
My problem is the annotation @RequestParam raise the following expection :
org.springframework.web.portlet.bind.MissingPortletRequestParameterException: Required String parameter 'query' is not present
at org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter$PortletHandlerMethodInvoker.raiseMissingParameterException(AnnotationMethodHandlerAdapter.java:559)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:514)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:353)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:155)
at org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:369)
at org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter.doHandle(AnnotationMethodHandlerAdapter.java:356)
at org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter.handleRender(AnnotationMethodHandlerAdapter.java:296)
at org.springframework.web.portlet.DispatcherPortlet.doRenderService(DispatcherPortlet.java:764)
at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:537)
at org.springframework.web.portlet.FrameworkPortlet.doDispatch(FrameworkPortlet.java:483)
at javax.portlet.GenericPortlet.render(GenericPortlet.java:248)
My guess is even if the method getPersons is not invoked. The @RequestParam(value="query) is still evaluated.
When I display my list of person, users can select a person to get detailed informations. I would like them to go back to the list of result without submitting a new query.
How can i handle this case properly ? Is there a way to skip @RequestParam to be evaluated ?
Thanks !
You could make @RequestParam
as not required
. This would allow your request to succeed, but query
would then be null.
@ModelAttribute("persons")
public List<Person> getPersons(@RequestParam(value="query" , required=false) String query) {
List<Person> personList = personService.SearchByName(query);
return personList;
}
For more details on RequestParam