request.getInputStream以流的方式讀取請求只能讀取一次

當項目上用了 request.getInputStream以流的方式讀取請求,而實際項目中通常會用到一些攔截器,作一些校驗,發現只能讀取一次,真正到Controller裏,發現是不能用的。前端

好比,前端請求時以json方式提交 ,後臺用用@RequestBody或者用流 作json到對象的解析,這時這個json串裏有個參數要放在攔截器裏校驗一下java

在攔截器裏以流的形式讀取了,後臺這就取不到參數spring

解決辦法,網上好多人是加了個過濾器,把請求包裝一下,apache

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

public class RequestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if (request instanceof HttpServletRequest) {
            requestWrapper = new SdHttpServletWrapper((HttpServletRequest) request);
        }
        if (null == requestWrapper) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }

    @Override
    public void destroy() {

    }

}
import org.apache.commons.lang.StringUtils;

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.Charset;

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

    public SdHttpServletWrapper(HttpServletRequest request)
            throws IOException {
        super(request);
        body = readBytes(request.getReader(), "utf-8");
    }

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

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {

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

    /**
     * 經過BufferedReader和字符編碼集轉換成byte數組
     *
     * @param br
     * @param encoding
     * @return
     * @throws IOException
     */
    private byte[] readBytes(BufferedReader br, String encoding) throws IOException {
        String str = null, retStr = "";
        while ((str = br.readLine()) != null) {
            retStr += str;
        }
        if (StringUtils.isNotBlank(retStr)) {
            return retStr.getBytes(Charset.forName(encoding));
        }
        return null;
    }


}
<filter>
		<filter-name>springFilter</filter-name>
		<filter-class> com.XXXXX.RequestFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>springFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

還有一種辦法就是前端請求時,把要校驗的參數,拼到url後面,這樣後臺這能夠同時用@RequestBody 和request.getparametere獲取參數json

POST /srs/manage/sysparam/query?token=dsfdsfsdfsdfs HTTP/1.1
Host: srs.xxx.com
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: a52c36d2-d42d-4fc5-3132-8ad03dd65a08數組

 {"classCode":"srs.txn.type",
    "code":"P",
    "name":""
}
 app

相關文章
相關標籤/搜索