As you know, in XML, the way to configure this is:
如您所知,在XML中,配置它的方法是:
<error-page>
<error-code>404</error-code>
<location>/my-custom-page-not-found.html</location>
</error-page>
But I haven't found a way to do it in Java config. The first way I tried was:
但我还没有找到一种方法在Java配置中执行此操作。我尝试的第一种方式是:
@RequestMapping(value = "/**")
public String Error(){
return "error";
}
And it appeared to work, but it has conflicts retrieving the resources.
它似乎工作,但它检索资源有冲突。
Is there a way to do it?
有办法吗?
7 个解决方案
#1
18
In Spring Framework, there are number of ways of handing exceptions (and particularly 404 error). Here is a documentation link.
在Spring Framework中,有许多处理异常的方法(尤其是404错误)。这是一个文档链接。
- First, you can still use
error-page
tag in web.xml, and customize error page. Here is an example. - 首先,您仍然可以在web.xml中使用error-page标记,并自定义错误页面。这是一个例子。
-
Second, you can use one
@ExceptionHandler
for all controllers, like this:其次,您可以为所有控制器使用一个@ExceptionHandler,如下所示:
@ControllerAdvice public class ControllerAdvisor { @ExceptionHandler(NoHandlerFoundException.class) public String handle(Exception ex) { return "404";//this is view name } }
For this to work, set throwExceptionIfNoHandlerFound property to true for
DispatcherServlet
in web.xml:为此,请将webEx中的DispatcherServlet的throwExceptionIfNoHandlerFound属性设置为true:
<init-param> <param-name>throwExceptionIfNoHandlerFound</param-name> <param-value>true</param-value> </init-param>
You can also pass some objects to error view, see javadoc for this.
您也可以将一些对象传递给错误视图,请参阅javadoc。
#2
10
The most clean solution since spring 4.2 RC3 is using the new createDispatcherServlet
hook within the class extending AbstractDispatcherServletInitializer
(or indirectly through extending AbstractAnnotationConfigDispatcherServletInitializer
) like this:
自Spring 4.2 RC3以来最干净的解决方案是在扩展AbstractDispatcherServletInitializer(或间接通过扩展AbstractAnnotationConfigDispatcherServletInitializer)的类中使用新的createDispatcherServlet钩子,如下所示:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
/* ... */
@Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
final DispatcherServlet dispatcherServlet = super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
Then you can use a global @ControllerAdvice
(a class that is annotated with @ControllerAdvice
) as described in the reference docs. Within the advice you can handle the NoHandlerFoundException
with an @ExceptionHandler
as described here.
然后,您可以使用全局@ControllerAdvice(使用@ControllerAdvice注释的类),如参考文档中所述。在建议中,您可以使用@ExceptionHandler处理NoHandlerFoundException,如此处所述。
This could look something like this:
这看起来像这样:
@ControllerAdvice
public class NoHandlerFoundControllerAdvice {
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<String> handleNoHandlerFoundException(NoHandlerFoundException ex) {
// prepare responseEntity
return responseEntity;
}
}
#3
4
Use code-based Servlet container initialization as described in the doc and override registerDispatcherServlet method to set throwExceptionIfNoHandlerFound property to true:
使用doc和覆盖registerDispatcherServlet方法中描述的基于代码的Servlet容器初始化将throwExceptionIfNoHandlerFound属性设置为true:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = getServletName();
Assert.hasLength(servletName, "getServletName() may not return empty or null");
WebApplicationContext servletAppContext = createServletApplicationContext();
Assert.notNull(servletAppContext,
"createServletApplicationContext() did not return an application " +
"context for servlet [" + servletName + "]");
DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
// throw NoHandlerFoundException to Controller
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
Assert.notNull(registration,
"Failed to register servlet with name '" + servletName + "'." +
"Check if there is another servlet registered under the same name.");
registration.setLoadOnStartup(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
Filter[] filters = getServletFilters();
if (!ObjectUtils.isEmpty(filters)) {
for (Filter filter : filters) {
registerServletFilter(servletContext, filter);
}
}
customizeRegistration(registration);
}
}
Then create an exception handler:
然后创建一个异常处理程序
@ControllerAdvice
public class ExceptionHandlerController {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "404";// view name for 404 error
}
}
Don't forget about using @EnableWebMvc annotation on your Spring configuration file:
不要忘记在Spring配置文件中使用@EnableWebMvc注释:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {"org.project.etc"})
public class WebConfig extends WebMvcConfigurerAdapter {
...
}
#4
3
Simple answer for 100% free xml:
100%免费xml的简单答案:
-
Set properties for
DispatcherServlet
设置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[] { "/" }; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true if(!done) throw new RuntimeException(); } }
-
Create
@ControllerAdvice
:创建@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"; } }
#5
3
In your web configuration class,
在您的Web配置类中,
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter
Declare a bean as follows,
声明一个bean如下,
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container)
{
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, "/500.html");
container.addErrorPages(error401Page,error404Page,error500Page);
}
};
}
Add the mentioned html files(401.html
.etc) to /src/main/resources/static/
folder.
将提到的html文件(401.html .etc)添加到/ src / main / resources / static /文件夹。
Hope this helps
希望这可以帮助
#6
3
For Java config there is a method setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound)
in DispatcherServlet
. By settting it to true
I guess you are doing same thing
对于Java配置,DispatcherServlet中有一个方法setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound)。通过将其设置为真,我猜你做的是同样的事情
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
then you can can this NoHandlerFoundException.class
in controller advice as stated in above answer
那么你可以在控制器建议中使用这个NoHandlerFoundException.class,如上面的答案中所述
it will be like something
它会像某样东西
public class WebXml implements WebApplicationInitializer{
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
DispatcherServlet dp = new DispatcherServlet(context);
dp.setThrowExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dp);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping(MAPPING_URL);
}
}
#7
1
The solution proposed in comments above really works:
上面评论中提出的解决方案确实有效:
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration)
{
registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}
#1
18
In Spring Framework, there are number of ways of handing exceptions (and particularly 404 error). Here is a documentation link.
在Spring Framework中,有许多处理异常的方法(尤其是404错误)。这是一个文档链接。
- First, you can still use
error-page
tag in web.xml, and customize error page. Here is an example. - 首先,您仍然可以在web.xml中使用error-page标记,并自定义错误页面。这是一个例子。
-
Second, you can use one
@ExceptionHandler
for all controllers, like this:其次,您可以为所有控制器使用一个@ExceptionHandler,如下所示:
@ControllerAdvice public class ControllerAdvisor { @ExceptionHandler(NoHandlerFoundException.class) public String handle(Exception ex) { return "404";//this is view name } }
For this to work, set throwExceptionIfNoHandlerFound property to true for
DispatcherServlet
in web.xml:为此,请将webEx中的DispatcherServlet的throwExceptionIfNoHandlerFound属性设置为true:
<init-param> <param-name>throwExceptionIfNoHandlerFound</param-name> <param-value>true</param-value> </init-param>
You can also pass some objects to error view, see javadoc for this.
您也可以将一些对象传递给错误视图,请参阅javadoc。
#2
10
The most clean solution since spring 4.2 RC3 is using the new createDispatcherServlet
hook within the class extending AbstractDispatcherServletInitializer
(or indirectly through extending AbstractAnnotationConfigDispatcherServletInitializer
) like this:
自Spring 4.2 RC3以来最干净的解决方案是在扩展AbstractDispatcherServletInitializer(或间接通过扩展AbstractAnnotationConfigDispatcherServletInitializer)的类中使用新的createDispatcherServlet钩子,如下所示:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
/* ... */
@Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
final DispatcherServlet dispatcherServlet = super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
Then you can use a global @ControllerAdvice
(a class that is annotated with @ControllerAdvice
) as described in the reference docs. Within the advice you can handle the NoHandlerFoundException
with an @ExceptionHandler
as described here.
然后,您可以使用全局@ControllerAdvice(使用@ControllerAdvice注释的类),如参考文档中所述。在建议中,您可以使用@ExceptionHandler处理NoHandlerFoundException,如此处所述。
This could look something like this:
这看起来像这样:
@ControllerAdvice
public class NoHandlerFoundControllerAdvice {
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<String> handleNoHandlerFoundException(NoHandlerFoundException ex) {
// prepare responseEntity
return responseEntity;
}
}
#3
4
Use code-based Servlet container initialization as described in the doc and override registerDispatcherServlet method to set throwExceptionIfNoHandlerFound property to true:
使用doc和覆盖registerDispatcherServlet方法中描述的基于代码的Servlet容器初始化将throwExceptionIfNoHandlerFound属性设置为true:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = getServletName();
Assert.hasLength(servletName, "getServletName() may not return empty or null");
WebApplicationContext servletAppContext = createServletApplicationContext();
Assert.notNull(servletAppContext,
"createServletApplicationContext() did not return an application " +
"context for servlet [" + servletName + "]");
DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
// throw NoHandlerFoundException to Controller
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
Assert.notNull(registration,
"Failed to register servlet with name '" + servletName + "'." +
"Check if there is another servlet registered under the same name.");
registration.setLoadOnStartup(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
Filter[] filters = getServletFilters();
if (!ObjectUtils.isEmpty(filters)) {
for (Filter filter : filters) {
registerServletFilter(servletContext, filter);
}
}
customizeRegistration(registration);
}
}
Then create an exception handler:
然后创建一个异常处理程序
@ControllerAdvice
public class ExceptionHandlerController {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "404";// view name for 404 error
}
}
Don't forget about using @EnableWebMvc annotation on your Spring configuration file:
不要忘记在Spring配置文件中使用@EnableWebMvc注释:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {"org.project.etc"})
public class WebConfig extends WebMvcConfigurerAdapter {
...
}
#4
3
Simple answer for 100% free xml:
100%免费xml的简单答案:
-
Set properties for
DispatcherServlet
设置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[] { "/" }; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true if(!done) throw new RuntimeException(); } }
-
Create
@ControllerAdvice
:创建@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"; } }
#5
3
In your web configuration class,
在您的Web配置类中,
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter
Declare a bean as follows,
声明一个bean如下,
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container)
{
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, "/500.html");
container.addErrorPages(error401Page,error404Page,error500Page);
}
};
}
Add the mentioned html files(401.html
.etc) to /src/main/resources/static/
folder.
将提到的html文件(401.html .etc)添加到/ src / main / resources / static /文件夹。
Hope this helps
希望这可以帮助
#6
3
For Java config there is a method setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound)
in DispatcherServlet
. By settting it to true
I guess you are doing same thing
对于Java配置,DispatcherServlet中有一个方法setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound)。通过将其设置为真,我猜你做的是同样的事情
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
then you can can this NoHandlerFoundException.class
in controller advice as stated in above answer
那么你可以在控制器建议中使用这个NoHandlerFoundException.class,如上面的答案中所述
it will be like something
它会像某样东西
public class WebXml implements WebApplicationInitializer{
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
DispatcherServlet dp = new DispatcherServlet(context);
dp.setThrowExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dp);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping(MAPPING_URL);
}
}
#7
1
The solution proposed in comments above really works:
上面评论中提出的解决方案确实有效:
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration)
{
registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}