Java Spring MVC:如何返回自定义 404 错误页面?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21061638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC: How to return custom 404 errorpages?
提问by Christian Rudolph
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.
当找不到请求的资源时,我正在寻找一种干净的方法来在 Spring 4 中返回自定义的 404 错误页面。对不同域类型的查询应该会导致不同的错误页面。
Here some code to show my intention (Meter is a domain class):
这里有一些代码来显示我的意图(Meter 是一个域类):
@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
我想象了几种处理问题的方法。首先将有可能创建RuntimeException
像
@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:
另一种可能性是HttpServletResponse
手动使用和设置状态码:
@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).
但是使用此解决方案,我必须为许多控制器方法(如编辑、删除)复制前 5 行。
Is there an elegant way to prevent duplicating these lines many times?
有没有一种优雅的方法来防止多次重复这些行?
采纳答案by Christian Rudolph
The solution is much simpler than thought. One can use one generic ResourceNotFoundException
defined as follows:
解决方案比想象的要简单得多。可以使用一种ResourceNotFoundException
定义如下的泛型:
public class ResourceNotFoundException extends RuntimeException { }
then one can handle errors within every controller with an ExceptionHandler
annotation:
然后可以使用ExceptionHandler
注释处理每个控制器中的错误:
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
.
每个控制器都可ExceptionHandler
以为ResourceNotFoundException
.
回答by Youddh
modified your web.xmlfile.Using following code.
修改了您的web.xml文件。使用以下代码。
<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.
现在在web.xml 中添加此代码。
<error-page>
<error-code>508802</error-code>
<location>/error500.jsp</location>
</error-page>
回答by Taras
You should follow this article where you can find detailed information about exception handling in Spring MVC projects.
您应该遵循这篇文章,在那里您可以找到有关 Spring MVC 项目中异常处理的详细信息。
@ControllerAdvice may help you in this case
在这种情况下@ControllerAdvice 可能会帮助你
回答by Ekansh Rastogi
You can map the error codes in web.xml like the following
您可以像下面这样映射 web.xml 中的错误代码
<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.
现在您可以创建一个控制器来映射在发现任何这些错误时命中的 url。
@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
有关完整示例,请参阅我的教程
回答by Manoj Kumar
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.
我们只需在web.xml文件中添加以下几行代码,并在项目的根目录中引入一个名为errorPage.jsp的新jsp文件即可完成需求。
<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>
回答by SerdukovAA
Simple answer for 100% free xml:
100% 免费 xml 的简单答案:
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(); }
}
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"; }
}
Create 404.jsp page with any content
设置 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(); }
}
创建@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"; }
}
创建包含任何内容的 404.jsp 页面
That's all.
就这样。
回答by skrueger
I also needed to NOT use org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer
.
我还需要不使用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."
根据org.springframework.web.servlet.DispatcherServlet.setThrowExceptionIfNoHandlerFound(boolean)
:“请注意,如果使用 DefaultServletHttpRequestHandler,则请求将始终转发到默认 servlet,并且在这种情况下永远不会抛出 NoHandlerFoundException。”
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) {
}
// ...
}
回答by Yasitha Bandara
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.
我正在处理一个 Netbeans 项目。我在我的 web.xml 中添加了以下几行。它仅在我提供来自 WEB-INF 文件夹的路径时才有效,如下所示。
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/view/common/errorPage.jsp</location>
</error-page>