Spring pass model from POST - spring

I'm quite knowledgeable with Spring yet. I'm trying to learn. Please help me quite a bit.
I have a form which uses modelAttribute="projectBean" which is working perfectly fine and I'm able to manipulate data on the controller below
#RequestMapping( value = "projects/newProject", method = RequestMethod.POST )
public String newProject( #ModelAttribute( "projectBean" )
ProjectBean projectBean, HttpServletRequest request, ModelMap model )
{
model.addAttribute( "projectBean", projectBean );
return "redirect:../projects/projectItems.do";
}
I'm done saving it to the database so I want now to pass the projectBean to another controller
#RequestMapping( value = "/projects/projectItems", method = RequestMethod.GET )
public String projectItems( #RequestParam( defaultValue = "" )
String message, #RequestParam( defaultValue = "" )
String messageType, #RequestParam( defaultValue = "" )
String projectID, HttpServletRequest request, #RequestParam( "projectBean" )
ProjectBean projectBean, ModelMap model )
{
return "project/items";
}
But i'm having this exception: Required ProjectBean parameter 'projectBean' is not present
What am I doing wrong?

You don't generally pass a model from one Controller to another Controller. I assume you are trying to perform some logic before passing the model to another JSP page (project/items in this case).
You can achieve the same in newProject() controller rather than trying to pass the model to another Controller
#RequestMapping( value = "projects/newProject", method = RequestMethod.POST )
public String newProject( #ModelAttribute( "projectBean" )
ProjectBean projectBean, HttpServletRequest request, RedirectAttributes redirectAttributes)
{
//Call DAO class to save the model to database
//Call BusinessDelegate class to perform the additional logic
//Add beans to RedirectAttributes using addFlashAttribute() methods to make it available in next JSP page
redirectAttributes.addFlashAttribute("projectBean", projectBean);
return "redirect:/project/items";
}
Note: In order to apply POST-REDIRECT-GET pattern, you should use RedirectAttributes instead of ModelMap to make the model attributes available in redirected JSP page.

Related

Error 400 when receiving data from URL parameters en Spring MVC

I am trying to receive data from an URL with two parameters like this one:
http://localhost:80000/xxx/xxx/tickets/search?codprovincia=28&municipio=110000
No matter the approach, I am always getting a 400 error, but if I access the URL without the two parameters, the controller returns the view correctly (without the parameters, naturally)
This is the code of my controller:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping("tickets")
public String tickets(Model model, #RequestParam ("codprovincia") String codprovincia, #RequestParam ("municipio") String municipio, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
Extra info: if I use this URL:
http://localhost:9081/xxx/xxx/tickets/search/28/790000
And this code:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping(value = "buscar/{codprovincia}/{municipio}", method = RequestMethod.GET)
public String buscar(#PathVariable Integer codprovincia, #PathVariable Integer municipio ,Model model, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
It gets the parameters correctly. The problem is that I have to use the first URL. I have reviewed similar questions about similar issues, and I have implemented the solutions to those issues, but I get the 400 error regardless what I try (add value="xxx=, required=false, and other suggestions.)
For RequestParam, you need to explicitly add 'name' attribute
#RequestParam(name = "codprovincia"), #RequestParam (name = "municipio")
No need to for HttpServletRequest, unless you have reason
Also, in your 'tickets' method, RequestMapping is not conforming to your URL path.
I think it should be
#RequestMapping("/xxx/tickets/search")
Cheers!

Issue with Spring Rest #RequestMapping when negating params

I have two spring controller methods :
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = "!applicationId") //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = {"idNumber","applicationId"}) //existing customer
public String requestOTP( #RequestParam(value="idNumber") String idNumber , #RequestParam(value="applicationId") String applicationId) {
return customerService.requestOTP(idNumber, applicationId);
}
using "!applicationId" , I am expecting that when I call the url with applicationId parameter there that the second method will be called , but actually when I pass a request like this :
{"idNumber":"345","applicationId":"64536"}
The first method gets called
This is the part of the params paremeters documentation that I rely on :
Finally, "!myParam" style expressions indicate that the specified
parameter is not supposed to be present in the request.
Can't you just simply delete first request params?
#RequestMapping(value="/requestotp",method = RequestMethod.POST) //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
The issue actually wasn't with negating the parameter, the issue was that I was sending {"idNumber":"345","applicationId":"64536"} in the POST body and I was expecting the variables to be mapped to the method parameters annotated with #RequestParam ... this is not correct ... #RequestParam only map URL parameters .... so the controller was trying to find the best match so it was using the first method as it contained #RequestBody

optional parameter in Spring MVC method

I am learning spring MVC and come across these methos in spring contrller MVC 3.1
ControllerClass(){
#RequestMapping(....)
public String show( Model uiModel) {
return ".....";
}
#RequestMapping(value = "/{id}", params = "form", method = RequestMethod.POST)
public String update(#Valid Contact contact, BindingResult bindingResult, Model uiModel,
HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale,
#RequestParam(value="file", required=false) Part file) {
if (bindingResult.hasErrors()) {
...........
return ".....";
}
parameters like BindingResult , Model ,
HttpServletRequest , RedirectAttributes , Locale ,
#RequestParam(value="file", required=false) Part are optional but I wonder where I can find these optional parameter and under which situation it can appear in method.
Parameter:
BindingResult - imagine you have an registration-form and you would pre validate the user input, then you can use the BindingResult.
Model - After the user is registered, he wants to edit his own profile he goes to a edit site, in this site you would show the data from the user. Here you can search for the user and add the user-object to the model and in the template you can read the values from the model-attribute.
HttpServletRequest provides request information.
#RequestParam(value="file", required=false) from Spring:
annotated parameters for access to specific Servlet request parameters. Parameter values are converted to the declared method argument type
Imagine you have a table of users and you would edit one of these, you select an entry and there you can send the userId as a requestparam.
There is a similar attribute, it's called #PathVariable the main difference, the #PathVariable is mandatory. The #RequestParam is optional respectively for this exist a "fallback/default value".
The #PathVariable is a part from the url:
#RequestMapping(value = "/{login}/edit", method = RequestMethod.GET)
public ModelAndView editUserByLogin(#PathVariable("login") final String login, final Principal principal) {}
The other two I have not used yet.

Spring 3 : Binding same controller method to multiple form action

I have a controller method with RequestMapping.PUT and having a URI
#RequestMapping(value = "/add/email", method = RequestMethod.POST)
public String addNewAccountEmail(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
return displayForm(model);
}
I have a form like :
<form:form id="add-user-email" action="/add/email" name="manageUserAddEmail" method="post" modelAttribute="accountEmail">
I want to have more form pointing to same action , but need to do different operations inside addNewAccountEmail method. So how can I achieve this in Spring ? Basically any parameter which can make me differentiate functionalities or somehow I can have multiple methods having same RequestMapping URL and Method ?
I can only use RequestMethod.POST as I have similar requirements for other methods as well.
Basically I do not want the URL to change in Browser when invoking actions, that is why I want all form actions to point to same action URL.
You could point all of your forms at the same controller method and then differentiate the form-specific functionality within that method by looking for form-specific request parameters.
Each form would need to add its own request parameter to identify it - such as:
<input type="hidden" name="form1_param" value="1"/>
And then you can vary the behaviour inside the method by inspecting the HttpServletRequest:
#RequestMapping(value = "/add/email", method = RequestMethod.POST, )
public String addNewAccountEmail(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model, HttpServletRequest request) {
if (request.getParameter("form1_param") != null) { // identifies 1st form
// Do something
} else if (request.getParameter("form2_param") != null) { // indentifies 2nd form
// Do something else
}
...
}
It would be cleaner however to have multiple controller methods mapped to the same path, but specify different params in the RequestMapping - to differentiate the different forms.
#RequestMapping(value = "/add/email", params="form1_param", method = RequestMethod.POST)
public String addNewAccountEmail1(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
// Do something specific for form1
return displayForm(model);
}
And also:
#RequestMapping(value = "/add/email", params="form2_param", method = RequestMethod.POST)
public String addNewAccountEmail2(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
// Do something specific for form2
return displayForm(model);
}
Etc.
#RequestMapping accepts arrays as parameters (with an or semantic).
#RequestMapping(
value = "/add/email",
method = { RequestMethod.POST, RequestMethod.PUT } )

request and session attribute value returns null in #ModelAttribute method

Am using spring mvc i want to access an request attribute inside #ModelAttribute method but its giving only null
#RequestMapping(value = "/abc", method = RequestMethod.GET, params = "data")
public ModelAndView aaaa()
{
String courseId = httpServletRequest.getParameter("courseValue");
System.out.println("course value data :" + courseId); // here am getting value
httpServletRequest.setAttribute("courseId", courseId); // setting in request
attribute
WebUtils.setSessionAttribute(httpServletRequest, "courseId", courseId);
// setting in session attribute
ModelAndView modelAndView = new ModelAndView("abc");
return modelAndView;
}
#ModelAttribute("termList")
public Map<String, String> def(HttpServletRequest httpServletRequest)
{
String courseId = (String) WebUtils
.getSessionAttribute(httpServletRequest, "courseId");
System.out.println("course value in term :" + courseId); // here its giving null
Map<String, String>map = courseSubLinkService.getTermDetailsBasedOnCourseId
(courseId);
httpServletRequest.setAttribute("termList", map);
return map;
}
I dont know where i did wrong please help me to get this value
From Spring docs:
#ModelAttribute methods in a controller are invoked before
#RequestMapping methods, within the same controller
This means that in moment when def is invoked HttpServletRequest hasn't attribute that you need because you set this attribute in aaaa method that will be invoked after def.

Resources