Filter, Interceptor, Validator, Aop 执行顺序

顺序如下
 

1 filter
    2.1 interceptor-pre
        3 valid参数校验
            4.1 aop-pre
                5 业务方法
            4.2 aop-post(校验失败,异常时_不执行)
    2.2 interceptor-post(校验失败,异常时_不执行)
                    6 全局异常捕获
    2.3 interceptor-afterCompletion(校验失败,异常时_任然执行)

============================================

filter 过滤器 https://www.cnblogs.com/huanzi-qch/p/11239167.html
filter: post拿不到参数? POST的请求是在请求体body中,而POST请求中的body参数是以流形式存在的    https://blog.csdn.net/qq_40866897/article/details/111404480

Interceptor 拦截器 https://blog.csdn.net/worilb/article/details/114194446

    https://www.cnblogs.com/eoooxy/p/6566347.html
  ①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
===================
WebRequestInterceptor与HandlerInterceptor的异同?https://www.cnblogs.com/zhangww/p/13596039.html

WebRequestInterceptor的入参WebRequest是包装了HttpServletRequest 和HttpServletResponse的,通过WebRequest获取Request中的信息更简便。
2.WebRequestInterceptor的preHandle是没有返回值的,说明该方法中的逻辑并不影响后续的方法执行,所以这个接口实现就是为了获取Request中的信息,或者预设一些参数供后续流程使用。
3.HandlerInterceptor的功能更强大也更基础,可以在preHandle方法中就直接拒绝请求进入controller方法。
使用场景

Validator 参数校验 SpringBoot 参数校验的方法 - 木白的菜园 - 博客园

aop spring boot 通过 aop 实现全局打印请求参数和返回结果 - 链滴

===========================================

Filter

@WebFilter(filterName = "testFilter", urlPatterns = {"/test"})
@Component
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 获取post时, 请求中的body参数是流的形式存在 request.getRequestParams()拿不到值
        // 所以需要自行封装
        RequestWrapper requestWrapper = new RequestWrapper(request);

        System.out.println("TestFilter," + request.getRequestURI());
        System.out.println(requestWrapper.getBodyString());
        //执行
        filterChain.doFilter(requestWrapper, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

RequestWrapper 防止读取流后, controller获取不到值

import org.springframework.util.StreamUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;


public class RequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //保存一份InputStream,将其转换为字节数组
        body = StreamUtils.copyToByteArray(request.getInputStream());
    }

    //转换成String
    public String getBodyString(){
        return new String(body, StandardCharsets.UTF_8);
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    //把保存好的InputStream,传下去
    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }
}

Interceptor

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...1");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...3");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("postafterCompletionHandle...4");
    }
}

注册拦截器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Component
public class MyInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/test").excludePathPatterns("/admin");

    }
}

aop

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyLogAspect {

    @Pointcut("@annotation(com.xxx.annotation.MyLog)")
    public void logCut() {
    }

    @Around("logCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("aop start");
        Object result = point.proceed();
        System.out.println("aop end");
        return result;
    }

}

controller

@RestController
@RequestMapping("")
public class TestController {
    @RequestMapping("/test")
    public String test() {
        System.out.println("业务逻辑....2");
        return "success";
    }
}

==================

其他:

servlet 【小家Java】Servlet规范之---请求(request):Servlet中如何获取POST请求参数?(使用getParameter())_Java方向盘-CSDN博客_request获取post参数

=================
如果 参数请求为json格式, 则可以通过调整日志级别 来实现快速打印请求参数
<logger name="org.springframework.web.servlet.DispatcherServlet" level="debug"/>

参考 DispatcherServlet 类的 logRequest()方法

org.springframework.web.servlet.DispatcherServlet [91]:POST "/test", parameters={}
org.springframework.web.servlet.DispatcherServlet [1131]:Completed 404 NOT_FOUND
org.springframework.web.servlet.DispatcherServlet [91]:"ERROR" dispatch for POST "/error", parameters={}
org.springframework.web.servlet.DispatcherServlet [1127]:Exiting from "ERROR" dispatch, status 404

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值