1.错误(异常)处理
默认错误处理
在servlet容器中,Spring Boot默认提供一个“/error”映射,作为全局的错误页面。
- 非浏览器端,该映射返回JSON格式的错误信息;
- 浏览器端,该映射返回一个默认的错误页面,错误页面为“whiteLabel”。
自定义错误处理
如果不想使用spring boot默认的错误处理,你可以实现ErrorController接口,然后注册该类型的bean定义或者添加类型为ErrorAttributes的bean。demo
BasicErrorController
自定义错误处理,也可以通过继承BasicErrorController类来实现。BasicErrorController类已经实现了ErrorController接口,该中已经有一个默认处理text/html的方法。如果你想添加一个新内容类型(如JSON)的处理程序,你需要添加一个具有@RequestMapping属性的方法,然后返回你自定义的实体类。
@ControllerAdvice
自定义错误处理,还可以定义一个带有@ControllerAdvice注释的类,返回自定义的JSON格式信息给特定的控制器或异常,如:
@ControllerAdvice(basePackageClasses = AcmeController.class)
public class AcmeControllerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(YourException.class)
@ResponseBody
ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
}
如果你抛出的Exception的Controller所在的包,和AcmeController所在的包是同一个。那么,你定义的JSON格式的异常信息就会替代原有的ErrorAttributes。
注:@ControllerAdvice只能接收来自controller层的异常或者错误。
2.异常页面
如果要为给定的状态代码显示你自己定义HTML错误页面,你需要将文件添加到/error文件夹中。错误页面可以是静态HTML(html的位置可以添加到任何静态资源文件夹下),也可以使用模板构建。文件的名称应该是确切的状态码或该系列掩码。例如:
- 404 客户端异常
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
- 5xx 服务端异常
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
还可以通过添加实现ErrorViewResolver接口的bean,应对更加复杂的映射,如
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
}
3.非Spring MVC异常页面
对于没有使用Spring MVC框架的应用,可以使用ErrorPageRegistrar接口直接注册ErrorPages。该抽象方法直接与底层嵌入式servlet容器一起工作,即使没有Spring MVC的DispatcherServlet也可以工作。如:
@Bean
public ErrorPageRegistrar errorPageRegistrar(){
return new MyErrorPageRegistrar();
}
// ...
private static class MyErrorPageRegistrar implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
}
}
如果你用一个路径注册了一个ErrorPage,这个路径最终会被一个过滤器处理(在非spring web框架中很常见,比如Jersey和Wicket),那么这个过滤器必须显式注册为一个错误调度程序,如下例所示:
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
注意,默认的FilterRegistrationBean不包含错误分发起类型。
注意:当部署到servlet容器时,Spring Boot使用其错误页面过滤器将带有错误状态的请求转发到适当的错误页面。如果响应还没有提交,请求只能被转发到正确的错误页面。默认情况下,WebSphere Application Server 8.0或更高版本在servlet服务方法成功完成后提交响应。您应该通过设置com.ibm.ws.webcontainer来禁用此行为。invokeFlushAfterService为false。
网友评论