Spring 3.0 forwarding request to different controller - java

What is the proper way to forward a request in spring to a different controller?
#RequestMapping({"/someurl"})
public ModelAndView execute(Model model) {
if (someCondition) {
//forward to controller A
} else {
//forward to controller B
}
}
All of the controller have dependencies injected by Spring, so I can't just create them and call them myself, but I want the request attributes to be passed on to the other controllers.

Try returning a String instead, and the String being the forward url.
#RequestMapping({"/someurl"})
public String execute(Model model) {
if (someCondition) {
return "forward:/someUrlA";
} else {
return "forward:/someUrlB";
}
}

You can use view name like "redirect:controllerName" or "forward:controllerName". The latter will reroute request to another controller and former will tell browser to redirect request to another url.
docs: https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-redirecting-redirect-prefix

You can use Spring RedirectView to dispatch request from one controller to other controller.
It will be by default Request type "GET"
RedirectView redirectView = new RedirectView("/controllerRequestMapping/methodmapping.do", true);

Related

Spring Controller to get both GET and POST variables

Sometimes we send a POST HTTP request with POST payload to an endpoint with URL variable, for example:
[POST] http://example.com/update-item?itemid=123456
To get the POST payload in the Spring controller class, I can do something this:
#RequestMapping(value = "/update-item", method = RequestMethod.POST)
public String updateItem(#RequestBody Item json) {
//some logics
return "/update-item-result";
}
However, at the same time, how can I get the variable from the URL (i.e. itemid in the above example) even for method = RequestMethod.POST?
I see a lot of Spring MVC examples on the web either get the GET variables from the URL or the POST variables from the payload, but I never see getting both in action.
You can use multiple HTTP requests by specifying the method attribute as an array in the #RequestMapping annotation.
#RequestMapping(value = "/update-item", method = {RequestMethod.POST,RequestMethod.GET})
public String updateItem(#RequestBody Item json) {
//some logics
return "/update-item-result";
}

How to retrieve value of parameters annotated by #RequestBody from a HttpServeletRequest object?

in a springcloud project
if a backend microservice has the following:
#RequestMapping("/test")
pubilc void test(#RequestBody MyPram myParam){
...
}
how can I retrive the "myParam" value in a zuul filter?
in other words, since I can have the following code segment in a zuul filter
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
how can I retrive the "myParam" value from a request?
i don't know in Spring Cloud but tried in springMVC (spring version 3) we can get the Request body HttpServeletRequest object or method.
#RequestMapping(value="/employee/{id}")
public #ResponseBody String demo(HttpServletRequest request, #PathVariable("id") Integer id) {
if (request.getMethod().equalsIgnoreCase("POST")) {
return "POST MEhod";
} else if (request.getMethod().equalsIgnoreCase("GET")) {
return "GET Method";
}
}
Its not exact what you are looking but it will give you hint to solve your problem

Display exception message handled by Spring using JSP

I'm new in Spring and also in JSP. I'm working in the project and I needed to create a page where application will be redirected in case of specific exceptions.
I have service's method which throws one of exceptions. This method is called in one of our page controller with #RequestMapping annotation. So to redirect to specific error page, I created two methods with #ExceptionHanlder which handle this exceptions in this controller. How it looks:
#ExceptionHandler(IllegalStateException.class)
public ModelAndView handleIllegalStateException (IllegalStateException ex) {
ModelAndView modelAndView = new ModelAndView("redirect:/error");
modelAndView.addObject("exceptionMsg", ex.getMessage());
return modelAndView;
}
But there wasn't enough. I also need to create ErrorPageController:
#Controller
#RequestMapping("/error")
public class ErrorPageController {
#RequestMapping(method = RequestMethod.GET)
public ModelAndView displayErrorPage() {
return new ModelAndView("error");
}
}
And now works displaying error page. But my problem is, that I can't display error message in JSP...
I have:
<h3>Error page: "${exceptionMsg}"</h3>
But I don't see a message ;/ Instead of it, I see message in URL:
localhost/error?exceptionMsg=Cannot+change+participation+status+if+the+event+is+cancelled+or+it+has+ended.
And it's wrong because in URL I want to have only an "localhost/error" and nothing more. This message I want to display in JSP.
To fix both of your issues (show the message, and have the proper url) you should in original code change you exception handler method to e.g.
#ExceptionHandler(IllegalStateException.class)
public RedirectView handleIllegalStateException(IllegalStateException ex, HttpServletRequest request) {
RedirectView rw = new RedirectView("/error");
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
if (outputFlashMap != null) {
outputFlashMap.put("exceptionMsg", ex.getMessage());
}
return rw;
}
Why? If you want your attributes to persist through redirect, you need to add them to flash scope. The code above uses the FlashMap, from the docs
A FlashMap is saved before the redirect (typically in the session) and
is made available after the redirect and removed immediately.
If it were to be a normal controller method, you could have simply added RedirectAttributes as an argument, but on #ExceptionHandler methods, the arguments of RedirectAttributes are not resolved, so you need to add the HttpServletRequest and use the RedirectView.
You have to change ModelAndView to:
#ExceptionHandler(IllegalStateException.class)
public ModelAndView handleIllegalStateException (IllegalStateException ex) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("exceptionMsg", ex.getMessage());
return modelAndView;
}
And have this part in error.jsp:
<h3>Error page: "${exceptionMsg}"</h3>

Set visible URL with Spring

Is there a way to set the displayed url of a page using Spring MVC ?
Let me be clearer with an example : I have the following controller :
#Controller
public class Display{
#RequestMapping(value = "myPage")
public ModelAndView display() {
ModelAndView result = new ModelAndView(Uris.MY_PAGE);
return result;
}
#RequestMapping(value = "myPage/revisited")
public ModelAndView accountManagement() {
ModelAndView result = new ModelAndView(Uris.ACCOUNT);
return display();
}
}
If I go on myPage/Revisited, I'll get the JSP associated to myPage. However, in my browser, the url will stay the same (myPage/revisited). How could I prevent that ?
To be more precise on what sam said, you can use UrlRewriteFilter, the installation process is explained in the link, then set a rule in the file urlrewrite.xml:
<rule match-type="wildcard">
<from>/myPage/revisited/redirect</from>
<to type="redirect">%{context-path}/myPage</to>
</rule>
And in your controller, just use what Emanuele said, i.e.
response.sendRedirect("redirect");

Spring MVC forwarding to controller with different HTTP method

I have login controller methods like so:
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
// do stuff with locale and model
// return an html page with a login form
return "home";
}
#RequestMapping(value = "/account/login", method = RequestMethod.POST)
public String login(Model model, /* username + password params */){
try {
// try to login
// redirect to account profile page
return "redirect:/account/profile";
} catch (LoginException e) {
// log
// here I want to reload the page I was on but not with a url /account/login
// possibly using a forward
model.addAttribute("error", e.getMessage());
return "forward:/home";
}
}
The above code works on successful log-in attempt. However, it fails when the log-in attempt fails because Spring's forward uses the current request with the same HTTP method. So because I used a POST to send my username/password (which caused log-in to fail), the forward will also use POST to go to the handler method for /home, home(), which is expecting a GET.
Is there any way in Spring to redirect to another controller method with a different HTTP method while maintaining the current model (since I want to show the error message)?
This is on Spring 3.2.1.
Do a redirect instead:
return "redirect:/home";
If you need Model attributes to be available after the redirect, you can use flash attributes.

Categories

Resources