springboot10:web开发常用功能(拦截器,文件上传,异常处理)

一.拦截器

1.使用

  • 访问任何请求,都只有登录才能访问,挨个写入请求太困难,使用拦截器机制handlerIntercepter(prehandle方法,posthandle方法,afterCompletion方法)
  • 编写一个拦截器实现handlerInterceptor接口
  • 编写的拦截器注册到容器中(实现webMvcConfigure的addInterceptors方法)
  • 指定拦截规则(如果是拦截所有,静态资源也会被拦截)
registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")//所有请求,包括静态资源也会拦截
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");//放行的请求

2.拦截器原理

  • 根据当前请求找到一个具体的handler执行,并且找到handler的所有拦截器,即handlerExecution
  • 找到了handler适配器后
  • 执行目标方法之前执行了 所有handler的prehandle方法
    • 对所有的拦截器执行for循环顺序执行所有拦截器调用prehandle方法
      • 如果当前拦截器prehandle返回true,放行,执行下一个拦截器的prehandle
      • 如果当前拦截器返回为false,直接倒序执行所有已经执行了的拦截器的afterCompletion
  • 如果任何一个拦截器执行失败返回false,直接跳出不执行目标方法
  • (所有拦截器都返回true)执行目标方法
  • 执行目标方法后执行所有的倒序posthandler方法
  • 前边步骤有任何异常,都直接触发拦截器aftercompletion方法
  • 页面渲染逻辑中
    • 页面成功渲染完成之后
    • 倒序触发所有拦截器的aftercompletion
      在这里插入图片描述

二.文件上传

1.文件上传使用

  • 使用multipart
 @PostMapping("/upload")
    public String upload(@RequestParam("email") String email,
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,
                         @RequestPart("photos") MultipartFile[] photos) throws IOException {

        if(!headerImg.isEmpty()){
            //保存到磁盘上
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("E:\\"+originalFilename));
        }
        if(photos.length>0){
            for(MultipartFile photo:photos){
                if(!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("E:\\"+originalFilename));
                }
            }
        }
        return "main";
    }

2.文件上传源码解析

  • 自动配置好了standardServletMultipartResolver(文件上传解析器)
  • 请求进来使用文件上传解析器判断并封装上传请求
    • 判断请求是否为文件上传请求(判断表单的内容类型是否为multipart/)
    • 判断是文件上传请求并封装
  • 将request封装为multipartHttpServletRequest
  • 找到handler来处理请求,执行具体的handler来执行
    • 利用参数解析器解析文件上传(@RequestPart(“headerImg”) MultipartFile headerImg,)
    • 找到参数解析器RequestPartMethod来将请求中的文件内容封装为MultipartFile

三.异常处理

1.springboot处理错误

  • 默认情况下,springboot提供/error处理所有错误的映射
  • 对于机器客户端,产生json
  • 对于浏览器客户端,产生错误页
    都有 时间戳,都有状态码

2.自定义错误页面

  • 默认规则:放在error下的4xx 和5xx

3.错误处理(自动配置)原理

①容器中配置

  • 有配置类errorMVCAutoConfiguration 自动配置异常处理规则
    • 给容器中放置了 DefaultErrorAttribute类型的组件 id:errorAttributes,定义错误页面可以包含的信息
    • 给容器中放置了 BasicErrorController类型的组件 id:basicErrorController(处理默认/error路径的请求;页面响应一个modelAndView(error))
    • 容器中有View组件,id:error(容器中有一个视图解析器(响应默认错误页)BeanNameViewResolver,按照返回的视图名error作为组件的id去找view对象)
    • 容器中中放置了DefaultErrorViewResolver,id=…,如果发生错误,会以HTTP状态码作为视图页地址(404,5xx)找到真正的页面 error/404,5xx.html
  • 如果想要返回页面,就会找error视图(staticView)。(默认是一个白页)
  • 上面的controller组件中的两个方法(responseEntity写出去json数据,errorHtml写出去一个视图 适配响应)

②整体流程(异常处理)

  • 找到适配器执行目标方法时(目标方法运行期间,有任何异常都会被catch,而且标志当前请求结束,并且用dispacthException进行封装)
  • 进入视图解析流程(页面渲染?)传参
    (request,response,handler,mv,dispatchException)
  • 处理handler异常最后返回一个mv
    • 遍历handlerExceptionResolvers处理器异常解析器看谁能处理当前异常
      • DefaultErrorAttribute…给请求域中保存了异常信息并且返回空(必须返回不为空才结束)
      • (继续解析) 三个异常解析器的组合(第一个异常解析器不满足其要求,第二个异常解析器不满足其要求,第三个异常解析器不满足要求)
      • 默认没有任何解析器能处理异常,异常被抛出
    • 如果没有任何解析器处理异常,最终底层会发送(转发)/error请求
  • 接下来 BasicErrorController来处理/error请求
  • 此时是浏览器发送,此时其中方法处理/error
    • 此时会解析错误视图,遍历所有的ErrorViewResolver错误视图解析器看谁能处理错误视图
      • DefaultErrorViewResolver把响应的状态码500拿到作为错误页的地址拼接/error/500,然后通过模板引擎判断有没有/error/500页面,如果有直接返回页面带.html页面

4.定制错误处理逻辑

  • 自定义错误页 放在error下的4xx 和5xx(400错误无法解决)精确匹配
  • 利用@ControllerAdvice + @ExceptionHandler处理异常
    • @ControllerAdvice该类为处理异常类 @ExceptionHandler({ArithmeticException.class,NullPointerException.class})为该方法能处理的异常类型
    • 原理?
    • 在三个异常解析器的组合中第一个异常解析器ExceptionHandlerExceptionResolver能够处理(第一个异常处理器判断是否有标志@ExceptionHandler的方法,如果有标志,就调用该方法进行处理)
    • return 字符串(放到了modelAndView) 等于正常的方法
  • 抛出自己定义的异常
    @ResponseStatus()可以在自定义异常类声明一个错误状态码(也可以被解析)
    • 原理?
    • 在三个异常解析器的组合中第二个异常解析器ResponseStatusExceptionResolver能够处理(第二个异常处理器判断当前异常是否有@ResponseStatus注解,如果有,就调用该方法进行处理)
    • 将注解的状态码解析出来,然后直接跳去错误页 response.sendError();tomcat发送的/error,然后进入处理error逻辑
  • 底层异常(参数不存在)框架抛出异常
    • 在三个异常解析器的组合中第三个异常解析器DefaultHandlerExceptionResolver能够处理(第三个异常处理器判断当前异常是否是springmvc底层的异常,如果是,就调用该方法进行处理)
    • 然后sendError(执行方法立即结束,tomcat抛出一个/Error(包含状态码),看谁能处理)
    • 正常直接返回tomcat的错误页,但是sprignmvc底层有servlet专门处理/error请求

5.自定义异常解析器

  • 直接定义返回值modelandView不让其他异常解析器解析,并且response.sendError(511,“错误”) 即tomcat发送 /error
  • @order 让其排在第一位
  • @component成为bean
  • 实现handlerExceptionResolver异常解析器

6.ErrorViewResolver实现自定义处理异常

  • response.sendError error请求就回转给controller
  • 异常没人处理,也会直接senderror(modelandview都是null)
  • 要去的页面地址是ErrorViewResolver解析的,去/error/xxx.html页面
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值