Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如何在Java配置中使用@ControllerAdvice捕获http状态错误?_Spring_Jakarta Ee_Exception Handling - Fatal编程技术网

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配置方法。所以它不适合我