杭州网站建设推荐q479185700上墙wordpress美化文章标题
web/
2025/9/29 19:42:55/
文章来源:
杭州网站建设推荐q479185700上墙,wordpress美化文章标题,关键词查询网站的工具,个人建设网站论文ExceptionHandler的作用
ExceptionHandler是Spring框架提供的一个注解#xff0c;用于处理应用程序中的异常。当应用程序中发生异常时#xff0c;ExceptionHandler将优先地拦截异常并处理它#xff0c;然后将处理结果返回到前端。该注解可用于类级别和方法级别#xff0c;…ExceptionHandler的作用
ExceptionHandler是Spring框架提供的一个注解用于处理应用程序中的异常。当应用程序中发生异常时ExceptionHandler将优先地拦截异常并处理它然后将处理结果返回到前端。该注解可用于类级别和方法级别以捕获不同级别的异常。
在Spring中使用ExceptionHandler非常简单只需在需要捕获异常的方法上注解ExceptionHandler然后定义一个方法该方法将接收异常并返回异常信息并将该异常信息展示给前端用户。
ExceptionHandler的使用 说明针对可能出问题的Controller新增注解方法ExceptionHandler下面是一个基本的ExceptionHandler示例 java
RestController
public class ExceptionController {ExceptionHandler(Exception.class)public ResponseEntityString handleException(Exception ex) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(An error occurred: ex.getMessage());}RequestMapping(/test)public String test() throws Exception {throw new Exception(Test exception!);}
}在上面的示例中我们定义了一个叫做ExceptionController的类该类是一个RestController注解的控制器它包括一个可以产生异常的请求处理程序一个用于捕获和处理异常的ExceptionHandler方法。
RequestMapping注解配置了一个名为“/test”的API该API将抛出一个异常该异常将由我们上面的ExceptionHandler进行处理。当请求“/test”时Controller方法将引发异常并触发ExceptionHandler方法。
在上面的ExceptionHandler方法中我们通过ResponseEntity将异常信息提供给客户端HTTP状态码设置为500。这使客户端了解已发生错误并能够在日志中记录异常信息以便日后调试。 总之使用ExceptionHandler能够更好的掌控应用的异常信息使得应用在发生异常的时候更加可控并且更加容易进行调试。 ExceptionHandler的注意事项 Controller类下多个ExceptionHandler上的异常类型不能出现一样的否则运行时抛异常。 ExceptionHandler下方法返回值类型支持多种常见的ModelAndViewResponseBody注解标注ResponseEntity等类型都OK.
源码分析介绍
原理说明-doDispatch 代码片段位于org.springframework.web.servlet.DispatcherServlet#doDispatch 执行RequestMapping方法抛出异常后Spring框架 try-catch的方法捕获异常, 正常逻辑发不发生异常都会走processDispatchResult流程 区别在于异常的参数是否为null .
java HandlerExecutionChain mappedHandler null;Exception dispatchException null;ModelAndView mv null;try{//根据请求查找handlerMapping找到controllermappedHandlergetHandler(request); //找到处理器适配器HandlerAdapterHandlerAdapter ha getHandlerAdapter(mappedHandler.getHandler()); if(!mappedHandler.applyPreHandle(request,response)){ //拦截器preHandlereturn ;} //调用处理器适配器执行RequestMapping方法mvha.handle(request,response); //拦截器postHandlemappedHandler.applyPostHandle(request,response,mv); }catch(Exception ex){dispatchExceptionex;}//将异常信息传入了processDispatchResult(request,response,mappedHandler,mv,dispatchException) 原理说明-processDispatchResult 代码片段位于org.springframework.web.servlet.DispatcherServlet#processDispatchResult 如果 RequestMapping 方法抛出异常拦截器的postHandle方法不执行进入processDispatchResult判断入参dispatchException不为null , 代表发生异常调用processHandlerException处理。
原理说明-processHandlerException 代码片段位于org.springframework.web.servlet.DispatcherServlet#processHandlerException this当前对象指dispatchServlethandlerExceptionResolvers可以看到三个HandlerExceptionResolver这三个是Spring框架帮我们注册的遍历有序集合handlerExceptionResolvers调用接口的resolveException方法。 注册的第一个HandlerExceptionResolver.ExceptionHandlerExceptionResolver, 继承关系如下面所示。 原理说明-AbstractHandlerExceptionResolver 代码片段位于:org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver#resolveException 这里AbstractHandlerExceptionResolver的shouldApplyTo都返回true, logException用来记录日志、prepareResponse方法用来设置response的Cache-Control。 异常处理方法就位于doResolveException 注意AbstractHandlerExceptionResolver和AbstractHandlerMethodExceptionResolver名字看起来非常相似但是作用不同一个是面向整个类的一个是面向方法级别的。 原理说明-AbstractHandlerMethodExceptionResolver 代码片段位于:org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver#shouldApplyTo 接口方法实现AbstractHandlerExceptionResolver的resolveException先判断shouldApplyToAbstractHandlerExceptionResolver 和子类AbstractHandlerMethodExceptionResolver都实现了shouldApplyTo方法子类的shouldApplyTo都调用父类AbstractHandlerExceptionResolver的shouldApplyTo.
父类AbstractHandlerExceptionResolver的shouldApplyTo方法. 代码片段位于:org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver#shouldApplyTo Spring初始化的时候并没有额外配置 , 所以mappedHandlers和mappedHandlerClasses都为null, 可以在这块扩展进行筛选 AbstractHandlerExceptionResolver提供了setMappedHandlerClasses 、setMappedHandlers用于扩展。
doResolveException 代码片段位于org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver#doResolveException Spring请求方法执行一样的处理方式设置argumentResolvers、returnValueHandlers之后进行调用异常处理方法。 获取ExceptionHandler
ExceptionHandler的方法入参支持Exception SessionAttribute 、 RequestAttribute注解、 HttpServletRequest 、HttpServletResponse、HttpSession。 ExceptionHandler方法返回值常见的可以是: ModelAndView 、ResponseBody注解、ResponseEntity。
getExceptionHandlerMethod方法
getExceptionHandlerMethod说明 获取对应的ExceptionHandler方法封装成ServletInvocableHandlerMethod返回。
exceptionHandlerCache是针对Controller层面的ExceptionHandler的处理方式而exceptionHandlerAdviceCache是针对ControllerAdvice的处理方式. 这两个属性都位于ExceptionHandlerExceptionResolver中。 ExceptionHandlerMethodResolver缓存A之前没存储过Controller的class 所以新建一个ExceptionHandlerMethodResolver 加入缓存中ExceptionHandlerMethodResolver 的初始化工作一定做了某些工作。
resolveMethod方法
根据异常对象让 ExceptionHandlerMethodResolver 解析得到 method 匹配到异常处理方法就直接封装成对象 ServletInvocableHandlerMethod 就不会再去走ControllerAdvice里的异常处理器了这里说明了。 resolveMethodByExceptionType根据当前抛出异常寻找 匹配的方法并且做了缓存以后遇到同样的异常可以直接走缓存取出 resolveMethodByExceptionType方法尝试从缓存AexceptionLookupCache中根据异常class类型获取Method 初始时候肯定缓存为空 就去遍历ExceptionHandlerMethodResolver的mappedMethods(上面提及了key为异常类型value为methodexceptionType为当前RequestMapping方法抛出的异常判断当前异常类型是不是ExceptionHandler中value声明的子类或本身满足条件就代表匹配上了
可能存在多个匹配的方法使用ExceptionDepthComparator排序排序规则是按照继承顺序来(继承关系越靠近数值越小当前类最小为0,顶级父类Throwable为int最大值)排序之后选取继承关系最靠近的那个并且ExceptionHandlerMethodResolver的exceptionLookupCache中key为当前抛出的异常value为解析出来的匹配method.
全局级别异常处理器实现HandlerExceptionResolver接口
java
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {ModelMap mmpnew ModelMap();mmp.addAttribute(ex,ex.getMessage());return new ModelAndView(error,mmp);}
}使用方式 只需要将该Bean加入到Spring容器可以通过Xml配置也可以通过注解方式加入容器; 方法返回值不为null才有意义如果方法返回值为null可能异常就没有被捕获. 缺点分析比如这种方式全局异常处理返回JSP、velocity等视图比较方便返回json或者xml等格式的响应就需要自己实现了.如下是我实现的发生全局异常返回JSON的简单例子.
java
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println(发生全局异常!);ModelMap mmpnew ModelMap();mmp.addAttribute(ex,ex.getMessage());response.addHeader(Content-Type,application/json;charsetUTF-8);try {new ObjectMapper().writeValue(response.getWriter(),ex.getMessage());response.getWriter().flush();} catch (IOException e) {e.printStackTrace();}return new ModelAndView();}
}全局级别异常处理器ControllerAdviceExceptionHandler使用方法
用法说明这种情况下 ExceptionHandler与第一种方式用法相同返回值支持ModelAndViewResponseBody等多种形式。
java
ControllerAdvice
public class GlobalController {ExceptionHandler(RuntimeException.class)public ModelAndView fix1(Exception e){System.out.println(全局的异常处理器);ModelMap mmpnew ModelMap();mmp.addAttribute(ex,e);return new ModelAndView(error,mmp);}
}方式一提到ExceptionHandlerExceptionResolver不仅维护Controller级别的ExceptionHandler同时还维护的ControllerAdvice级别的ExceptionHandler代码片段位于 isApplicableToBeanType方法是用来做条件判断的ControllerAdvice注解有很多属性用来设置条件 basePackageClasses、assignableTypes、annotations等比如我限定了annotations为注解X 那标注了X 的ControllerA就可以走这个异常处理器ControllerB就不能走这个异常处理器。
现在问题的关键就只剩下了exceptionHandlerAdviceCache是什么时候扫描ControllerAdvice的下面的逻辑和ExceptionHandler的逻辑一样了exceptionHandlerAdviceCache初始化逻辑: 代码片段位于:org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#afterPropertiesSetafterPropertiesSet是Spring bean创建过程中一个重要环节。 代码片段位于org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#initExceptionHandlerAdviceCache ControllerAdviceBean.findAnnotatedBeans方法查找了SpringMvc父子容器中标注 ControllerAdvice 的bean, new ExceptionHandlerMethodResolver初始化时候解析了当前的ControllerAdvice的bean的ExceptionHandler,加入到ExceptionHandlerExceptionResolver的exceptionHandlerAdviceCache中key为ControllerAdviceBeanvalue为ExceptionHandlerMethodResolver . 到这里exceptionHandlerAdviceCache就初始化完毕。
Spring父子容器中所有ControllerAdivce的bean的方法 代码片段位于org.springframework.web.method.ControllerAdviceBean#findAnnotatedBeans 遍历了SpringMVC父子容器中所有的bean标注ControllerAdvice注解的bean加入集合返回。
比较说明
ControllerExceptionHandler、HandlerExceptionResolver接口形式、ControllerAdviceExceptionHandler优缺点说明
调用优先级
ControllerExceptionHandler优先级最高ControllerAdviceExceptionHandler 略低HandlerExceptionResolver最低。 三种方式并存的情况 优先级越高的越先选择而且被一个捕获处理了就不去执行其他的。 三种方式都支持多种返回类型 ControllerExceptionHandler、ControllerAdviceExceptionHandler可以使用Spring支持的ResponseBody、ResponseEntity。 HandlerExceptionResolver方法声明返回值类型只能是 ModelAndView如果需要返回JSON、xml等需要自己实现.。
缓存利用 ControllerExceptionHandler的缓存信息在ExceptionHandlerExceptionResolver的exceptionHandlerCacheControllerAdviceExceptionHandler的缓存信息在ExceptionHandlerExceptionResolver的exceptionHandlerAdviceCache中, HandlerExceptionResolver接口是不做缓存的在异常报错的情况下才会走自己的HandlerExceptionResolver实现类多少有点性能损耗.
ExceptionHandler的作用ExceptionHandler的使用 ExceptionHandler的注意事项 源码分析介绍 原理说明-doDispatch 原理说明-processDispatchResult 原理说明-processHandlerException 原理说明-AbstractHandlerExceptionResolver 原理说明-AbstractHandlerMethodExceptionResolver 父类AbstractHandlerExceptionResolver的shouldApplyTo方法. doResolveException 全局级别异常处理器实现HandlerExceptionResolver接口全局级别异常处理器ControllerAdviceExceptionHandler使用方法比较说明 调用优先级 三种方式都支持多种返回类型 缓存利用
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84065.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!