当前位置: 首页 > 科技观察

你知道SpringMVC异常处理句柄的细节吗?

时间:2023-03-14 12:56:35 科技观察

回顾@Controller和@ControllerAdvice类可以使用@ExceptionHandler注解注解方法来处理controller方法的异常,如下例所示:Localexceptionhandling@ControllerpublicclassSimpleController{//...//canonly处理当前SimpleController中发生的Exception@ExceptionHandlerpublicResponseEntityhandle(Exceptionex){//...}}全局异常处理@RestControllerAdvicepublicclassTestControllerAdvice{//全局异常处理@ExceptionHandlerpublicObjecthandle(Exceptione){return"我是一个全局异常:"+e.getMessage();}}指定可以处理的异常类型@ExceptionHandler({FileSystemException.class,RemoteException.class})publicResponseEntityhandle(Exceptionex){//...}在@ExceptionHandler中指定可以处理的异常类。以上就是SpringMVC异常处理的基本使用回顾。通过@ExceptionHandler注解方法,在上述方法中接受异常类。这个方法可以接收什么样的参数和返回值?异常处理程序参数@ExceptionHandler方法支持以下参数:方法参数描述用于访问引发的异常的异常类型。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实例转换后写入response。请参阅@ResponseBody。HttpEntity、ResponseEntity返回值指定完整的响应(包括HTTP标头和文本)由HttpMessageConverter实例转换并写入响应。请参见响应实体。String要通过ViewResolver实现解析并与隐式模型一起使用的视图的名称-通过命令对象和@ModelAttribute方法确定。处理程序方法还可以通过声明模型参数(如前所述)以编程方式丰富模型。View用于呈现隐式模型的View实例-由命令对象和@ModelAttribute方法确定。处理程序方法还可以通过声明模型参数(如前所述)以编程方式丰富模型。java.util.Map、org.springframework.ui.Model属性被添加到隐式模型中,视图名称通过RequestToViewNameTranslator隐式确定。@ModelAttribute添加到模型的属性通过RequestToViewNameTranslator隐式确定视图名称。请注意,@ModelAttribute是可选的。请参阅此表末尾的“任何其他返回值”。ModelAndView对象要使用的视图和模型属性以及(可选)响应状态。void具有void返回类型(或void返回值)的方法如果还具有ServletResponse、OutputStream参数或@ResponseStatus注释,则被认为已完全处理响应。如果控制器进行了肯定的ETag或lastModified时间戳检查,情况也是如此(有关详细信息,请参阅控制器)。如果以上都不成立,则void返回类型也可以代表REST控制器的“无响应主体”或HTML控制器的默认视图名称选择。任何其他返回值如果返回值与上述任何一个都不匹配,并且不是简单类型(由BeanUtils#isSimpleProperty确定),默认情况下它将被视为要添加到模型中的模型属性。如果是简单类型,还是没有解决。RESTAPI异常REST服务的一个常见要求是在响应正文中包含错误详细信息。Spring框架不会自动执行此操作,因为响应主体中错误详细信息的表示是特定于应用程序的。但是,@RestController可以使用带有ResponseEntity返回值的@ExceptionHandler方法来设置响应的状态和正文。这些方法也可以在@ControllerAdvice类中声明,以便全局应用。在响应主体中实现带有错误详细信息的全局异常处理的应用程序应考虑扩展ResponseEntityExceptionHandler,它提供对SpringMVC引发的异常的处理,并提供用于自定义响应主体的挂钩。要使用它,创建一个ResponseEntityExceptionHandler的子类,用@ControllerAdvice注释它,覆盖必要的方法,并将它声明为一个Springbean,如下所示:对象主体、HttpHeaders标头、HttpStatus状态、WebRequest请求){System.out.println(">>>>>>>>>>>>-body-"+body);System.out.println(">>>>>>>>>>>-标题-"+标题);System.out.println(">>>>>>>>>>>>-状态-"+状态);返回新的ResponseEntity<>(ex.getMessage(),headers,status);ResponseEntityExceptionHandler类内置了多种类型的异常处理AcceptableException.class、MissingPathVariableException.class、MissingServletRequestParameterException.class、ServletRequestBindingException.class、ConversionNotSupportedException.class、TypeMismatchException.class、HttpMessageNotReadableException.class、HttpMessageNotWritableException.class、MethodArgumentNotValidException.class、MissingServletRequestPartException.class、BindException.class、NoHandlerFoundExceptionTimeout.class、Async.类})@NullablepublicfinalResponseEntityhandleException(Exceptionex,WebRequestrequest)throwsException{HttpHeadersheaders=newHttpHeaders();if(exinstanceofHttpRequestMethodNotSupportedException){HttpStatus状态=HttpStatus.METHOD_NOT_ALLOWED;返回handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException)ex,headers,status,request);}elseif(exinstanceofHttpMediaTypeNotSupportedException){HttpStatus状态=HttpStatus.UNSUPPORTED_MEDIA_TYPE;返回handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException)ex,headers,status,request);}//...否则{抛出ex;}}}