Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC: How to return custom 404 errorpages?

I'm looking for a clean way to return customized 404 errorpages in Spring 4 when a requested resource was not found. Queries to different domain types should result in different error pages.

Here some code to show my intention (Meter is a domain class):

@RequestMapping(value = "/{number}", method = RequestMethod.GET)
public String getMeterDetails(@PathVariable("number") final Long number, final Model model) {
    final Meter result = meterService.findOne(number);
    if (result == null) {
        // here some code to return an errorpage
    }

    model.addAttribute("meter", result);
    return "meters/details";
}

I imagine several ways for handling the problem. First there would be the possibility to create RuntimeExceptions like

@ResponseStatus(HttpStatus.NOT_FOUND)
public class MeterNotFoundExcption extends RuntimeException { }

and then use an exception handler to render a custom errorpage (maybe containing a link to a list of meters or whatever is appropriate).

But I don't like polluting my application with many small exceptions.

Another possibility would be using HttpServletResponse and set the statuscode manually:

@RequestMapping(value = "/{number}", method = RequestMethod.GET)
public String getMeterDetails(@PathVariable("number") final Long number, final Model model,
final HttpServletResponse response) {
    final Meter meter = meterService.findOne(number);
    if (meter == null) {
        response.setStatus(HttpStatus.NOT_FOUND.value());
        return "meters/notfound";
    }

    model.addAttribute("meter", meter);
    return "meters/details";
}

But with this solution I have to duplicate the first 5 lines for many controller methods (like edit, delete).

Is there an elegant way to prevent duplicating these lines many times?

like image 208
Christian Rudolph Avatar asked Jan 11 '14 11:01

Christian Rudolph


People also ask

How does Spring MVC handle 404 error?

The 404 error code is configured properly, but it will caused the “. htm” extension handling conflict between the “servlet container” and Spring's “DispatcherServlet“. To solve it, try change the 404. htm to other file extension, for example 404.

How do I redirect 404 error to custom error page?

To have a custom 404 page for this error, we should edit our . htacess file, which is located under the root folder (usually inside the public_html folder for cPanel servers). If you can't find the . htacess file, you can simply create it.

How do I redirect a custom error page in spring boot?

In Spring Boot 1.4. x you can add a custom error page: If you want to display a custom HTML error page for a given status code, you add a file to an /error folder. Error pages can either be static HTML (i.e. added under any of the static resource folders) or built using templates.


4 Answers

The solution is much simpler than thought. One can use one generic ResourceNotFoundException defined as follows:

public class ResourceNotFoundException extends RuntimeException { } 

then one can handle errors within every controller with an ExceptionHandler annotation:

class MeterController {     // ...     @ExceptionHandler(ResourceNotFoundException.class)     @ResponseStatus(HttpStatus.NOT_FOUND)     public String handleResourceNotFoundException() {         return "meters/notfound";     }      // ...      @RequestMapping(value = "/{number}/edit", method = RequestMethod.GET)     public String viewEdit(@PathVariable("number") final Meter meter,                            final Model model) {         if (meter == null) throw new ResourceNotFoundException();          model.addAttribute("meter", meter);         return "meters/edit";     } } 

Every controller can define its own ExceptionHandler for the ResourceNotFoundException.

like image 54
Christian Rudolph Avatar answered Oct 05 '22 23:10

Christian Rudolph


modified your web.xml file.Using following code.

<display-name>App Name </display-name> <error-page> <error-code>500</error-code> <location>/error500.jsp</location> </error-page>  <error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> 

Access this by following code.

response.sendError(508802,"Error Message"); 

Now add this code in web.xml.

<error-page> <error-code>508802</error-code> <location>/error500.jsp</location> </error-page> 
like image 32
Youddh Avatar answered Oct 05 '22 23:10

Youddh


You can map the error codes in web.xml like the following

    <error-page>
        <error-code>400</error-code>
        <location>/400</location>
    </error-page>

    <error-page>
        <error-code>404</error-code>
        <location>/404</location>
    </error-page>

    <error-page>
        <error-code>500</error-code>
        <location>/500</location>
    </error-page>

Now you can create a controller to map the url's that are hit when any of these error is found.

@Controller
public class HTTPErrorHandler{

    String path = "/error";

    @RequestMapping(value="/404")
    public String error404(){
       // DO stuff here 
        return path+"/404";
    }
    }

For full example see my tutorial about this

like image 22
Ekansh Rastogi Avatar answered Oct 05 '22 22:10

Ekansh Rastogi


Simple answer for 100% free xml:

  1. Set properties for DispatcherServlet

    public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfig.class  };
    }
    
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {AppConfig.class  };
    }
    
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
    
    //that's important!!
    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true
        if(!done) throw new RuntimeException();
    }
    

    }

  2. Create @ControllerAdvice:

    @ControllerAdvice
    public class AdviceController {
    
    @ExceptionHandler(NoHandlerFoundException.class)
    public String handle(Exception ex) {
        return "redirect:/404";
    }
    
    @RequestMapping(value = {"/404"}, method = RequestMethod.GET)
    public String NotFoudPage() {
        return "404";
    
    }
    

    }

  3. Create 404.jsp page with any content

That's all.

like image 32
SerdukovAA Avatar answered Oct 06 '22 00:10

SerdukovAA