Spring 如何在Java配置中使用@ControllerAdvice捕获http状态错误?
我有这样的控制器来处理异常:Spring 如何在Java配置中使用@ControllerAdvice捕获http状态错误?,spring,jakarta-ee,exception-handling,Spring,Jakarta Ee,Exception Handling,我有这样的控制器来处理异常: @ControllerAdvice public class GlobalErrorController { public static final String DEFAULT_ERROR_VIEW = "errors/default"; @ExceptionHandler(Throwable.class) public ModelAndView exception(Exception e) { ModelAndView mav = new Mode
@ControllerAdvice
public class GlobalErrorController {
public static final String DEFAULT_ERROR_VIEW = "errors/default";
@ExceptionHandler(Throwable.class)
public ModelAndView exception(Exception e) {
ModelAndView mav = new ModelAndView(DEFAULT_ERROR_VIEW);
mav.addObject("name", e.getClass().getSimpleName());
mav.addObject("message", e.getMessage());
return mav;
}
}
捕获任何异常,但如何捕获404和其他http状态错误?
@ControllerAdvice
和@ExceptionHandler
仅捕获实际修补到dispatcherservlet的代码引发的异常。如果请求从未进入控制器类,那么这将不起作用
相反,您必须在web.xml中进行错误代码映射,如下所示:
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
404
/404
然后,您可以映射URL/404,以显示包含所需内容的任何视图。用户永远不会被重定向到该URL或知道它存在。映射到/404的控制器方法还可以包含异常参数。
@ControllerAdvice
和@ExceptionHandler
仅捕获实际通过dispatcherservlet修补的代码引发的异常。如果请求从未进入控制器类,那么这将不起作用
相反,您必须在web.xml中进行错误代码映射,如下所示:
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
404
/404
然后,您可以映射URL/404,以显示包含所需内容的任何视图。用户永远不会被重定向到该URL或知道它存在。映射到/404的控制器方法还可以包含异常参数。您不能使用
@ExceptionHandler
捕获在控制器之前或之后引发的异常
但您可以注册自定义的
HandlerExceptionResolver
。一种简单的方法是只扩展DefaultHandlerExceptionResolver
,但您也可以配置SimpleMappingExceptionResolver
,并使用order
属性使其优先于默认值。您不能使用@ExceptionHandler
捕获在控制器之前或之后引发的异常
但您可以注册自定义的
HandlerExceptionResolver
。一种简单的方法是只扩展DefaultHandlerExceptionResolver
,但您也可以配置SimpleMappingExceptionResolver
,并使用order
属性使其优先于默认值。解决方案非常简单。当我使用Java配置方法时,最终得到的smth如下:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { JPAConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = super.getServletName();
Assert.hasLength(servletName, "getServletName() may not return empty or null");
WebApplicationContext servletAppContext = super.createServletApplicationContext();
Assert.notNull(servletAppContext,
"createServletApplicationContext() did not return an application " +
"context for servlet [" + servletName + "]");
DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
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());
super.customizeRegistration(registration);
}
}
公共类AppInitializer扩展AbstractAnnotationConfigDispatcherServletInitializer{
@凌驾
受保护类[]getRootConfigClasses(){
返回新类[]{JPAConfig.Class};
}
@凌驾
受保护类[]getServletConfigClasses(){
返回新类[]{WebConfig.Class};
}
@凌驾
受保护的字符串[]getServletMappings(){
返回新字符串[]{”/“};
}
@凌驾
受保护的无效注册表DispatcherServlet(ServletContext ServletContext){
字符串servletName=super.getServletName();
hasLength(servletName,“getServletName()不能返回空或null”);
WebApplicationContext servletAppContext=super.createServletApplicationContext();
Assert.notNull(servletAppContext,
“createServletApplicationContext()未返回应用程序”+
“servlet[“+servletName+”]”的上下文;
DispatcherServlet DispatcherServlet=新DispatcherServlet(servletAppContext);
dispatcherServlet.SetThroweExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic registration=servletContext.addServlet(servletName,dispatcherServlet);
Assert.notNull(注册,
无法注册名为“+servletName+”的servlet+
“检查是否有另一个servlet以相同的名称注册。”);
注册。设置加载启动(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
超级用户注册(注册);
}
}
使用ControllerAdvice+ExceptionHandler注释解决方案非常简单。当我使用Java配置方法时,最终得到的smth如下:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { JPAConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = super.getServletName();
Assert.hasLength(servletName, "getServletName() may not return empty or null");
WebApplicationContext servletAppContext = super.createServletApplicationContext();
Assert.notNull(servletAppContext,
"createServletApplicationContext() did not return an application " +
"context for servlet [" + servletName + "]");
DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
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());
super.customizeRegistration(registration);
}
}
公共类AppInitializer扩展AbstractAnnotationConfigDispatcherServletInitializer{
@凌驾
受保护类[]getRootConfigClasses(){
返回新类[]{JPAConfig.Class};
}
@凌驾
受保护类[]getServletConfigClasses(){
返回新类[]{WebConfig.Class};
}
@凌驾
受保护的字符串[]getServletMappings(){
返回新字符串[]{”/“};
}
@凌驾
受保护的无效注册表DispatcherServlet(ServletContext ServletContext){
字符串servletName=super.getServletName();
hasLength(servletName,“getServletName()不能返回空或null”);
WebApplicationContext servletAppContext=super.createServletApplicationContext();
Assert.notNull(servletAppContext,
“createServletApplicationContext()未返回应用程序”+
“servlet[“+servletName+”]”的上下文;
DispatcherServlet DispatcherServlet=新DispatcherServlet(servletAppContext);
dispatcherServlet.SetThroweExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic registration=servletContext.addServlet(servletName,dispatcherServlet);
Assert.notNull(注册,
无法注册名为“+servletName+”的servlet+
“检查是否有另一个servlet以相同的名称注册。”);
注册。设置加载启动(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
超级用户注册(注册);
}
}
使用ControllerAdvice+ExceptionHandler注释我知道这个解决方案,但问题是该项目使用了Java配置方法。所以不适合meI了解这个解决方案,但问题是该项目使用了Java配置方法。所以它不适合我