Spring Boot相关

Spring Boot相关

拦截器

  1. 首先创建自定义的拦截器,实现HandlerInterceptor接口,然后重写其下的三个方法(preHandle,postHandle,afterCompletion

    package com.fmxu.interceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * @author Dell
     * @projectName springbootdemo
     * @description: 登陆检查
     * @date 2021/3/31/14:55
     */
    /*
    * 1、配置好拦截器需要拦截哪些请求
    * 2、把这些配置放在容器中
    *
    * */
    public class LoginInterceptor implements HandlerInterceptor {
    
    
        //目标方法执行之前
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //登陆检查逻辑
            HttpSession session = request.getSession();
            Object loginUser = session.getAttribute("loginUser");
            //登陆就放行
            if(loginUser!=null){
                return true;
            }
            //否则拦截. 跳转到登录页
            response.sendRedirect("/");
            return false;
        }
    
        //目标方法执行之后
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
    
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    
  2. 然后创建自定义的配置类,实现WebMvcConfigurer接口,重写addInterceptors方法

    package com.fmxu.config;
    
    
    import com.fmxu.interceptor.LoginInterceptor;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * @author Dell
     * @projectName springbootdemo
     * @description:
     * @date 2021/3/31/14:53
     */
    @Configuration
    public class MyConfig implements WebMvcConfigurer {
    
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor())
                    .addPathPatterns("/**")    //拦截所有资源
                    .excludePathPatterns("/","/login");    //不拦截的请求路径
        }
    }
    
    

    拦截器原理

    • 根据当前请求,HandlerExecutionChain找到可以处理请求的handler以及handler的所有拦截器
    • 顺序执行所有拦截器的prehandle方法
      • 如果当前拦截器的preHandle方法返回的是true,则执行下一个拦截器的prehandle
      • 如果当前拦截器返回的为false,则直接调用triggerAfterCompletion方法倒序执行已经放行的拦截器的afterCompletion方法。
    • 如果任何一个拦截器返回false,直接跳出不执行目标方法。
    • 所有拦截器都返回True,执行目标方法。
    • 倒序执行所有拦截器的postHandle方法。

    在这里插入图片描述

文件上传

  1. 简单模拟一下

    package com.fmxu.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestPart;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.IOException;
    
    
    /**
     * @author Dell
     * @projectName springbootdemo
     * @description:
     * @date 2021/3/31/16:00
     */
    //模拟单文件上传和多文件上传
    @Controller
    public class UploadController {
    
    
        @PostMapping("/upload")
        public String upload(@RequestPart MultipartFile image,@RequestPart MultipartFile[] photos) throws IOException {
            if(!image.isEmpty()){
                //获取文件的原始名
                String originalFilename = image.getOriginalFilename();
                image.transferTo(new File("D:\\cache\\"+originalFilename));
            }
    
            if(photos.length>0){
                for (MultipartFile photo : photos) {
                    if(!photo.isEmpty()){
                        String originalFilename = photo.getOriginalFilename();
                        photo.transferTo(new File("D:\\cache\\"+originalFilename));
                    }
                }
            }
            return "main";
        }
    
    }
    

    一般文件上传有大小限制。

    我们可以在application.yml主配置文件中设置文件上传的大小。

    spring:
      servlet:
        multipart:
          max-file-size: 10MB
          max-request-size: 100MB
    

    原理

    文件上传自动配置类-MultipartAutoConfiguration-MultipartProperties

    • 自动配置好了StandardServletMultipartResolver[文件上传解析器]
    • 原理步骤
      • 请求进来使用文件上传解析器判断isMultipart并封装(使用resolveMultipart并返回MultipartHttpServletRequest)文件上传请求
      • 参数解析器来解析并将请求中的文件内容封装成MultipartFile
      • 将request中文件信息封装为一个Map.MultiValue<String,MultipartFile>

异常处理

  1. 错误处理

    默认规则:

    • 默认情况下,Spring Boot提供/error处理所有错误的映射
    • 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态码和异常消息的详细信息。对于浏览器客户端,响应一个whitelabel错误视图,以HTML格式呈现相同的数据。
    • 要对其进行自定义,添加View解析为error
    • 要完全替换默认行为,可以实现ErrorController并注册该类型的Bean定义,或者添加ErrorAttributes类型的组件以使用现有机制替换其内容。
    • 在static目录下添加error目录,并在其下面添加4xx,5xx页面会被自动解析。
  2. 异常处理自动配置原理

    • ErrorMvcAutoConfiguration 自动配置异常处理规则

    • 容器中的组件:

      • 类型:DefaultErrorAttributes -> id : errorAttributes

      • 类型:BasicErrorAttributes -> id : basicErrorAttributes

        默认处理/error路径的请求。 页面响应 new ModelAndView("error",model)

        容器中有View组件 -> id是error (也即是默认错误响应页)

        容器中放入BeanNameViewResolver(视图解析器)组件,按照返回的视图名作为组件的id去容器找View对象。

  3. 异常处理步骤流程

    1. 执行目标方法,目标方法运行期间有任何异常都会被catch,而且标识当前请求结束,并且抛出dispatchException异常

    2. 进入视图解析流程(页面渲染)

    3. processHandlerException处理handler发生的异常,处理完返回ModelAndView

      • 遍历所有的handlerExceptionResolvers,看谁能处理当前异常[HandlerExceptionResolver处理器异常解析器]

      • 系统默认的异常解析器:

        - `DefaultErrorAttributes`
        - `ExceptionHandlerExceptionResolver`
        - `ResponseStatusExceptionResolver`
        - `DefaultHandlerExceptionResolver`
        
        1. DefaultErrorAttributes先来处理异常,把异常信息保存到request域,并返回null
        2. 默认没有任何解析器能处理异常,所以异常会被抛出
          • 如果没有任何解析器能处理异常最终底层会发送/error请求,会被底层的BasicErrorController处理
          • 解析错误视图,遍历所有的ErrorViewResolver看谁能解析。
          • 默认的DefaultErrorViewResolver,作用是把响应状态码作为错误页的地址,error/500.html
          • 末班引擎最终响应这个页面error/500.html
            析器能处理异常最终底层会发送/error请求,会被底层的BasicErrorController处理
          • 解析错误视图,遍历所有的ErrorViewResolver看谁能解析。
          • 默认的DefaultErrorViewResolver,作用是把响应状态码作为错误页的地址,error/500.html
          • 末班引擎最终响应这个页面error/500.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值