攔截@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的講求可以實現(目前我用的是攔截器)


免責聲明!

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



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