I've managed to build static error pages and redirect to them with this bean:
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (optiuniEnvironment.equals("development")) {
ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/404.html");
container.addErrorPages(error401Page, error404Page, error500Page);
}
}
};
}
However, now I want to build a custom page, that uses the functionality of the controller.
So in my controller I have something like
@RequestMapping("/404.html")
String pageNotFound(Model model, HttpServletRequest request)
{
return "404";
}
and wish to redirect to it if I encounter the HttpStatus 404.
I believe the answer is configuring the DispatcherServlet, but not sure.
Any ideas? Thanks!
(if possible, please use java-based configurations, not xml)
You can handle these error using following methods:
1. Using Exception Handler method in same controller:
@ExceptionHandler(NoHandlerFoundException.class)
public String handle404Exception(NoHandlerFoundExceptionex) {
//do whatever you want
return "viewName";
}
2. Create Exception controller
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(NoHandlerFoundException.class)
public String handle404Exception(NoHandlerFoundExceptionex) {
//do whatever you want
return "viewName";
}
}
If using Spring Boot, set following properties in application.properties
server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
3. Adding Error Page Registrar:
@Bean
public ErrorPageRegistrar errorPageRegistrar(){
return new CustomErrorPageRegistrar();
}
private static class CustomErrorPageRegistrar implements ErrorPageRegistrar {
// Register your error pages and url paths.
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
}
}
and define your controller endpoint for respective urls (eg. /400)
Solution for SpringBoot version: 1.2 - even if not the best - it's good enough for now.
Created a GlobalErrorController
@RestController
@Profile("prod")
public class GlobalErrorController implements ErrorController {
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public void error(HttpServletResponse response) throws IOException {
int status = response.getStatus();
switch (status) {
case 404:
response.sendRedirect("/404");
break;
case 401:
response.sendRedirect("/401");
break;
case 403:
response.sendRedirect("/401");
break;
default:
response.sendRedirect("/404");
}
}
@Override
public String getErrorPath() {
return PATH;
}
}
And in my HomeController I added:
@RequestMapping("404")
String get404ErrorPage() {
return "404";
}
@RequestMapping("401")
String get401ErrorPage() {
return "401";
}
I chose this approach because I need in the error pages some functionality from the controller.
Other solutions are more than welcome!