当前位置: 首页 > news >正文

如何做阿语垂直网站平台门户

如何做阿语垂直网站,平台门户,建设银行信用卡中心网站首页,谷歌网站推广https://www.bilibili.com/video/BV1sS411c7Mo 文章目录 一、全局异常处理器的类型1-1、实现方式一1-2、实现方式二 二、全局异常拦截点2-1、入口2-2、全局异常拦截器是如何注入到 DispatcherServlet 的 三、ControllerAdvice 如何解析、执行3-1、解析3-2、执行 四、其它4-1、设…https://www.bilibili.com/video/BV1sS411c7Mo 文章目录 一、全局异常处理器的类型1-1、实现方式一1-2、实现方式二 二、全局异常拦截点2-1、入口2-2、全局异常拦截器是如何注入到 DispatcherServlet 的 三、ControllerAdvice 如何解析、执行3-1、解析3-2、执行 四、其它4-1、设置HTTP状态码4-2、异常处理器排序4-3、所谓全局异常 最近在做系统升级的时候引发了一个BUG原本系统是有一个异常处理器A引入了某个底包中也带了一个异常处理器B最终走了底包的异常处理器B。 A对于异常的时候会返回HTTP状态码为500B对于异常处理器返回的HTTP状态码为200前端基于HTTP状态码进行提示的就出了问题 本篇文章我们就来讨论一下在JavaWeb中的全局异常处理器是何时何地如何执行的。 在进行学习之前需要先知道HTTP执行流程SpringMVC执行流程 一、全局异常处理器的类型 全局异常处理器的父接口是 HandlerExceptionResolver简单来说就是实现或间接实现它的类就叫全局异常处理器。 package org.springframework.web.servlet;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable;public interface HandlerExceptionResolver {NullableModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Nullable Object handler, Exception ex); }HandlerExceptionResolver 的继承关系图 1-1、实现方式一 SpringBoot项目最大的特点就是注解在SpringBoot项目中全局异常拦截的注解是ControllerAdvice RestControllerAdvice ControllerAdvice ResponseBody 使用 ControllerAdvice的类最终会生成 ExceptionHandlerExceptionResolver 1-2、实现方式二 重写 doResolveHandlerMethodException 方法然后注册当前的bean public class ExceptionHandler extends AbstractHandlerMethodExceptionResolver {private final static Logger logger LoggerFactory.getLogger(ExceptionHandler.class);Overrideprotected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception ex) {return new ModelAndView();} }二、全局异常拦截点 2-1、入口 org.springframework.web.servlet.DispatcherServlet#doDispatch 这个方法就是SpringMVC的执行流程的核心代码了下面是简化代码 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest request;HandlerExecutionChain mappedHandler null;boolean multipartRequestParsed false;WebAsyncManager asyncManager WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv null;Exception dispatchException null;try {// ...mv ha.handle(processedRequest, response, mappedHandler.getHandler());// ....}catch (Exception ex) {dispatchException ex;}catch (Throwable err) {dispatchException new NestedServletException(Handler dispatch failed, err);}// 异常处理的入口processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {// ....}catch (Throwable err) {// ....}finally {// ... } }org.springframework.web.servlet.DispatcherServlet#processDispatchResult private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,Nullable HandlerExecutionChain mappedHandler, Nullable ModelAndView mv,Nullable Exception exception) throws Exception {boolean errorView false;if (exception ! null) {Object handler (mappedHandler ! null ? mappedHandler.getHandler() : null);// 异常处理mv processHandlerException(request, response, handler, exception);errorView (mv ! null);}// ... }org.springframework.web.servlet.DispatcherServlet#processHandlerException protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,Nullable Object handler, Exception ex) throws Exception {// Success and error responses may use different content typesrequest.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);// Check registered HandlerExceptionResolvers...ModelAndView exMv null;if (this.handlerExceptionResolvers ! null) {// 遍历循环所有的拦截器来尝试处理这个异常拦截器已经按照 order 排好序了for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {exMv resolver.resolveException(request, response, handler, ex);// 只有返回了 ModelAndView 才结束不然一直往下走if (exMv ! null) {break;}}}// ...// 如果没有全局异常处理器 可以处理这个异常 就继续抛出去throw ex; }2-2、全局异常拦截器是如何注入到 DispatcherServlet 的 上面看到是从 handlerExceptionResolvers 从获取所有的异常处理器它是一个list Nullable private ListHandlerExceptionResolver handlerExceptionResolvers;在DispatcherServlet里面有一个onRefresh方法它是重写的父类FrameworkServlet的在初始化ServletBean的时候会被调用一次它里面会做很多初始化的操作其中一个就是获取容器里面的全局异常拦截器 一层层看上去其实是 Servlet接口的 init方法触发的 Override protected void onRefresh(ApplicationContext context) {initStrategies(context); }protected void initStrategies(ApplicationContext context) {// ...initHandlerExceptionResolvers(context);// ... }找到bean容器里面的所有异常拦截器把它存在 handlerExceptionResolvers 里面并排序 private void initHandlerExceptionResolvers(ApplicationContext context) {this.handlerExceptionResolvers null;if (this.detectAllHandlerExceptionResolvers) {// 从bean容器里面找到所有的 HandlerExceptionResolverMapString, HandlerExceptionResolver matchingBeans BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);if (!matchingBeans.isEmpty()) {this.handlerExceptionResolvers new ArrayList(matchingBeans.values());// 排序AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);}}// ... }三、ControllerAdvice 如何解析、执行 3-1、解析 在springframework 中有这样一个类 ExceptionHandlerExceptionResolver package org.springframework.web.servlet.mvc.method.annotation;public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolverimplements ApplicationContextAware, InitializingBean {// ... }⚠️可以回到【全局异常处理器的类型】的图看看ExceptionHandlerExceptionResolver其实就是全局异常处理器HandlerExceptionResolver的子类 它实现了 InitializingBean重写了afterPropertiesSet这个方法会在bean初始化完之后执行 Override public void afterPropertiesSet() {// Do this first, it may add ResponseBodyAdvice beansinitExceptionHandlerAdviceCache();// ... }initExceptionHandlerAdviceCache 会把所有使用了ControllerAdvice 的bean找到并把它存在自己的参数里面 private final MapControllerAdviceBean, ExceptionHandlerMethodResolver exceptionHandlerAdviceCache new LinkedHashMap();private void initExceptionHandlerAdviceCache() {if (getApplicationContext() null) {return;}// 找到所有使用了 ControllerAdvice 的beanListControllerAdviceBean adviceBeans ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());for (ControllerAdviceBean adviceBean : adviceBeans) {Class? beanType adviceBean.getBeanType();if (beanType null) {throw new IllegalStateException(Unresolvable type for ControllerAdviceBean: adviceBean);}// 解析全部的 ExceptionHandler 注解ExceptionHandlerMethodResolver resolver new ExceptionHandlerMethodResolver(beanType);if (resolver.hasExceptionMappings()) {// 存入当前的类参数里面this.exceptionHandlerAdviceCache.put(adviceBean, resolver);}if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {this.responseBodyAdvice.add(adviceBean);}}// ... }org.springframework.web.method.ControllerAdviceBean#findAnnotatedBeans public static ListControllerAdviceBean findAnnotatedBeans(ApplicationContext context) {ListableBeanFactory beanFactory context;if (context instanceof ConfigurableApplicationContext) {// Use internal BeanFactory for potential downcast to ConfigurableBeanFactory abovebeanFactory ((ConfigurableApplicationContext) context).getBeanFactory();}ListControllerAdviceBean adviceBeans new ArrayList();// 遍历所有的beanfor (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Object.class)) {if (!ScopedProxyUtils.isScopedTarget(name)) {// 找到符合的beanControllerAdvice controllerAdvice beanFactory.findAnnotationOnBean(name, ControllerAdvice.class);if (controllerAdvice ! null) {// 存起来adviceBeans.add(new ControllerAdviceBean(name, beanFactory, controllerAdvice));}}}// 排序OrderComparator.sort(adviceBeans);return adviceBeans; }配合ControllerAdvice 注解的通常是 ExceptionHandler 它用来制定具体的异常把所有的 ExceptionHandler都存入了 mappedMethods 中org.springframework.web.method.annotation.ExceptionHandlerMethodResolver#ExceptionHandlerMethodResolver public ExceptionHandlerMethodResolver(Class? handlerType) {for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {for (Class? extends Throwable exceptionType : detectExceptionMappings(method)) {addExceptionMapping(exceptionType, method);}} } private void addExceptionMapping(Class? extends Throwable exceptionType, Method method) {Method oldMethod this.mappedMethods.put(exceptionType, method);if (oldMethod ! null !oldMethod.equals(method)) {throw new IllegalStateException(Ambiguous ExceptionHandler method mapped for [ exceptionType ]: { oldMethod , method });} }至此ControllerAdvice的解析完成 生成了一个ExceptionHandlerExceptionResolver它通过多级实现了 HandlerExceptionResolver所有使用ControllerAdvice的类都存在了 exceptionHandlerAdviceCache 中所有使用 ExceptionHandler 的方法否存在了mappedMethods 中 3-2、执行 从【2-1】得知执行异常处理器的时候是执行 HandlerExceptionResolver.resolveException方法它只有这一个方法从【3-1】得知所有使用 ControllerAdvice 注解的类都被存在了ExceptionHandlerExceptionResolver 中从【1】得知ExceptionHandlerExceptionResolver的继承关系如下图 一层层去看调用关系最终会执行的是 这个很简单直接去看即可org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException 执行过程就是循环exceptionHandlerAdviceCache中的每一个全局拦截器再循环每个拦截器里面的mappedMethods看哪个可以匹配上就执行哪个 四、其它 4-1、设置HTTP状态码 大多数情况下我们会自定义返回值code比如未鉴权返回给前端HTTP状态码是200code为401但在某些情况下也会直接返回HTTP状态码401可以使用 ResponseStatus ResponseStatus(HttpStatus.UNAUTHORIZED) ExceptionHandler(Exception.class) public ResultObj bizExceptionHandler(Exception e) {log.info(全局异常拦截, e);return ResultObj.success(); }4-2、异常处理器排序 springframework 里面提供了一个Ordered 接口实现它重写里面 getOrder 方法就可以进行排序了 4-3、所谓全局异常 并不是系统任何异常都会被它所拦截因为我们已经知道它的执行点是在MVC的流程中所以就只有HTTP异常才会被拦截处理
http://www.hkea.cn/news/14307602/

相关文章:

  • 模板网站配置文件移动网页设计
  • 网站开发的检索速度在啥范围之内wordpress移除评论
  • 网站备案期间如何google搜索引擎入口 镜像
  • 株洲网站建设方案咨询登陆网站密码不保存怎么做
  • 怎么做网站弹窗通知网站域名需icp备案吗
  • 做推广网站的文章nginx wordpress 重写
  • 婚纱网站设计代码html重庆市建设工程信息网 施工许可
  • 中国小康建设网是骗子网站吗?阿坝州建设局网站刘志彬
  • 进口跨境电商网站制作河南红旗渠建设集团网站
  • 温州营销网站制作报价济南市住房和城乡建设局官网
  • 苏州网站搜索排名相册管理网站模板下载
  • 个人备案网站可以做淘宝客吗城乡建设厅建设网站
  • 做网站的顶部图片手机网站建设注册塔山双喜
  • 多层分销网站建设企业建站的费用
  • oecms(php企业网站管理系统)网站如何做快捷支付
  • 利用网站源代码建立网站wordpress怎么删除
  • 温州做网站掌熊号主机屋wordpress建站
  • 建域名做网站淘宝网站设计公司
  • 网站的域名和密码wordpress 7天热门
  • 博客内容跟网站相关吗做网站一般用什么几号字
  • 网站制作公司去哪找辽阳专业建设网站公司
  • 电脑建设银行怎样设置网站查询杭州网站设计询问蓝韵网络
  • 小公司网站建设岳池做网站电话
  • 自己做网站挂广告怎么赚钱吗网站规划设计的一般流程
  • 罗湖区做网站的公司温州市网站制作
  • 宁德做网站公司上海资格证报名网站
  • 深圳网页制作推广公司排名seo知识点
  • 网站做优化多少钱十大网络推广公司
  • 网站建设上线浙江建设三类人员证书查询
  • 佛山市建设小学网站wordpress文档模板下载