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

销售网站内容设计/关键词优化排名怎么做

销售网站内容设计,关键词优化排名怎么做,阿里巴巴国际站特点,wordpress手机版怎么用在Spring里,我们可以使用ControllerAdvice来声明一些全局性的东西,最常见的是结合ExceptionHandler注解用于全局异常的处理。ControllerAdvice是在类上声明的注解,其用法主要有三点:ExceptionHandler注解标注的方法:用…

在Spring里,我们可以使用@ControllerAdvice来声明一些全局性的东西,最常见的是结合@ExceptionHandler注解用于全局异常的处理。

@ControllerAdvice是在类上声明的注解,其用法主要有三点:@ExceptionHandler注解标注的方法:用于捕获Controller中抛出的不同类型的异常,从而达到异常全局处理的目的;

@InitBinder注解标注的方法:用于请求中注册自定义参数的解析,从而达到自定义请求参数格式的目的;

@ModelAttribute注解标注的方法:表示此方法会在执行目标Controller方法之前执行 。

看下具体用法:

// 这里@RestControllerAdvice等同于@ControllerAdvice + @ResponseBody@RestControllerAdvice

public class GlobalHandler {

private final Logger logger = LoggerFactory.getLogger(GlobalHandler.class);

// 这里@ModelAttribute("loginUserInfo")标注的modelAttribute()方法表示会在Controller方法之前 // 执行,返回当前登录用户的UserDetails对象 @ModelAttribute("loginUserInfo")

public UserDetails modelAttribute() {

return (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

}

// @InitBinder标注的initBinder()方法表示注册一个Date类型的类型转换器,用于将类似这样的2019-06-10 // 日期格式的字符串转换成Date对象 @InitBinder

protected void initBinder(WebDataBinder binder) {

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

dateFormat.setLenient(false);

binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));

}

// 这里表示Controller抛出的MethodArgumentNotValidException异常由这个方法处理 @ExceptionHandler(MethodArgumentNotValidException.class)

public Result exceptionHandler(MethodArgumentNotValidException e) {

Result result = new Result(BizExceptionEnum.INVALID_REQ_PARAM.getErrorCode(),

BizExceptionEnum.INVALID_REQ_PARAM.getErrorMsg());

logger.error("req params error", e);

return result;

}

// 这里表示Controller抛出的BizException异常由这个方法处理 @ExceptionHandler(BizException.class)

public Result exceptionHandler(BizException e) {

BizExceptionEnum exceptionEnum = e.getBizExceptionEnum();

Result result = new Result(exceptionEnum.getErrorCode(), exceptionEnum.getErrorMsg());

logger.error("business error", e);

return result;

}

// 这里就是通用的异常处理器了,所有预料之外的Exception异常都由这里处理 @ExceptionHandler(Exception.class)

public Result exceptionHandler(Exception e) {

Result result = new Result(1000, "网络繁忙,请稍后再试");

logger.error("application error", e);

return result;

}

}

在Controller里取出@ModelAttribute标注的方法返回的UserDetails对象:

RestController

@RequestMapping("/json/exam")

@Validated

public class ExamController {

@Autowired

private IExamService examService;

// ...... @PostMapping("/getExamListByOpInfo")

public Result> getExamListByOpInfo( @NotNull Date examOpDate,

@ModelAttribute("loginUserInfo") UserDetails userDetails) {

List resVos = examService.getExamListByOpInfo(examOpDate, userDetails);

Result> result = new Result(resVos);

return result;

}

}

这里当入参为examOpDate=2019-06-10时,Spring会使用我们上面@InitBinder注册的类型转换器将2019-06-10转换examOpDate对象:

@PostMapping("/getExamListByOpInfo")

public Result> getExamListByOpInfo(@NotNull Date examOpDate,

@ModelAttribute("loginUserInfo") UserDetails userDetails) {

List resVos = examService.getExamListByOpInfo(examOpDate, userDetails);

Result> result = new Result(resVos);

return result;

}

@ExceptionHandler标注的多个方法分别表示只处理特定的异常。这里需要注意的是当Controller抛出的某个异常多个@ExceptionHandler标注的方法都适用时,Spring会选择最具体的异常处理方法来处理,也就是说@ExceptionHandler(Exception.class)这里标注的方法优先级最低,只有当其它方法都不适用时,才会来到这里处理。

下面我们看看Spring是怎么实现的,首先前端控制器DispatcherServlet对象在创建时会初始化一系列的对象:

public class DispatcherServlet extends FrameworkServlet {

// ......protected void initStrategies(ApplicationContext context) {

initMultipartResolver(context);

initLocaleResolver(context);

initThemeResolver(context);

initHandlerMappings(context);

initHandlerAdapters(context);

initHandlerExceptionResolvers(context);

initRequestToViewNameTranslator(context);

initViewResolvers(context);

initFlashMapManager(context);

}

// ......}

对于@ControllerAdvice 注解,我们重点关注initHandlerAdapters(context)和initHandlerExceptionResolvers(context)这两个方法。

initHandlerAdapters(context)方法会取得所有实现了HandlerAdapter接口的bean并保存起来,其中就有一个类型为RequestMappingHandlerAdapter的bean,这个bean就是@RequestMapping注解能起作用的关键,这个bean在应用启动过程中会获取所有被@ControllerAdvice注解标注的bean对象做进一步处理,关键代码在这里:

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter

implements BeanFactoryAware, InitializingBean {

// ...... private void initControllerAdviceCache() {

// ......List adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

AnnotationAwareOrderComparator.sort(adviceBeans);

List requestResponseBodyAdviceBeans = new ArrayList<>();

for (ControllerAdviceBean adviceBean : adviceBeans) {

Class> beanType = adviceBean.getBeanType();

if (beanType == null) {

throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);

}

// 找到所有ModelAttribute标注的方法并缓存起来Set attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);

if (!attrMethods.isEmpty()) {

this.modelAttributeAdviceCache.put(adviceBean, attrMethods);

if (logger.isInfoEnabled()) {

logger.info("Detected @ModelAttribute methods in " + adviceBean);

}

}

// 找到所有InitBinder标注的方法并缓存起来Set binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);

if (!binderMethods.isEmpty()) {

this.initBinderAdviceCache.put(adviceBean, binderMethods);

if (logger.isInfoEnabled()) {

logger.info("Detected @InitBinder methods in " + adviceBean);

}

}

// ......}

}

// ......}

经过这里处理之后,@ModelAttribute和@InitBinder就能起作用了,至于DispatcherServlet和RequestMappingHandlerAdapter是如何交互的这就是另一个复杂的话题了,此处不赘述。

再来看DispatcherServlet的initHandlerExceptionResolvers(context)方法,方法会取得所有实现了HandlerExceptionResolver接口的bean并保存起来,其中就有一个类型为ExceptionHandlerExceptionResolver的bean,这个bean在应用启动过程中会获取所有被@ControllerAdvice注解标注的bean对象做进一步处理,关键代码在这里:

public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver

implements ApplicationContextAware, InitializingBean {

// ......private void initExceptionHandlerAdviceCache() {

// ......List adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

AnnotationAwareOrderComparator.sort(adviceBeans);

for (ControllerAdviceBean adviceBean : adviceBeans) {

ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(adviceBean.getBeanType());

if (resolver.hasExceptionMappings()) {

// 找到所有ExceptionHandler标注的方法并保存成一个ExceptionHandlerMethodResolver类型的对象缓存起来this.exceptionHandlerAdviceCache.put(adviceBean, resolver);

if (logger.isInfoEnabled()) {

logger.info("Detected @ExceptionHandler methods in " + adviceBean);

}

}

// ......}

}

// ......}

当Controller抛出异常时,DispatcherServlet通过ExceptionHandlerExceptionResolver来解析异常,而ExceptionHandlerExceptionResolver又通过ExceptionHandlerMethodResolver 来解析异常, ExceptionHandlerMethodResolver 最终解析异常找到适用的@ExceptionHandler标注的方法是这里:

public class ExceptionHandlerMethodResolver {

// ......private Method getMappedMethod(Class extends Throwable> exceptionType) {

List> matches = new ArrayList>();

// 找到所有适用于Controller抛出异常的处理方法,例如Controller抛出的异常// 是BizException(继承自RuntimeException),那么@ExceptionHandler(BizException.class)和// @ExceptionHandler(Exception.class)标注的方法都适用此异常for (Class extends Throwable> mappedException : this.mappedMethods.keySet()) {

if (mappedException.isAssignableFrom(exceptionType)) {

matches.add(mappedException);

}

}

if (!matches.isEmpty()) {

// 这里通过排序找到最适用的方法,排序的规则依据抛出异常相对于声明异常的深度,例如// Controller抛出的异常是BizException(继承自RuntimeException),那么BizException// 相对于@ExceptionHandler(BizException.class)声明的BizException.class其深度是0,// 相对于@ExceptionHandler(Exception.class)声明的Exception.class其深度是2,所以// @ExceptionHandler(BizException.class)标注的方法会排在前面Collections.sort(matches, new ExceptionDepthComparator(exceptionType));

return this.mappedMethods.get(matches.get(0));

}

else {

return null;

}

}

// ......}

整个@ControllerAdvice处理的流程就是这样,这个设计还是非常灵活的。

源码github地址,各位同学可以试着去运行下项目熟悉这个流程:jufeng98/java-master​github.com

http://www.jmfq.cn/news/5231089.html

相关文章:

  • 西安微网站开发/百度在线识别图片
  • 设计网站登录框ps怎么做/湖南百度推广
  • 网站怎么做视频背景/搜索引擎营销的方法包括
  • 金坛市住房和城乡建设局网站/竞价托管怎么做
  • 做哪种网站能赚到钱/软文营销实施背景
  • 网站打不开 别的电脑能打开/新闻软文怎么写
  • 百度网站推广优化工具/东莞整站优化排名
  • 用建站ABC做的网站 怎么营销/私人做网站建设
  • 定制化开发/aso优化什么意思
  • 电子商务网站开发环境/广州seo运营
  • 法拍房北京网站/关键词挖掘ppt
  • 手机可做兼职的网站/青岛网站seo
  • 网站建设服务描述/一键优化是什么意思
  • 网站建设分为多少模块/微信信息流广告投放
  • 临沂网站建设兼职/百度com打开
  • 济南学习网站制作/宁波核心关键词seo收费
  • 网站开发技术主管工作职责/我想做地推怎么找渠道
  • 自己做物流网站/长沙网站托管优化
  • 公司简历模板范文填写/seo关键词排名优化软件
  • 北京网站优化和推广/成都搜索优化排名公司
  • 做爰全过程免费网站的视频教程/品牌策划案
  • 重庆城市建设集团官方网站/引流软件有哪些
  • 不属于常用网站建设的是/老铁外链
  • 深圳宝安网站建设/网络营销是做什么
  • 深圳市住房和建设局工程交易网/seo推广的方法
  • 提高审美的网站推荐/长沙百度网站推广
  • 网上创建公司/上海网站seo外包
  • 网站建设顶呱呱/电工培训机构
  • 卖狗人怎么做网站/seo网址超级外链工具
  • 移动门户网站建设特点/北京网站制作