环境:Spring5。3。23回顾 Controller和ControllerAdvice类可以使用ExceptionHandler注解标注方法来处理控制器方法的异常,如下例所示:局部异常处理ControllerpublicclassSimpleController{。。。只能处理当前SimpleController中发生的异常ExceptionHandlerpublicResponseEntityStringhandle(Exceptionex){。。。}}全局异常处理RestControllerAdvicepublicclassTestControllerAdvice{全局异常处理ExceptionHandlerpublicObjecthandle(Exceptione){return我是全局异常:e。getMessage();}}指定能处理的异常类型ExceptionHandler({FileSystemException。class,RemoteException。class})publicResponseEntityStringhandle(Exceptionex){。。。} 在ExceptionHandler中指明能够处理的异常类。 以上是回顾了SpringMVC异常处理的基本使用,通过ExceptionHandler注解标注方法,在上面的方法中都接受的是异常类,那这方法可以接收什么样的参数及返回值呢?异常句柄参数 ExceptionHandler方法支持以下参数: 方法参数 描述 Exceptiontype 用于访问引发的异常。 HandlerMethod 用于访问引发异常的控制器方法。 WebRequest,NativeWebRequest 对请求参数、请求和会话属性的通用访问,而不直接使用ServletAPI。 javax。servlet。ServletRequest,javax。servlet。ServletResponse 选择任何特定的请求或响应类型(例如,ServletRequest或HttpServletRequest或Spring的MultipartRequest或MultipartHttpServletRequest)。 javax。servlet。http。HttpSession 强制会话的存在。因此,这样的参数永远不会为空。注意,会话访问不是线程安全的。如果允许多个请求并发访问一个会话,可以考虑将RequestMappingHandlerAdapter实例的synchronizeOnSession标志设置为true。 java。security。Principal 当前已验证的用户如果已知,可能是特定的Principal实现类。 HttpMethod 请求的HTTP方法。 java。util。Locale 当前请求区域设置,由可用的最特定的LocaleResolver确定实际上是配置的LocaleResolver或LocaleContextResolver。 java。util。TimeZone,java。time。ZoneId 与当前请求关联的时区,由LocaleContextResolver确定。 java。io。OutputStream,java。io。Writer 用于访问由ServletAPI公开的原始响应体。 java。util。Map,org。springframework。ui。Model,org。springframework。ui。ModelMap 用于访问错误响应的模型。总是空的。 RedirectAttributes 指定在重定向情况下使用的属性(将被追加到查询字符串中)和临时存储的flash属性,直到重定向后的请求。请参见重定向属性和Flash属性。 SessionAttribute 对于任何会话属性的访问,与作为类级SessionAttributes声明的结果存储在会话中的模型属性相反。更多细节请参见SessionAttribute。 RequestAttribute 用于访问请求属性。详见RequestAttribute。异常句柄返回值 ExceptionHandler方法支持以下返回值: 返回值 描述 ResponseBody 返回值通过HttpMessageConverter实例转换并写入响应。看到ResponseBody。 HttpEntity,ResponseEntity 返回值指定通过HttpMessageConverter实例转换完整响应(包括HTTP报头和正文)并将其写入响应。看到ResponseEntity。 String 要用ViewResolver实现解析的视图名称,并与隐式模型一起使用通过命令对象和ModelAttribute方法确定。处理程序方法还可以通过声明model参数(前面描述过)以编程方式丰富模型。 View 一个用于呈现隐式模型的View实例通过命令对象和ModelAttribute方法确定。处理程序方法还可以通过声明model参数(前面描述过)以编程方式丰富模型。 java。util。Map,org。springframework。ui。Model 属性被添加到隐式模型中,视图名通过RequestToViewNameTranslator隐式确定。 ModelAttribute添加到模型中的属性,通过RequestToViewNameTranslator隐式确定视图名。 注意ModelAttribute是可选的。请参阅该表末尾的任何其他返回值。 ModelAndViewobject 要使用的视图和模型属性以及(可选的)响应状态。 void具有void返回类型(或空返回值)的方法,如果它还具有ServletResponse、OutputStream参数或ResponseStatus注释,则认为它已经完全处理了响应。如果控制器已经做了一个正的ETag或lastModified时间戳检查(详情请参阅Controllers),同样也是正确的。 如果以上都不为真,void返回类型也可以表示REST控制器的无响应体或HTML控制器的默认视图名称选择。 Anyotherreturnvalue 如果返回值与上述任何一个都不匹配,并且不是简单类型(由BeanUtilsisSimpleProperty决定),默认情况下,它将被视为要添加到模型中的模型属性。如果是简单类型,则仍未解决。RESTAPI异常 REST服务的一个常见需求是在响应体中包含错误详细信息。Spring框架不会自动执行此操作,因为响应体中的错误细节表示是特定于应用程序的。但是,RestController可以使用带有ResponseEntity返回值的ExceptionHandler方法来设置响应的状态和主体。这样的方法也可以在ControllerAdvice类中声明,以便全局应用它们。 在响应体中使用错误细节实现全局异常处理的应用程序应该考虑扩展ResponseEntityExceptionHandler,它为SpringMVC引发的异常提供处理,并提供自定义响应体的钩子。要使用它,可以创建ResponseEntityExceptionHandler的子类,用ControllerAdvice注释它,重写必要的方法,并将其声明为Springbean,如下:RestControllerAdvicestaticclassCustomResponseEntityExceptionHandlerextendsResponseEntityExceptionHandler{OverrideprotectedResponseEntityObjecthandleExceptionInternal(Exceptionex,Objectbody,HttpHeadersheaders,HttpStatusstatus,WebRequestrequest){System。out。println(bodybody);System。out。println(headersheaders);System。out。println(statusstatus);returnnewResponseEntity(ex。getMessage(),headers,status);}} ResponseEntityExceptionHandler类中内置了很多类型的异常处理publicabstractclassResponseEntityExceptionHandler{ExceptionHandler({HttpRequestMethodNotSupportedException。class,HttpMediaTypeNotSupportedException。class,HttpMediaTypeNotAcceptableException。class,MissingPathVariableException。class,MissingServletRequestParameterException。class,ServletRequestBindingException。class,ConversionNotSupportedException。class,TypeMismatchException。class,HttpMessageNotReadableException。class,HttpMessageNotWritableException。class,MethodArgumentNotValidException。class,MissingServletRequestPartException。class,BindException。class,NoHandlerFoundException。class,AsyncRequestTimeoutException。class})NullablepublicfinalResponseEntityObjecthandleException(Exceptionex,WebRequestrequest)throwsException{HttpHeadersheadersnewHttpHeaders();if(exinstanceofHttpRequestMethodNotSupportedException){HttpStatusstatusHttpStatus。METHODNOTALLOWED;returnhandleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException)ex,headers,status,request);}elseif(exinstanceofHttpMediaTypeNotSupportedException){HttpStatusstatusHttpStatus。UNSUPPORTEDMEDIATYPE;returnhandleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException)ex,headers,status,request);}。。。else{throwex;}}} 完毕!!! 关注我不迷路 完全自定义实现SpringMVC核心组件 SpringWebFluxSecurity结合R2DBC实现权限控制