How should I add attribute after redirect to a controller - spring-mvc

I am just a newbie about Spring.
I am now using #ExceptionHandler to handle all the exception for my web application. And after I catch the exception, it will go to and error.jsp page displaying the error message.
I have a ParentController and in that, I have:
#org.springframework.web.bind.annotation.ExceptionHandler(PortalException.class)
public ModelAndView handle(PortalException e, HttpServletRequest request) {
ModelMap map = new ModelMap();
map.addAttribute("message", e.getMessage());
return new ModelAndView("/error", map);
}
and I have a ErrorControllerextends the ParentController to add the attributes:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Model model, HttpServletRequest request) {
model.addAttribute("excetpion.message", request.getParameter("message"));
return "/error";
}
}
In the error.jsp:
<p>Excpetion is: ${exception.message}</p>
When I run my application, I can catch the exception and jump to error.jsp, but no exception message is display.
Anyone can help me to figure out how to solve it.

Please try use:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Map<String, Object> map, HttpServletRequest request) {
map.put("excetpion.message", request.getParameter("message"));
return "/error";
}
}
UPDATE
Map you get it messae from #Controller to View in this case error.jsp
I hope these helped! :)

Related

Springboot app ResponseBodyAdvice Not triggered

I am trying to update an audit entry using the response body advice but as far as I can tell it never gets executed. I see the bean in the logs:
{"timestamp":"2018-08-21T15:48:08.349Z","level":"INFO","thread":"main",
"logger":"org.springframework.data.rest.webmvc.RepositoryRestHandlerAdapter",
"message":"Detected ResponseBodyAdvice bean in responseAuditAdvice","context":"default"}
My controller method looks like this:
#PostMapping(path = "/stage", consumes = {
"application/json"
}, produces = {
"application/json"
})
#ResponseBody
public ResponseEntity<?> stage(#Valid #RequestBody StagingDto stagingDto,
#RequestHeader(HttpHeaders.USER_AGENT) String userAgent,
BindingResult bindingResult) {
I have a RequestAuditAdvice that extends RequestBodyAdviceAdapter and it is working fine. Also if the error flow occurs I see the exception advice executing as well. it is only the response advice that is failing to trigger. Any suggestions?
here is the advice bean:
#Slf4j
#RequiredArgsConstructor(onConstructor_ = #Inject)
#ControllerAdvice
public class ResponseAuditAdvice implements ResponseBodyAdvice<Object> {
private final RequestService requestService;
#Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
#Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
log.info("Updating audit for response.");
String ip = new String (request.getRemoteAddress().getAddress().getAddress());
requestService.auditResponse(ip, 200);
return body;
}
}

Spring forward is not working in android api

I have been search on google but I can not find the solution so please tell me why spring forward is not working in android api but working in web api so how to fix it?
#Controller
#RequestMapping(value = "/")
public class LoginController {
#RequestMapping(method = {RequestMethod.GET,RequestMethod.POST,RequestMethod.HEAD})
public ModelAndView home(#ModelAttribute LoginInfo user, Model model,
HttpServletRequest request, HttpServletResponse response)throws Exception {
System.out.println("LoginController.user.userName: "+userName);
return new ModelAndView("forward:admin.html");
}
#RequestMapping(value = "/admin", method={RequestMethod.GET, RequestMethod.POST})
public ModelAndView successAdmin(#ModelAttribute LoginInfo user, Model model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("admin.userName: "+userName);
return null;
}
}
I also use return new ModelAndView("forward:/admin.html"); but not forward the request to /admin handler method.
Try to use
return new ModelAndView("admin.html");
in your home method
or change the home function to
public String home() {
return "forward:/admin";
}}

How pass POST parameters from controller to another Controller Spring MVC?

I have startController and start view. In this view I input number and amount and validate it. If validation was successful, I want pass this parameters(number and amount) to another controller, and after that make some operations with it, in this controller. I see two way:
make this operations in first controller, in another methods and use second view for it. But my controller will very big and all logic will be this.
create second controller and second view and pass parameters to this controller.
I make this:
#Controller
#RequestMapping("/")
public class StartController {
#Autowired
private ValidateService validateService;
#RequestMapping(method = RequestMethod.GET)
public ModelAndView printWelcome() {
ModelAndView modelAndView = new ModelAndView("start");
return modelAndView;
}
#RequestMapping(value = "process", method = RequestMethod.POST)
public ModelAndView process(HttpServletRequest request) {
ModelAndView modelAndView;
String phoneNumber = request.getParameter("phone_number");
int amount = Integer.parseInt(request.getParameter("amount"));
String result = validateService.validate(phoneNumber, amount);
if (!result.equals("OK")) {
modelAndView = new ModelAndView("start");
modelAndView.addObject("result",result);
}else {
modelAndView = new ModelAndView("redirect:/check/process");
modelAndView.addObject("phone_number", phoneNumber);
modelAndView.addObject("amount",amount);
}
return modelAndView;
}
and if result != OK I redirect to new controller
#Controller
#RequestMapping("/check")
public class CheckController {
#RequestMapping(value = "process", method = RequestMethod.GET)
public ModelAndView process(HttpServletRequest request) {
ModelAndView modelAndView = new ModelAndView("check");
String phoneNumber = request.getParameter("phone_number");
int amount = Integer.parseInt(request.getParameter("amount"));
return modelAndView;
}
}
But I need pass parameters with RequestMethod.POST and it will not work. How do it?
You can return a ModelAndView with parameters as follow:
return new ModelAndView("redirect:/check/process?phone_number="+yourPhoneNumber+"&amount="+amount)
You can use forward to go to a new controller right?
"forward:/test2?param1=foo&param2=bar";
Please see below link for more details.
Spring forward with added parameters?

Spring MVC - Request Return Value in Browser

I imported the Getting Started - Securing a Web Application in STS and added a controller for navigation, the request gets called and the return value instead of redirecting gets displayed in the browser. Any idea why it does this and how to fix it?
Here is the code:
#RestController
public class BetController {
#RequestMapping("/")
public String username(Model model) {
System.out.println("Test");
model.addAttribute("username", WebSecurityConfig.getUsername());
return "statpage";
}
The page start page is registered in this manner:
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("startpage");
registry.addViewController("/login").setViewName("login");
}
All I get in the browser is a blank page with "startpage" on it, looking at the page's source there is no html just "startpage"
Returning ModelAndView instead of a String in the RequestMapping method solved the problem:
#RequestMapping("/")
public ModelAndView username(Model m) {
ModelAndView mav = new ModelAndView();
mav.addObject("username", WebSecurityConfig.getUsername());
mav.setViewName("betting");
return mav;
}
Another solution is changing #RestController to #Controller and making sure all the names match

Best practices of handling PageNotFound for unmapped request-mappings

My use-case:
I have multiple "kind of logical parts" in my application, that are separated by url. something like:
- someUrl/servletPath/onePartOfMyApplication/...
- someUrl/servletPath/otherPartOfMyApplication/...
Now I want to handle unmapped requests (404s) for each part differently.
How I'm handling it now:
my web.xml:
...
<error-page>
<error-code>404</error-code>
<location>/servletPath/404.html</location>
</error-page>
my controller:
#Controller
public class ExceptionController
{
#ResponseStatus(value = HttpStatus.NOT_FOUND)
#RequestMapping(value = "/404.html")
protected String show404Page(final HttpServletRequest request)
{
final String forward = (String) request.getAttribute("javax.servlet.forward.request_uri");
// parse string and redirect to whereever, depending on context
final String redirectPath = parse(forward);
return "redirect: " + redirectPath;
}
...
My aim:
Is there a more elegant (spring-like)-way of handling 404s, instead of parsing the request in a controller or interceptor and declaring the error-page in my web.xml?
Would be nice if my controller should could look something like this:
#Controller
public class ExceptionController
{
#ResponseStatus(value = HttpStatus.NOT_FOUND)
#RequestMapping(value = "/onePartOfMyApplication/404.html")
protected String show404PageForOnePart(final HttpServletRequest request)
{
// do something
...
return "onePartPage";
}
#ResponseStatus(value = HttpStatus.NOT_FOUND)
#RequestMapping(value = "/otherPartOfMyApplication/404.html")
protected String show404PageForOtherPart(final HttpServletRequest request)
{
// do something different
...
return "otherPartPage";
}
I use #ExceptionHandler annotation. In controller I have something like:
private class ItemNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ItemNotFoundException(String message) {
super(message);
}
}
#ExceptionHandler
#ResponseStatus(HttpStatus.NOT_FOUND)
public void handleINFException(ItemNotFoundException ex) {
}
And then I throw an exception either in Controller (or in Service layer):
#RequestMapping("/{id}")
#ResponseBody
public Item detail(#PathVariable int id) {
Item item = itemService.findOne(id);
if (item == null) { throw new ItemNotFoundException("Item not found!"); }
return item;
}
You can do anything you like in method annotated with #ExceptionHandler. Right now in my example it shows a standard 404 error which you can customize in web.xml, but you can do much, much more. See documentation: http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html

Resources