request.getInputStream以流的方式读取请求只能读取一次

当项目上用了 request.getInputStream以流的方式读取请求,而实际项目中一般会用到一些拦截器,做一些校验,发现只能读取一次,真正到Controller里,发现是不能用的。

比如,前端请求时以json方式提交 ,后台用用@RequestBody或者用流 做json到对象的解析,这时这个json串里有个参数要放在拦截器里校验一下

在拦截器里以流的形式读取了,后台这就取不到参数

解决办法,网上好多人是加了个过滤器,把请求包装一下,



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获取参数

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":""
}
 

转载于:https://my.oschina.net/lvzi98/blog/2980786

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值