• spring boot 整合web开发(二)


    目录

     


    • 自定义错误页
    • CORS支持(前端跨域请求)
    • 拦截器HandlerInterceptor
    • 启动系统任务
    • springboot配置AOP
    • 整合servlet、filter、listener

     下图为本节内容

    1、自定义错误页

    springboot中默认错误是由BasicErrorController类来处理的,该类核心方法有errorHtml(返回Html),error(返回json),DefaultErrorViewResolver是Springboot默认错误解析器。该类源码中可以看出4xx、5xx文件作为错误视图,找不到会回到errorHtml方法中,使用error作为默认的错误页面视图。

    1)、自定义Error数据

    BasicErrorController的errorHtml、error都是通过getErrorAttributes方法获取error信息。该方法会调用DefaultErrorAttributes类的getErrorAttributes方法,而DefaultErrorAttributes类是在ErrorMvcAutoCongfigutration默认提供的。

    @Bean
    @ConditionalOnMissingBean(
    value = {ErrorAttributes.class},
    search = SearchStrategy.CURRENT
    )
    public DefaultErrorAttributes errorAttributes() {
    return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException());
    }

    从这段源码可以看出,当系统没有听过ErrorAttributes时才会采用DefaultErrorAttributes,因此自定义错误时,只需要自己提供一个ErrorAttributes。

    @Component
    public class MyErrorAttribute extends DefaultErrorAttributes {


    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
    Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
    errorAttributes.put("custommsg","出错了");
    errorAttributes.remove("error");
    return errorAttributes;
    }
    }

    2)、自定义error视图

    BasicErrorController的errorHtml方法中调用resolveErrorView方法获取一个ModelAndView实例。resolveErrorView是由ErrorViewResolver提供的。

    @Bean
    @ConditionalOnBean({DispatcherServlet.class})
    @ConditionalOnMissingBean
    public DefaultErrorViewResolver conventionErrorViewResolver() {
    return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties);
    }

     想要自定义自己的视图,只需要提供自己的ErrorViewResolver

    @Component
    public class MyErrorViewResolver implements ErrorViewResolver {
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
    ModelAndView modelAndView = new ModelAndView("errorPage");
    modelAndView.addObject("custommsg","出错了");
    modelAndView.addAllObjects(model);
    return modelAndView;
    }
    }

     3)、自定义视图和自定义数据

    查看Error自动化配置类ErrorMvcAutoConfiguration,BasicErrorController是一个默认的配置。

    @Bean
    @ConditionalOnMissingBean(
    value = {ErrorController.class},
    search = SearchStrategy.CURRENT
    )
    public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
    return new BasicErrorController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers);
    }

    从这段源码可以看到,如果没有提供自己的ErrorController,则springboot提供BasicErrorController作为默认的ErrorController。

    @Controller
    public class MyErrorController extends BasicErrorController {
    public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties,
    List<ErrorViewResolver> errorViewResolvers) {
    super(errorAttributes,serverProperties.getError(),errorViewResolvers);
    }

    @Override
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
    HttpStatus status = getStatus(request);
    Map<String, Object> model =
    getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML));
    model.put("custommsg","出错了");
    ModelAndView modelAndView = new ModelAndView("myErrorPage",model,status);
    return modelAndView;
    }

    @Override
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
    Map<String, Object> errorAttributes = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
    errorAttributes.put("custommsg","出错了");
    HttpStatus status = getStatus(request);
    return new ResponseEntity<>(errorAttributes,status);
    }
    }

     2、CORS支持(前端跨域请求)

    配置跨域可以在方法上加注解、全局配置。

    在方法上加注解

    @PostMapping("/book")
    @CrossOrigin(value = "http://localhost:8081",maxAge = 1800,allowedHeaders = "*")
    public String addBook(String name) {
    return "receive:" + name;
    }

    全局配置

    //跨域全局配置
    @Override
    public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/book/**")
    .allowedHeaders("*")
    .allowedMethods("*")
    .maxAge(1800)
    .allowedOrigins("http://localhost:8081");
    }

     3、拦截器HandlerInterceptor

    配置拦截器,定义配置类进行拦截器的配置

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MyInterceptor())
    .addPathPatterns("/**")
    .excludePathPatterns("/static/**");
    }

     4、启动系统任务

    1)、CommandLineRunner

    /**
    * CommandLineRunner 系统启动时加载参数
    * @author shuliangzhao
    * @Title: MyCommandLineRunner
    * @ProjectName spring-boot-learn
    * @Description: TODO
    * @date 2019/7/21 12:34
    */
    @Component
    @Order(1)
    public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
    System.out.println("Runner>>>" + Arrays.toString(args));
    }
    }

    2)、ApplicationRunner

    /**
    * --name = zhangsan getOptionNames getOptionValues
    * 路遥 平凡的世界 getNonOptionArgs取值
    * @author shuliangzhao
    * @Title: MyApplicationRunner
    * @ProjectName spring-boot-learn
    * @Description: TODO
    * @date 2019/7/21 12:36
    */
    @Component
    public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
    List<String> nonOptionArgs = args.getNonOptionArgs();
    System.out.println("nonOptionArgs>>>" + nonOptionArgs);
    Set<String> optionNames = args.getOptionNames();
    for (String optionName:optionNames) {
    System.out.println("key:" + optionName + ";value:" + args.getOptionValues(optionName));
    }
    }
    }

     5、springboot配置AOP

    Joinpoint:连接点,类里面可以被增强的方法即为连接点,例如想修改哪个方法的功能,那么这个方法即为连接点
    Pointcut:切入点,对于Joinpoint进行拦截的定义即为切入点,例如拦截所有的insert
    Advice:通知,拦截到Joinpoint之后所要做的事就是通知,
    Aspect:切面,Pointcut和Advice的结合
    Target:目标对象,要增强类为target
    @Component
    @Aspect
    public class LogAspect {

    @Pointcut("execution(* com.sl.service.*.*(..))")
    public void pc() {
    }

    @Before(value = "pc()")
    public void before(JoinPoint jp) {
    String name = jp.getSignature().getName();
    System.out.println(name + "方法开始执行...");
    }

    @After(value = "pc()")
    public void after(JoinPoint jp) {
    String name = jp.getSignature().getName();
    System.out.println(name + "方法执行结束...");
    }

    @AfterReturning(value = "pc()",returning = "result")
    public void afterReturning(JoinPoint jp,Object result) {
    String name = jp.getSignature().getName();
    System.out.println(name + "方法返回值为:" + result);
    }

    @AfterThrowing(value = "pc()",throwing = "e")
    public void afterThrowing(JoinPoint jp,Exception e) {
    String name = jp.getSignature().getName();
    System.out.println(name + "方法抛出异常,异常时:" + e);
    }

    @Around("pc()")
    public Object around(ProceedingJoinPoint pj) throws Throwable {
    return pj.proceed();
    }
    }

     6、整合servlet、filter、listener

    以servle为例,需要在启动类上加上@ServletComponentScan

    @WebServlet
    public class MyHttpServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("name>>>" + req.getParameter("name"));
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    super.doGet(req, resp);
    }
    }

    我的github地址上都有单独的工程讲解,可以去参考:https://github.com/FadeHub/spring-boot-learn  

  • 相关阅读:
    Linux组件封装(三) Thread的封装
    Linux组件封装(二) 条件变量Condition的封装
    Linux组件封装(一) 互斥锁MutexLock
    迭代器适配器(二) general inserter的简单实现
    迭代适配器(一) back_insert和front_insert的简单实现
    priority_queue的简单实现
    svm简易例子——matlab版本
    讲座 on the connection between vision and language
    svm相关理解
    为什么深度学习有效?(why deep learning works)
  • 原文地址:https://www.cnblogs.com/treeshu/p/11253430.html
Copyright © 2020-2023  润新知