0%

解决HttpServletRequest InputStream只能读取一次问题

在Filter中读取inputSeream读取一次之后就无法再次读取,解决办法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class LoggerHttpServletRequestWrapper extends HttpServletRequestWrapper {

private final byte[] body;

public LoggerHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = StreamUtils.readBytes(request.getInputStream());
}

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

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

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

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

@Override
public void setReadListener(ReadListener readListener) {

}

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

}

调用如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(request instanceof HttpServletRequest) {
requestWrapper = new LoggerHttpServletRequestWrapper((HttpServletRequest) request);
if (((HttpServletRequest) request).getMethod().equals("POST")){
String path = ((HttpServletRequest) request).getServletPath();
String param = StreamUtils.streamToString(requestWrapper.getInputStream());
LoggerFactory.getLogger("filter."+path).info(param);
}else if (((HttpServletRequest) request).getMethod().equals("GET")){
String path = ((HttpServletRequest) request).getServletPath();
String queryString = ((HttpServletRequest) request).getQueryString();
LoggerFactory.getLogger("filter."+path).info(queryString);
}


}
if(requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}

工具类如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class StreamUtils {

/**
* @param inputStream inputStream
* @return 字符串转换之后的
*/
public static String streamToString(InputStream inputStream) {
try(BufferedReader br =new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
StringBuilder builder = new StringBuilder();
String output;
while((output = br.readLine())!=null){
builder.append(output);
}
return builder.toString();
} catch (IOException e) {
throw new RuntimeException("Http 服务调用失败",e);
}
}



public static byte[] readBytes(ServletInputStream inputStream) {
return streamToString(inputStream).getBytes(Charset.forName("UTF-8"));
}
}