当接口请求的时候使用application/json之类的文本格式的时候,获取的时候需要从request的body体里获取,当需要使用过滤器、拦截器或者AOP的时候,难免会遇到读流的问题,拦截到的request读取过一次之后在Controller中就无法再获取,此处记录解决方案:

1
2
3
4
5
6
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 缓存request到ApiHttpServletRequestWrapper中
ApiHttpServletRequestWrapper wrapper = new ApiHttpServletRequestWrapper(request);
String jsonStr = RequestJsonUtil.getRequestJsonString(wrapper);
Map<String, Object> param = JSONObject.fromObject(jsonStr);

ApiHttpServletRequestWrapper.java

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StreamUtils;
/**
* 重写HttpServletRequestWrapper的方法
*/
public class ApiHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody = null;
public ApiHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
//缓存请求body
try {
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 重写 getInputStream()
*/
@Override
public ServletInputStream getInputStream() throws IOException {
if(requestBody == null){
requestBody= new byte[0];
}
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
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() throws IOException {
return bais.read();
}
};
}
/**
* 重写 getReader()
*/
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}

RequestJsonUtil.java

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 请求Json工具类
*/
public class RequestJsonUtil {
/***
* 获取 request 中 json 字符串的内容
* @param request
* @return
* @throws IOException
*/
public static String getRequestJsonString(HttpServletRequest request)
throws IOException {
String submitMehtod = request.getMethod();
// GET
if (submitMehtod.equals(RequestMethod.GET)) {
return new String(request.getQueryString().getBytes("iso-8859-1"), "utf-8").replaceAll("%22", "\"");
// POST
} else {
return getRequestPostStr(request);
}
}
/**
* 获取 post 请求的 byte[] 数组
* @param request
* @return
* @throws IOException
*/
public static byte[] getRequestPostBytes(HttpServletRequest request)
throws IOException {
int contentLength = request.getContentLength();
if (contentLength < 0) {
return null;
}
byte buffer[] = new byte[contentLength];
for (int i = 0; i < contentLength; ) {
int readlen = request.getInputStream().read(buffer, i,
contentLength - i);
if (readlen == -1) {
break;
}
i += readlen;
}
return buffer;
}
/**
* 获取 post 请求内容
* @param request
* @return
* @throws IOException
*/
public static String getRequestPostStr(HttpServletRequest request)
throws IOException {
byte buffer[] = getRequestPostBytes(request);
String charEncoding = request.getCharacterEncoding();
if (charEncoding == null) {
charEncoding = "UTF-8";
}
return new String(buffer, charEncoding);
}
}

最后,需要把所有请求都过滤一遍

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
package com.sq580.openapi.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.sq580.openapi.filter.HttpServletRequestReplacedFilter;
/**
* 自定义Filter配置
*/
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean httpServletRequestReplacedFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HttpServletRequestReplacedFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("httpServletRequestReplacedFilter");
registration.setOrder(1);
return registration;
}
}

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
43
import com.sq580.ms.institution.facade.util.request.ApiHttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* ClassName: HttpServletRequestReplacedFilter<br/>
* Function: TODO ADD FUNCTION(可选)<br/>
* Reason: TODO ADD REASON(可选)<br/>
* Date: 2017-11-06 19:09<br/>
*
* @author zoro
*/
@Slf4j
public class HttpServletRequestReplacedFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("httpServletRequestReplacedFilter init, FilterConfig:{}",filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(request instanceof HttpServletRequest) {
requestWrapper = new ApiHttpServletRequestWrapper((HttpServletRequest) request);
}
if(requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy() {
log.info("httpServletRequestReplacedFilter destroy.");
}
}