Spring RequestMapping: Get path with slashes - spring-mvc

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)

Related

Forward request to spring controller

From a servlet , I am forwarding the request to a spring controller like below
RequestDispatcher rd = request.getRequestDispatcher("/myController/test?reqParam=value");
rd.forward(request, response);
In order to pass a parameter to the spring controller , I am passing it as request parameter in the forward URL.
Is there a better way of doing this ?
Instead of passing in request parameter , can I pass as a method parameter to the spring controller during forward ?
This will be called when /myController/test?reqParam=value is requested:
#RequestMapping("/myController/test")
public String myMethod(#RequestParam("reqParam") String reqParamValue) {
return "forward:/someOtherUrl?reqParam="+reqParamValue; //forward request to another controller with the param and value
}
Or you can alternatively do:
#RequestMapping("/myController/test")
public String myMethod(#RequestParam("reqParam") String reqParamValue,
HttpServletRequest request) {
request.setAttribute("reqParam", reqParamValue);
return "forward:/someOtherUrl";
}
you can use path variable such as follow without need to use query string parameter:
#RequestMapping(value="/mapping/parameter/{reqParam}", method=RequestMethod.GET)
public #ResponseBody String byParameter(#PathVariable String reqParam) {
//Perform logic with reqParam
}

Spring MVC: #RequestParam not seen with POST

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)....

URL with hash in Spring Mvc

everyone.
I'm using Spring MVC 4. My App sends activation url to user's email.
Activation url:
www.example.com:8080/myapp/user/activate/$2a$10$Ax2WL93zU3mqjtdxuYlYvuWWyQsPBhkhIfzYHJYk4rdNlAY8qCyC6
But, my App can't find path.
My controller:
#RequestMapping(value = "/user/activate/{hash})
public void activateUser(#PathVariable("hash") String hash) {
userService.activate(hash);
}
What am I doing wrong?
Update:
I've found out that if hash contains dot (".") then throws 404 error.
I've change my url:
www.example.com:8080/myapp/user/activate?code=$2a$10$Ax2WL93zU3mqjtdxuYlYvuWWyQsPBhkhIfzYHJYk4rdNlAY8qCyC6
and my controller:
#RequestMapping(value = "/user/activate)
public void activateUser(#RequestParam("code") String hash) {
userService.activate(hash);
}
It works perfectly.
you are not returning anything from the controller, hence receiving a 404
If you have dot (.) in your path variable value, then you must declare it explicitly in the RequestMapping, as shown below -
#RequestMapping(value = "/download/{attachmentUri:.+}", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<InputStreamResource> downloadAttachment(#PathVariable("attachmentUri") String attachmentUri,
HttpServletResponse response,
WebRequest webRequest) {
}

prevent json of my command object from comming down to client during post

My controller has following calls
#ModelAttribute("commandObject")
public UsersCommand getCommand(HttpServletRequest req) throws Exception {
...
return command;
}
#RequestMapping(value = {"addusers.json"}, method = RequestMethod.GET)
public void handleGet() {
//empty method
}
#RequestMapping(value = {"addusers.json"}, method = RequestMethod.POST)
public void handlePost(#ModelAttribute("commandObject") UsersCommand command, HttpServletRequest req) throws Exception {
//do stuff
}
during the get i get the json of my UsersCommand object, however after I do a post, I am getting the json of my command object which i do not need as i want to do a fire and forget post.
How can I avoid the json object from coming down to browser during post?
It seems like you only want JSON returned with the GET method. To do this, remove the #ModelAttribute method all-together. This tells Spring to add the return object to your model on every handler in the controller, which you don't want. Then modify your GET handler to be like the following:
#RequestMapping(value = {"addusers.json"}, method = RequestMethod.GET)
#ResponseBody
public UserCommand handleGet() {
UserCommand cmd = getUserCommand();
return cmd;
}
The #ResponseBody annotation tells Spring to serialize the return type to JSON (or XML if you annotated your class with JAXB, and depending on the request accept headers). For this to work, you also need to add Jackson to your classpath and make sure you're using <mvc:annotation-driven /> or #EnableWebMvc in your XML or Java config, respectively.
This will sound like self-promotion, but I wrote a post about this if you want more detail: http://codetutr.com/2013/04/09/spring-mvc-easy-rest-based-json-services-with-responsebody/.
Hope that's helpful! Let me know if I can add any more clarity for you.

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