Spring MVC: #RequestParam not seen with POST - http

Given:
Spring MVC
Controller method mapped to POST
Body parameters "abc=1&def=2"
However, the method 'reads' correctly the parameters only if they are given in the URL, not in the body. (The requests are done with a browser tool that makes POST requests)
Why?
#RequestMapping(value = "/url", method = RequestMethod.POST)
public #ResponseBody String something( #RequestParam(value="abc", required=false) String abc, #RequestParam(value="def", required=false) String def)....

Related

Spring MVC : Request Mapping with matching sub paths

I have 2 methods in a class with request mapping as below:
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(#ModelAttribute RegistrationForm registrationForm, Model model, HttpServletRequest request) {
}
and
#RequestMapping(value = "/two/register", method = RequestMethod.GET)
public String registerTwo(#ModelAttribute TwoRegistrationForm twoRegistrationForm, Model model, HttpServletRequest request) {
}
Is it possible that a call to /two/register will trigger /register because the subpaths match?
Have tried to debug this flow on local and everything works ok. However, when deployed onto a server and integrated to Site Minder - the above behaviour is observed.
Site Minder is configured to say -
if user hits /app -> forward to /app/register and
if user hits /app/two -> forward to /app/mgr/register

How to handle two spring forms in one page with respective submit actions?

I have two spring forms on one page with their own submit actions:
JSP:
<form:form id="frm_user_login" class="animated fadeIn" method="post" action="./loginsubmit.htm" commandName="useSignInFm">
<form:form id="frm_user_register" class="animated fadeIn" method="post" action="./registersubmit.htm" commandName="userRegistrationForm">
And their respective mappings in one Contoller:
Contoller:
#RequestMapping(value = "/loginsubmit.htm", method = RequestMethod.POST)
public ModelAndView signIn(#ModelAttribute("useSignInFm") SignInForm signInForm, BindingResult bindingResult,
Model model, HttpServletRequest request)
#RequestMapping(value = "/registersubmit.htm", method = RequestMethod.POST)
public ModelAndView userRegistration(#ModelAttribute("userRegistrationForm") UserRegistrationForm userRegistrationFm,
BindingResult bindingResult,Model model, HttpServletRequest request)
Submitting one form (userRegistrationForm) gives exception of other form:
Neither BindingResult nor plain target object for bean name 'useSignInFm' available as request attribute.
How can I handle this?
Since you're rendering two forms in one page, you need to bind them both in your controller mappings, otherwise the unbinded one will get lost while returning to the view, causing that error. The form backing objects must both exists when rendering the view.
So try this, it worked in my case, very similar to yours:
#RequestMapping(value = "/loginsubmit.htm", method = RequestMethod.POST)
public ModelAndView signIn(#Valid #ModelAttribute("useSignInFm") SignInForm signInForm,
BindingResult bindingResult, #ModelAttribute("userRegistrationForm")
UserRegistrationForm userRegistrationFm, Model model, HttpServletRequest request)
#RequestMapping(value = "/registersubmit.htm", method = RequestMethod.POST)
public ModelAndView userRegistration(#Valid #ModelAttribute("userRegistrationForm")
UserRegistrationForm userRegistrationFm, BindingResult bindingResult,
#ModelAttribute("useSignInFm") SignInForm signInForm, Model model, HttpServletRequest request)
Notice that I added the #Valid annotation because I assume that you want to validate the first form in each request mapping. Also be careful at the position of the bindingResult parameter: it must follow the #ModelAttribute parameter whose binding results you want to consider.
Neither BindingResult nor plain target object for bean name 'useSignInFm' available as request attribute
means that , there is no element with id/name matching "useSignInFm". You should start fixing that first.

Spring RequestMapping: Get path with slashes

Is there a way to get the first part of the url path, before /c:
Thats it: /Category1/Subcategory1.1/Subcategory1.1.1/c/{categoryCode:.*}
#Controller
#RequestMapping(value = "/**/c")
public class CategoryPageController {
#RequestMapping(value = "/{categoryCode:.*}", method = RequestMethod.GET)
public ModelAndView viewCategory(#PathVariable String categoryCode,
final HttpServletRequest request) {
String categoryPath = ...
I tried to use AntPathMatcher (extractPathWithinPattern) but I'm not able to define the correct pattern.
inject the request object by simply adding the the HttpServletRequest to the method signature, and
then access the Request Url by calling getRequestURL().
(oh and auto converting answers to comments, stackoverflow jumps the shark)

Spring 3 -- how to do a GET request from a forward

I'm trying to forward a request to another Spring controller that takes a GET request, but it's telling me POST is not supported. Here is the relevant portion from my first controller method, which does take a POST request, since I'm using it for a login function.
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(#ModelAttribute("administrator") Administrator administrator,
Model model) {
// code that's not germane to this problem
return "forward:waitingBulletins";
}
Here is the method I'm trying to forward to.
#RequestMapping(value = "/waitingBulletins", method = RequestMethod.GET)
public String getWaitingBulletins(Model model) {
// the actual code follows
}
Here is the error message in my browser.
HTTP Status 405 - Request method 'POST' not supported
--------------------------------------------------------------------------------
type Status report
message Request method 'POST' not supported
description The specified HTTP method is not allowed for the requested resource (Request method 'POST' not supported).
forward maintains the original request intact, so you are forwarding a POST request and missing a handler for it.
By the looks of it, what you're really trying to implement is the POST-redirect-GET pattern, which uses redirect instead of forward.
You only need to change your POST handler to:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(#ModelAttribute("administrator") Administrator administrator,
Model model) {
// code that's not germane to this problem
return "redirect:waitingBulletins";
}
to make it work.

Spring-MVC 3.1: Forwarding A Request From One Controller Function To Another

I'm using Spring 3.1. I have a controller function that takes in a command object ( a data holder ) submitted via a FORM and does some processing :
#RequestMapping(value = "/results", method = RequestMethod.POST)
public String toResultsScreen(#ModelAttribute("ssdh") SearchScreenDataHolder ssdh,
BindingResult bindingResult,
ModelMap model,
HttpSession session) {
if (bindingResult.hasErrors()) {
logger.debug("Error returning to /search screen");
return "search";
}
netView = "results";
// do stuff
return nextView;
} // end function
Some user would like to programmatically make GET links to obtain information from our site and I would like to set up another handler that would handle that request. It would create a new installation of that the command object ( ssdh ) and populate it with the parameters sent via the GET request. Then it would pass it on to the handler above. Something like this:
#RequestMapping(value = "/pubresult")
public String toPublicResultsScreen(ModelMap model,
HttpSession session,
#RequestParam (required=true) String LNAME,
#RequestParam (required=false)String FNAME){
Search search = new Search(usertype);
// Capture the search parameters sent by HTTP
ssdh.setLast_name(LNAME);
ssdh.setFirst_name(FNAME);
// To Do: "forward this data holder, ssdh to the controller function quoted first
return nextView;
} // end function
My question is how can I forward my command/data holder object to the first controller function such that I don't have to alter the code to the first controller function in any way?
You can use RedirectAttributes object which was introduced in Spring MVC 3.1 and populate it with data you want to keep for redirection. It called PRG (POST/Redirect/GET) pattern.
#RequestMapping(value="/saveUserDetails.action", method=RequestMethod.POST)
public String greetingsAction(#Validated User user,RedirectAttributes redirectAttributes){
//setting attributes
redirectAttributes.addFlashAttribute("firstName", user.getFirstName());
redirectAttributes.addFlashAttribute("lastName", user.getLastName())
return "redirect:success.html";
}
I wrote some technical article regarding how to use it. I believe it will give you more details:
http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31
You should be able to set the ssdh in a ModelAttribute and simply forward it back, this way, the RequestDispatcher should be able to map it back to the /results handler:
#RequestMapping(value = "/pubresult")
public String toPublicResultsScreen(ModelMap model,
HttpSession session,
#RequestParam (required=true) String LNAME,
#RequestParam (required=false)String FNAME, Model model){
Search search = new Search(usertype);
// Capture the search parameters sent by HTTP
ssdh.setLast_name(LNAME);
ssdh.setFirst_name(FNAME);
model.addAttribute("ssdh", ssdh);
return "forward:/results";
}
Use
org.springframework.web.servlet.view.RedirectView
class from spring package to redirect to different page in spring MVC controller. The Baeldung blog page has more details
Sample code:
#RequestMapping(value = "/", method = RequestMethod.GET)
public RedirectView mainMethod() {
return new RedirectView("/login");
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView mainLogin() {
ModelAndView model = new ModelAndView("login");
return model;
}

Resources