Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 491 Vote(s) - 3.45 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Spring MVC: How to return custom 404 errorpages?

#1
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):
<!-- language: lang-java -->

@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 `RuntimeException`s like
<!-- language: lang-java -->

@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:
<!-- language: lang-java -->

@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?
Reply

#2
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>


Reply

#3
You should follow this article where you can find detailed information about exception handling in Spring MVC projects.

[spring-mvc-exception-handling][1]

@ControllerAdvice may help you in this case

[1]:

[To see links please register here]

Reply

#4
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`.
Reply

#5
We can just add following lines of code into web.xml file and introduce a new jsp file named errorPage.jsp into root directory of the project to get the requirement done.

<error-page>
<error-code>400</error-code>
<location>/errorPage.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/errorPage.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/errorPage.jsp</location>
</error-page>
Reply

#6
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.

Reply

#7
I also needed to NOT use `org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer`.

According to `org.springframework.web.servlet.DispatcherServlet.setThrowExceptionIfNoHandlerFound(boolean)`: "Note that if DefaultServletHttpRequestHandler is used, then requests will always be forwarded to the default servlet and a NoHandlerFoundException would never be thrown in that case."

[To see links please register here]

-

**Before**

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.foo.web")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}

// ...
}

**After**

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.foo.web")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}

// ...
}
Reply

#8
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][1]


[1]:

[To see links please register here]

Reply

#9
I'm working with a Netbeans project.I added following lines to my web.xml.It only works when I give the path from WEB-INF folder as follows.

<error-page>
<error-code>404</error-code>
<location>/WEB-INF/view/common/errorPage.jsp</location>
</error-page>
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through