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

黑龙江住房和城乡建设厅网站首页小清新网站源码

黑龙江住房和城乡建设厅网站首页,小清新网站源码,织梦网站上传,wordpress手机字体变大6前情概要 这个问题其实困扰了我一周时间,一周都在 Google 上旅游,我要如何动态的设置 RestControllerAdvice 里面的 basePackages 以及 baseClasses 的值呢?经过一周的时间寻求无果之后打算决定放弃的我终于找到了一些关键的线索。 当然在此…

前情概要

这个问题其实困扰了我一周时间,一周都在 Google 上旅游,我要如何动态的设置 @RestControllerAdvice 里面的 basePackages 以及 baseClasses 的值呢?经过一周的时间寻求无果之后打算决定放弃的我终于找到了一些关键的线索。
当然在此也感激这篇文章:@ControllerAdvice的用法和原理探究
其实我们只要有调试源码的习惯,也能够发现这些东西,可能有时候就是差那么一点动力吧,比如我,就想直接看现成的解析,没有那么主动去调试源码,哈哈哈。

发现了关键问题之后

其实从上面这篇文章里我提取到的关键信息如下:

@Bean
public HandlerExceptionResolver handlerExceptionResolver(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();configureHandlerExceptionResolvers(exceptionResolvers);if (exceptionResolvers.isEmpty()) {addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);}extendHandlerExceptionResolvers(exceptionResolvers);HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();composite.setOrder(0);composite.setExceptionResolvers(exceptionResolvers);return composite;
}

PS:😓 后来我才发现这里面的 configureHandlerExceptionResolversaddDefaultHandlerExceptionResolvers extendHandlerExceptionResolvers 这三个方法是源码里面的,我还一直在找这个博主有关这两个方法的实现。

OK 回来,这里面的关键就是我需要往 Spring IOC 里面添加一个 HandlerExceptionResolverComposite ,并且设置它的处理器列表就好了。
于是我就顺着这个思路开始捣鼓,OK,下面是第一个版本的代码:

版本一

Starter 配置类(关键代码)

@Bean
public HandlerExceptionResolver handlerExceptionResolver() {final HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();final List<HandlerExceptionResolver> resolves =Collections.singletonList(new RestGlobalExceptionHandler(starterProperties));composite.setOrder(0);composite.setExceptionResolvers(resolves);return composite;
}

Handler 处理器类(关键代码)

public final class RestGlobalExceptionHandler extends DefaultHandlerExceptionResolver implementsHandlerExceptionResolver {@Overridepublic ModelAndView resolveException(final HttpServletRequest request,final HttpServletResponse response,final Object handler,final Exception ex) {ModelAndView view = new ModelAndView();if (ex instanceof BusinessException) {printToResponse(response, handlerError(request, (BusinessException) ex));} else if (ex instanceof MethodArgumentNotValidException) {printToResponse(response, handlerError(request, (MethodArgumentNotValidException) ex));} else {// use default exception handlerview = super.doResolveException(request, response, handler, ex);}if (Objects.isNull(view)) {// use finally exception handlerview = new ModelAndView();printToResponse(response, handlerError(request, ex));}return view;}// handlerError 以及 printToResponse 方法省略
}

这里说下为什么就要继承 DefaultHandlerExceptionResolver以及实现HandlerExceptionResolver接口:
实现接口:因为 HandlerExceptionResolverComposite类的 resolves 列表就是一个List<HandlerExceptionResolver>, 所以我们自定义的 Handler 需要实现这个接口。
继承 DefaultHandlerExceptionResolver类:因为可以看到我重写了 resolveException这个方法

但是这还存在问题:

// 这个是 DefaultHandlerExceptionResolver 的 doResolveException 方法,你们实践第一版的时候会发现,有一些异常信息被这方法处理了,但是我发现如果使用 @RestControllerAdvice 结合 @ExceptionHandler 的话,优先是考虑我们自定义的异常处理的,于是有了下面的版本二。
@Nullableprotected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {try {if (ex instanceof HttpRequestMethodNotSupportedException) {return this.handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException)ex, request, response, handler);}if (ex instanceof HttpMediaTypeNotSupportedException) {return this.handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException)ex, request, response, handler);}if (ex instanceof HttpMediaTypeNotAcceptableException) {return this.handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException)ex, request, response, handler);}if (ex instanceof MissingPathVariableException) {return this.handleMissingPathVariable((MissingPathVariableException)ex, request, response, handler);}if (ex instanceof MissingServletRequestParameterException) {return this.handleMissingServletRequestParameter((MissingServletRequestParameterException)ex, request, response, handler);}if (ex instanceof ServletRequestBindingException) {return this.handleServletRequestBindingException((ServletRequestBindingException)ex, request, response, handler);}if (ex instanceof ConversionNotSupportedException) {return this.handleConversionNotSupported((ConversionNotSupportedException)ex, request, response, handler);}if (ex instanceof TypeMismatchException) {return this.handleTypeMismatch((TypeMismatchException)ex, request, response, handler);}if (ex instanceof HttpMessageNotReadableException) {return this.handleHttpMessageNotReadable((HttpMessageNotReadableException)ex, request, response, handler);}if (ex instanceof HttpMessageNotWritableException) {return this.handleHttpMessageNotWritable((HttpMessageNotWritableException)ex, request, response, handler);}if (ex instanceof MethodArgumentNotValidException) {return this.handleMethodArgumentNotValidException((MethodArgumentNotValidException)ex, request, response, handler);}if (ex instanceof MissingServletRequestPartException) {return this.handleMissingServletRequestPartException((MissingServletRequestPartException)ex, request, response, handler);}if (ex instanceof BindException) {return this.handleBindException((BindException)ex, request, response, handler);}if (ex instanceof NoHandlerFoundException) {return this.handleNoHandlerFoundException((NoHandlerFoundException)ex, request, response, handler);}if (ex instanceof AsyncRequestTimeoutException) {return this.handleAsyncRequestTimeoutException((AsyncRequestTimeoutException)ex, request, response, handler);}} catch (Exception var6) {Exception handlerEx = var6;if (this.logger.isWarnEnabled()) {this.logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);}}return null;}

版本二

这里主要解决的是,有一些自定义的异常处理提前被 DefaultHandlerExceptionResolver 类的 doResolveException 的方法处理了,了解 Spring IOC 容器的小伙伴应该都知道,这很容易让我们联想起,Bean 的顺序问题,那么我们哪里设置了我们自定义 Bean 的顺序呢,也就是使用 @Order 或者代码里面设置了,没错,就是这里:

@Bean
public HandlerExceptionResolver handlerExceptionResolver() {final HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();final List<HandlerExceptionResolver> resolves =Collections.singletonList(new RestGlobalExceptionHandler(starterProperties));// 这里,这里,这里composite.setOrder(0);composite.setExceptionResolvers(resolves);return composite;
}

但是我们要怎么知道我们具体要设置的值是什么呢?大家都知道在使用 Spring 的时候设置 Bean 的 Order 值越小那么它的优先级越高,所以我尝试着把 0 换成 -1,试试,结果还真成功了,我们自定义的优先执行了,但是作为一个搞技术的人,还是想摸清楚它的原理吧,为啥设置成 -1 就可以了呢?
一开始没有啥头绪,不知道怎么去查找 Spring 配置异常处理这块( 主要还是源码不熟 -_-! ),但后面想一想,把目标换一下不就好了,是因为 DefaultHandlerExceptionResolver 这个 Bean 的原因,那我就找 Spring 是哪里把他放进 Spring IOC 容器的不就好了。因为我使用的框架是 SpringBoot,所以相关的配置肯定在 XXXAutoConfiguration 类里面,于是就找找找…

  • WebMvcAutoConfiguration 没有…
  • DispatcherServletAutoConfiguration 没有…

好吧最后还是借助 IntelliJ 这个工具,因为我们自定义的是一个 HandlerExceptionResolverComposite Bean,所以我们进入这个类:
在这里插入图片描述
发现它实现了 HandlerExceptionResolver 这个接口,一般 Spring 都会使用接口作为一个接收实现的变量,然后 return 回去交给 Spring IOC 容器,所以我们再进入这个接口:
在这里插入图片描述
利用 IntelliJ 的工具,找到哪里注入了这个 Bean:
在这里插入图片描述
在这里插入图片描述
进去之后发现了跟我们类似的代码:
在这里插入图片描述
看到 618 行的 this.addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager); 吗?这个就是添加 DefaultHandlerExceptionResolver 的地方,并且设置的 Order 是 0,如果 Debug 的话你会发现这个方法除了加入 DefaultHandlerExceptionResolver 之外,还会加入自定义使用注解的异常处理器,但是它在 List 中的顺序比 DefaultHandlerExceptionResolver 靠前,所以它会优先使用自定义的处理器处理,但是使用注解是 Spring 自己处理的,然后加入这个 List 中,我们没办法去修改这个 List,但是我们知道了可以自定义 HandlerExceptionResolverComposite 并且把它的 Order 设置成比 0 小就好了,所以这就是为什么我们设置成 -1 就可以覆盖 DefaultHandlerExceptionResolver 的行为的原因。

所有的代码已经放在我的代码仓库:码云,欢迎来访以及给我小⭐⭐


文章转载自:

http://iOZUeHKo.smqjL.cn
http://TFzVvQx6.smqjL.cn
http://Si0KUCqK.smqjL.cn
http://wOdVsnCR.smqjL.cn
http://qeLTdN2R.smqjL.cn
http://13AtBvYp.smqjL.cn
http://tAThYjai.smqjL.cn
http://hR2aW7W4.smqjL.cn
http://xNk0eXUS.smqjL.cn
http://HHUuDaBw.smqjL.cn
http://7eQzGkIK.smqjL.cn
http://38xVpeYX.smqjL.cn
http://XC1VDwsh.smqjL.cn
http://Tq8ysspc.smqjL.cn
http://DAghrtrG.smqjL.cn
http://lGvOcrOp.smqjL.cn
http://5SZcloYk.smqjL.cn
http://7iqRSABV.smqjL.cn
http://GakYece7.smqjL.cn
http://nDNlt1n5.smqjL.cn
http://4rW5jWrf.smqjL.cn
http://i8paTWGO.smqjL.cn
http://FxqbZWnQ.smqjL.cn
http://2qLeboJi.smqjL.cn
http://P9B7uukL.smqjL.cn
http://eRiGi9Jb.smqjL.cn
http://9MvSeNFH.smqjL.cn
http://K1Y8smvQ.smqjL.cn
http://X8mmToxR.smqjL.cn
http://ZTGXVCWW.smqjL.cn
http://www.dtcms.com/wzjs/739648.html

相关文章:

  • 玉田建设局网站吉安工商注册官方网站
  • 西安网站建设排名免费ppt资源网站
  • 西宁市城北区建设网站官网cms
  • 网络管理系统登录白城网站seo
  • 公司网站界面如何设计移动网站建设模板
  • 自己做网站能否赚钱6建设官方网站企业登录
  • python培训机构岳阳seo公司
  • 四川省建设注册资格中心网站wordpress模板最新
  • 做好史志网站建设如何制作橡皮泥 简单
  • 青岛平台网站建设嵌入式开发难学吗
  • 设计门户网站wordpress 树
  • 大鹏新区网站建设二手交易网站怎么做
  • 手机官方网站工地建筑劳务公司招工平台
  • 网站商城建设员招聘信息网络广告公司排名
  • dede企业网站创立一个网站要多少钱
  • 网络哪里能接活做网站莆田有哪几家做网站设计
  • 单位网站建设管理工作总结wordpress导航栏制作教程
  • html移动网站开发摄影设计思路
  • 手机网站尺寸大小网站建设就业前景2017
  • 买域名后 怎么做网站电商拿货平台
  • 做网站预付款 怎么做账哪里做网站需求
  • 《php网站开发》课程资料胖小七网站建设
  • 建立个人网站的步骤有哪些seo自己做网站吗
  • 工信部备案网站苏州网站设计多少钱
  • 天津建设网站需要的费用郑州 发布会
  • mvc做的游戏网站代码wordpress多重查询
  • 网站建设计划书范本php网站的开发背景
  • 网站流量与带宽数码产品网站建设计划书
  • 网站建设的推进方案宁波网站制作怎样
  • 牛商网营销型网站多少钱网站开发盈亏平衡分析表