springboot 如何在請求進入controller之前改變body中的值


springboot 如何在請求進入controller之前改變body中的值

  • 攔截器HandlerInterceptorAdapter

通過繼承HandlerInterceptorAdapter 攔截器,可以重寫preHandle方法,但是在這個方法里直接對HttpServletRequest中的body進行更改是無效的。HttpServletRequest請求實際上並沒有改變。

  • HttpServletRequestWrapper 請求包裝類

通過繼承HttpServletRequestWrapper 可以重寫自己的包裝類。如:

public class MultiReadHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private String tempBody;

    public MultiReadHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        tempBody = AbstractRequestUtils.getRequestBody(request);
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(tempBody.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public int readLine(byte[] b, int off, int len) throws IOException {
                return super.readLine(b, off, len);
            }

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

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() {
                return byteArrayInputStream.read();
            }
        };
    }

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

    public String getBody() {
        return this.tempBody;
    }

    public void setBody(String body) {
        this.tempBody = body;
    }

}

在這里面定義了一個tempbody,可以防止出現流只能被讀取一次而出現的流重讀錯誤。

  • 定義一個過濾器,以過濾相應請求,讓它們使用包裝過的HttpServletRequest。
@Slf4j
public class RequestWrapperFilter implements Filter {

    @Override
    public void init(FilterConfig config) {
        log.info("==>RequestWrapperFilter啟動");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
        MultiReadHttpServletRequestWrapper requestWrapper = new MultiReadHttpServletRequestWrapper((HttpServletRequest) request);
        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
    }
}
  • 在WebMvcConfigurer中注冊過濾器(這里也注冊了最開始的攔截器)
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public WebInterceptor webInterceptor() {
        return new WebInterceptor();
    }

    @Bean
    public FilterRegistrationBean addRequestWrapperFilter() {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new RequestWrapperFilter());
        registration.setName("RequestWrapperFilter");
        registration.addUrlPatterns("/interest/*");
        registration.setOrder(1);
        return registration;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webInterceptor()).addPathPatterns("/interest/**");
    }
}
  • 在攔截器中對body中的值進行修改
@Slf4j
public class WebInterceptor extends HandlerInterceptorAdapter {
    @Resource
    private IpVisitService ipVisitService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String ip = HttpUtils.getRemoteIP(request);

        log.info("!!!!!!!!!!!!!!!!currentIp:{}", ip);

        MultiReadHttpServletRequestWrapper requestWrapper = (MultiReadHttpServletRequestWrapper) request;
        String body = requestWrapper.getBody();
        Preconditions.checkArgument(!StringUtils.isEmpty(body), "請求參數有誤!");
        BaseReq baseReq = JSON.parseObject(body, BaseReq.class);
        baseReq.setIp(ip);
        requestWrapper.setBody(JSON.toJSONString(baseReq));
        return true;
    }

}

經過實驗,證明修改成功!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM