springboot利用拦截器和过滤器获取post请求参数

时间:2025-03-20 11:53:56

示例

        • 1. 继承HttpServletRequestWrapper
        • 2. 配置拦截器
        • 3. 注册拦截器
        • 4. 配置过滤器,用来把request请求传递下去
        • 5. 在启动类中注册拦截器

1. 继承HttpServletRequestWrapper
package com.example.springboot.wrapper;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class RequestWrapper extends HttpServletRequestWrapper {

    private final String body;

    public RequestWrapper(HttpServletRequest request) {
        super(request);

        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {

        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;
    }

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

    public String getBody() {
        return this.body;
    }
}
2. 配置拦截器
package com.example.springboot.interceptor;

import com.example.springboot.wrapper.RequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

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

@Component("parameterInterceptor")
@Slf4j
public class ParameterInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

        RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest);
        String body = requestWrapper.getBody();

        log.info("post request parameter ----> " + body);

        httpServletRequest.setAttribute("body", new RequestWrapper(httpServletRequest).getBody());

        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        (request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
3. 注册拦截器
package com.example.springboot.config;

import com.example.springboot.interceptor.ParameterInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

// 方式一:
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //註冊TestInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(new ParameterInterceptor());
        registration.addPathPatterns("/vds/education/*");  // 指定路径下的都被拦截 最好不使用/**
        /*registration.excludePathPatterns("/","/error","/static/**");       //添加不拦截路径*/
    }
}
config:
  path:
    special: 
      - 需要拦截的路径1
      - 需要拦截的路径2
      - ...
package com.example.springboot.config;

import com.example.springboot.interceptor.ParameterInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

// 方式二: 通过配置文件设置拦截路径
@Configuration
@ConfigurationProperties(prefix = "")
public class InterceptorConfigurer implements WebMvcConfigurer {

    private List<String> special = new ArrayList<>();

    public List<String> getSpecial() {
        return special;
    }

    public void setSpecial(List<String> special) {
        this.special = special;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        //注册ParameterInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(new ParameterInterceptor());

        registration.addPathPatterns(special);  // 指定路径都被拦截 最好不使用/**

        /*registration.excludePathPatterns("/","/error","/static/**");       //添加不拦截路径*/

    }
}
4. 配置过滤器,用来把request请求传递下去
package com.example.springboot.filter;


import com.example.springboot.wrapper.RequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


// @Component
// @Component会将类自动注册为bean 在启动类中再用@ServletComponentScan扫描注册bean会出现bean重复注册报错,二者选其一 或者在配置文件中启用覆盖同名bean -bean-definition-overriding=true
@WebFilter(urlPatterns = "/*",filterName = "channelParameterFilter")
@Slf4j
public class ChannelParameterFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        log.info("filer 初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("过滤操作");
        ServletRequest requestWrapper = null;
        if (servletRequest instanceof HttpServletRequest) {

            requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
        }
        if (requestWrapper == null) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            filterChain.doFilter(requestWrapper, servletResponse);
        }
    }

    @Override
    public void destroy() {
        log.info("销毁过滤器");
    }
}
5. 在启动类中注册拦截器
package com.example.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Configuration;

@SpringBootApplication
/**
 * 使用 @ServletComponentScan 注解
 * Servlet 可以直接通过 @WebServlet 注解自动注册
 * Filter 可以直接通过 @WebFilter 注解自动注册
 * Listener 可以直接通过 @WebListener 注解自动注册
 */
@ServletComponentScan("")  //注册过滤器注解
// @Component会将类自动注册为bean 在启动类中再用@ServletComponentScan扫描注册bean会出现bean重复注册报错,二者选其一 或者在配置文件中启用覆盖同名bean -bean-definition-overriding=true
@Configuration
public class SpringBootTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTestApplication.class, args);
    }
}