拦截@RequestBody的请求数据

要拦截首先想到的是拦截器,@RequestBody只能以流的方式读取,流被读过一次后,就不在存在了,会导致会续无法处理,因此不能直接读流

为了解决这个问题,思路如下:

1、读取流前先把流保存一下

2、使用过滤器拦截读取,再通过chain.doFilter(wrapper, response);将保存的流丢到后面程序处理

package com.qmtt.tools;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * 
 * @author 流的方式获取JSON数据
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    // 存放JSON数据主体
    private final String body;

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream 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) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }

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

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

            @Override
            public void setReadListener(ReadListener listener) {

            }
        };
        return servletInputStream;
    }

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

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

过滤器写法如下

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String path = req.getContextPath();
        String method = req.getServletPath();
        Map map = request.getParameterMap();
        String msg = "";
        RequestWrapper wrapper = new RequestWrapper(req);
        if (map != null)
            msg = JsonUtils.toJsonString(map);
        log.info(String.format("请求路径:%s,请求方法%s,请求参数:%s-%s", path, method, msg, wrapper.getBody()));
        chain.doFilter(wrapper, response);
    }

另一种方法:通过拦截器处理,拦截所有controller的讲求可以实现(目前我用的是拦截器)

有追求,才有动力!

向每一个软件工程师致敬!

by wujf

mail:921252375@qq.com

原文地址:https://www.cnblogs.com/wujf/p/8337797.html