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

做公益筹集项目的网站北京朝阳双桥网站建设

做公益筹集项目的网站,北京朝阳双桥网站建设,ftp链接网站空间,吴中网页设计报价博主看到新服务是封装的自定义异常#xff0c;准备入手剖析一下#xff0c;自定义的异常是如何进行抓住我们请求的方法的异常#xff0c;并进行封装返回到。废话不多说#xff0c;先看看如何才能实现封装异常#xff0c;先来一个示例#xff1a; 1 ControllerAdvice2 pub…博主看到新服务是封装的自定义异常准备入手剖析一下自定义的异常是如何进行抓住我们请求的方法的异常并进行封装返回到。废话不多说先看看如何才能实现封装异常先来一个示例 1 ControllerAdvice2 public class TstExceptionHandle{3 4 ExceptionHandler(Exception.class)5 public void myExceptionHandle(HttpServletResponse response){6 response.setStatus(403);7 System.out.println(做封装处理);8 }9 10 } 博主只做了简单的配置示例主要的是进行源码剖析Springboot是如何获取自定义异常并进行返回的。来吧 第一步肯定是在Springboot启动的过程中进行的异常处理初始化于是就找到了handlerExceptionResolver类在创建该类的时候会进行添加我们自定义异常。 1 public HandlerExceptionResolver handlerExceptionResolver(2 Qualifier(mvcContentNegotiationManager) ContentNegotiationManager contentNegotiationManager) {3 ListHandlerExceptionResolver exceptionResolvers new ArrayList();4 //不用管这个方法这个方法主要进行的是调用实现了WebMvcConfigurer接口bean的configureHandlerExceptionResolvers方法系统的都是空方法5 configureHandlerExceptionResolvers(exceptionResolvers);6 if (exceptionResolvers.isEmpty()) {7 //我们的在这里才添加我们看看这个方法8 addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);9 } 10 extendHandlerExceptionResolvers(exceptionResolvers); 11 HandlerExceptionResolverComposite composite new HandlerExceptionResolverComposite(); 12 composite.setOrder(0); 13 composite.setExceptionResolvers(exceptionResolvers); 14 return composite; 15 } 1 protected final void addDefaultHandlerExceptionResolvers(ListHandlerExceptionResolver exceptionResolvers,2 ContentNegotiationManager mvcContentNegotiationManager) {3 4 ExceptionHandlerExceptionResolver exceptionHandlerResolver createExceptionHandlerExceptionResolver();5 exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager);6 exceptionHandlerResolver.setMessageConverters(getMessageConverters());7 exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers());8 exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers());9 if (jackson2Present) { 10 exceptionHandlerResolver.setResponseBodyAdvice( 11 Collections.singletonList(new JsonViewResponseBodyAdvice())); 12 } 13 if (this.applicationContext ! null) { 14 exceptionHandlerResolver.setApplicationContext(this.applicationContext); 15 } 16 //上面的 都是设置的属性跟我们没啥大关系主要在这里进行的添加自定义异常处理 17 exceptionHandlerResolver.afterPropertiesSet(); 18 exceptionResolvers.add(exceptionHandlerResolver); 19 20 ResponseStatusExceptionResolver responseStatusResolver new ResponseStatusExceptionResolver(); 21 responseStatusResolver.setMessageSource(this.applicationContext); 22 exceptionResolvers.add(responseStatusResolver); 23 24 exceptionResolvers.add(new DefaultHandlerExceptionResolver()); 25 } 最主要的初始化过程在这里从这些代码中就可以看到为什么我们自定义异常需要进行使用ControllerAdvice并且方法使用ExceptionHandler(Exception.class)注解了 1 Override2 public void afterPropertiesSet() {3 // Do this first, it may add ResponseBodyAdvice beans4 //走这里初始化添加5 initExceptionHandlerAdviceCache();6 7 if (this.argumentResolvers null) {8 ListHandlerMethodArgumentResolver resolvers getDefaultArgumentResolvers();9 this.argumentResolvers new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); 10 } 11 if (this.returnValueHandlers null) { 12 ListHandlerMethodReturnValueHandler handlers getDefaultReturnValueHandlers(); 13 this.returnValueHandlers new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers); 14 } 15 } 16 17 18 org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java 19 private void initExceptionHandlerAdviceCache() { 20 if (getApplicationContext() null) { 21 return; 22 } 23 //看到这里基本就知道啥意思了找出带有ControllerAdvice的注解bean 24 ListControllerAdviceBean adviceBeans ControllerAdviceBean.findAnnotatedBeans(getApplicationContext()); 25 for (ControllerAdviceBean adviceBean : adviceBeans) { 26 Class? beanType adviceBean.getBeanType(); 27 if (beanType null) { 28 throw new IllegalStateException(Unresolvable type for ControllerAdviceBean: adviceBean); 29 } 30 //找出当前bean的异常处理方法 31 ExceptionHandlerMethodResolver resolver new ExceptionHandlerMethodResolver(beanType); 32 if (resolver.hasExceptionMappings()) { 33 this.exceptionHandlerAdviceCache.put(adviceBean, resolver); 34 } 35 if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) { 36 this.responseBodyAdvice.add(adviceBean); 37 } 38 } 39 40 if (logger.isDebugEnabled()) { 41 int handlerSize this.exceptionHandlerAdviceCache.size(); 42 int adviceSize this.responseBodyAdvice.size(); 43 if (handlerSize 0 adviceSize 0) { 44 logger.debug(ControllerAdvice beans: none); 45 } 46 else { 47 logger.debug(ControllerAdvice beans: 48 handlerSize ExceptionHandler, adviceSize ResponseBodyAdvice); 49 } 50 } 51 } 找到类后是如何找到方法的呢主要看如何创建ExceptionHandlerMethodResolver的过程。 1 public ExceptionHandlerMethodResolver(Class? handlerType) {2 //EXCEPTION_HANDLER_METHODS的定义3 //public static final MethodFilter EXCEPTION_HANDLER_METHODS method -4 // AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);5 //所以他会寻找带有ExceptionHandler注解的方法6 for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {7 //寻找方法注解上配置的捕获的异常类并添加如果有两个方法都对一个异常进行自定义处理了怎么办呢。8 for (Class? extends Throwable exceptionType : detectExceptionMappings(method)) {9 //他会出异常的。不过前提是同一个类里不同类对同一个异常进行自定义的话谁在前面就有谁来处理 10 addExceptionMapping(exceptionType, method); 11 } 12 } 13 } 添加自定义异常的时候抛异常是在这里 1 private void addExceptionMapping(Class? extends Throwable exceptionType, Method method) { 2 Method oldMethod this.mappedMethods.put(exceptionType, method); 3 //在这里已经显示出来了博主就不试了 4 if (oldMethod ! null !oldMethod.equals(method)) { 5 throw new IllegalStateException(Ambiguous ExceptionHandler method mapped for [ 6 exceptionType ]: { oldMethod , method }); 7 } 8 } 好了。所有异常添加完毕了我们来测试一下异常来的时候Springboot是如何选择自定义异常并返回的我们上面所有的操作都是在创建HandlerExceptionResolver时进行的为什么要添加到HandlerExceptionResolver这里呢看一下代码 1 //第一次请求进来时会先查找是否有自定义异常如果有的话添加没有记录日志就完了2 private void initHandlerExceptionResolvers(ApplicationContext context) {3 this.handlerExceptionResolvers null;4 5 if (this.detectAllHandlerExceptionResolvers) {6 // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.7 //这里会在beanfactroy中查找到HandlerExceptionResolver类刚才初始化的时候我们所有的自定义异常都在里面 8 MapString, HandlerExceptionResolver matchingBeans BeanFactoryUtils9 .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); 10 if (!matchingBeans.isEmpty()) { 11 this.handlerExceptionResolvers new ArrayList(matchingBeans.values()); 12 // We keep HandlerExceptionResolvers in sorted order. 13 AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers); 14 } 15 } 16 else { 17 try { 18 HandlerExceptionResolver her 19 context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class); 20 this.handlerExceptionResolvers Collections.singletonList(her); 21 } 22 catch (NoSuchBeanDefinitionException ex) { 23 // Ignore, no HandlerExceptionResolver is fine too. 24 } 25 } 26 27 // Ensure we have at least some HandlerExceptionResolvers, by registering 28 // default HandlerExceptionResolvers if no other resolvers are found. 29 if (this.handlerExceptionResolvers null) { 30 this.handlerExceptionResolvers getDefaultStrategies(context, HandlerExceptionResolver.class); 31 if (logger.isTraceEnabled()) { 32 logger.trace(No HandlerExceptionResolvers declared in servlet getServletName() 33 : using default strategies from DispatcherServlet.properties); 34 } 35 } 36 } 走完初始化经过过滤器拦截器终于到了我们的请求方法我们的方法还报错了所以会走到异常中我们DispatcherServlet会进行抓住异常然后回调用我们的processDispatchResult方法大家可以自己看一下org/springframework/web/servlet/DispatcherServlet.java的源码然后我们来分析一下这个方法都干啥了吧 1 private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,2 Nullable HandlerExecutionChain mappedHandler, Nullable ModelAndView mv,3 Nullable Exception exception) throws Exception {4 5 boolean errorView false;6 7 if (exception ! null) {8 if (exception instanceof ModelAndViewDefiningException) {9 logger.debug(ModelAndViewDefiningException encountered, exception); 10 mv ((ModelAndViewDefiningException) exception).getModelAndView(); 11 } 12 else { 13 Object handler (mappedHandler ! null ? mappedHandler.getHandler() : null); 14 //如果请求方法有异常则进行处理并返回ModelAndView 15 mv processHandlerException(request, response, handler, exception); 16 errorView (mv ! null); 17 } 18 } 19 ......... 20 } 那Springboot是如何选择哪一个是符合条件的自定义异常处理呢如果我们定义了两个处理类都对同一个异常进行捕获并返回不一样的信息咋办呢看源码吧 1 //这里会选择符合条件的自定义异常2 protected ServletInvocableHandlerMethod getExceptionHandlerMethod(3 Nullable HandlerMethod handlerMethod, Exception exception) {4 5 Class? handlerType null;6 7 if (handlerMethod ! null) {8 // Local exception handler methods on the controller class itself.9 // To be invoked through the proxy, even in case of an interface-based proxy. 10 handlerType handlerMethod.getBeanType(); 11 ExceptionHandlerMethodResolver resolver this.exceptionHandlerCache.get(handlerType); 12 if (resolver null) { 13 resolver new ExceptionHandlerMethodResolver(handlerType); 14 this.exceptionHandlerCache.put(handlerType, resolver); 15 } 16 Method method resolver.resolveMethod(exception); 17 if (method ! null) { 18 return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method); 19 } 20 // For advice applicability check below (involving base packages, assignable types 21 // and annotation presence), use target class instead of interface-based proxy. 22 if (Proxy.isProxyClass(handlerType)) { 23 handlerType AopUtils.getTargetClass(handlerMethod.getBean()); 24 } 25 } 26 //exceptionHandlerAdviceCache这个map是我们添加 的自定义异常 27 for (Map.EntryControllerAdviceBean, ExceptionHandlerMethodResolver entry : this.exceptionHandlerAdviceCache.entrySet()) { 28 ControllerAdviceBean advice entry.getKey(); 29 //这个判断条件是查看是否有符合条件的自定义异常如果有两个的话 30 if (advice.isApplicableToBeanType(handlerType)) { 31 ExceptionHandlerMethodResolver resolver entry.getValue(); 32 Method method resolver.resolveMethod(exception); 33 if (method ! null) { 34 return new ServletInvocableHandlerMethod(advice.resolveBean(), method); 35 } 36 } 37 } 38 39 return null; 40 } 逻辑基本是上面的但是真正处理是否符合是在这里的一个方法中 1 public boolean isApplicableToBeanType(Nullable Class? beanType) {2 return this.beanTypePredicate.test(beanType);3 }4 public boolean test(Class? controllerType) {5 ///默认不配的其他属性的时候是返回true的就是对所有包下的异常都适用6 if (!hasSelectors()) {7 return true;8 }9 else if (controllerType ! null) { 10 //我们的ControllerAdvice注解是有basePackages属性的只有匹配成功才会返回否则就算自定义异常想要捕获不在捕获包范围下不管该异常 11 for (String basePackage : this.basePackages) { 12 if (controllerType.getName().startsWith(basePackage)) { 13 return true; 14 } 15 } 16 for (Class? clazz : this.assignableTypes) { 17 if (ClassUtils.isAssignable(clazz, controllerType)) { 18 return true; 19 } 20 } 21 for (Class? extends Annotation annotationClass : this.annotations) { 22 if (AnnotationUtils.findAnnotation(controllerType, annotationClass) ! null) { 23 return true; 24 } 25 } 26 } 27 return false; 28 } 到这里基本如何写自定义异常、以及为什么这么写、底层做了哪些判断都已经讲解完了自定义异常在工作中还是非常常用的一种手段因为我们不可能暴露出我们内部的错误信息直接返回给用户不仅用户体验不好并且安全性也极其差。
http://www.pierceye.com/news/704519/

相关文章:

  • 做论坛网站赚钱吗做电影网站要几G空间的
  • 网站建设综合实训心得intitle 网站建设
  • 天津市做网站公司wordpress demo
  • 做外贸网站公司公司网站的seo优化
  • 网站页面设置上海微信小程序开发公司
  • 中企动力是怎么建设网站的房地产市场低迷
  • 成都眉山网站建设平台兼职网站开发
  • 化妆品网站的建设 论文php技术的网站开发
  • 女人与黑狗做视频网站网站seo关键词排名
  • ps制作个人网站营销软文怎么写
  • 建立网站的方案南京小程序开发网站建设
  • 类似淘宝的网站怎么做的产品推广会议流程
  • 写作网站的文风软件开发的基本过程
  • 做胃镜多少钱那好天津津门网站a顺德高端网站
  • 网站升级维护中 模板用ps怎么做网站背景
  • 免费商城网站建设建设银行企业网站首页
  • 北京哪家网站建设公司比较好帝国cms怎么做网站地图
  • 做网站制作外包数据可视化
  • 专注大连网站建设青海项目信息网
  • 网站开发开题报告范文可以做免费的网站吗
  • 淄博网站备案wordpress代码实现下载
  • 网站做全景做的好看的网站
  • 宜春专业的企业网站建设公司网站建设待遇怎样
  • 苏州企业网站建设制作服务在线培训平台
  • 成都创建公司网站wordpress的多说美化
  • 企业网站建设的方案书用织梦做模板网站
  • 馆陶做网站容桂低价网站建设
  • 帮一个企业做网站流程免费做app的软件有哪些
  • 河间哪里有做网站的wordpress禁用修正版
  • 网站建设对网络营销的影响做网站的怎么挣钱