我正在尝试从 HttpServletRequest 记录请求正文,我添加了一个包装器来执行此操作,但在检索它后我仍然得到一个空请求正文。请问我怎么能多次得到尸体呢?
public class LogginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle - " + handler);
MDC.put(START_TIME_VAR, Long.toString(System.currentTimeMillis()));
MultiReadHttpServletRequest requestWrapper = new MultiReadHttpServletRequest(request);
final StringBuilder builder = new StringBuilder();
BufferedReader reader = null;
InputStream inputStream = requestWrapper.getInputStream();
if (inputStream != null) {
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
MDC.put(REQUEST_BODY_VAR, builder.toString());
包装:
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedBytes;
public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (cachedBytes == null)
cacheInputStream();
return new CachedServletInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
private void cacheInputStream() throws IOException {
/*
* Cache the inputstream in order to read it multiple times. For
* convenience, I use apache.commons IOUtils
*/
cachedBytes = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cachedBytes);
}
/* An inputstream which reads the cached request body */
public class CachedServletInputStream extends ServletInputStream {
private ByteArrayInputStream input;
public CachedServletInputStream() {
/* create a new input stream from the cached request body */
input = new ByteArrayInputStream(cachedBytes.toByteArray());
}
@Override
public int read() throws IOException {
return input.read();
}
}
}
我确实得到一个空的请求正文(rawrequest 有一个 header 但正文为空):
@RequestMapping(value = "/someuri", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Object post(final HttpServletRequest request,
@PathVariable final String parameter, @PathVariable final String parameter2,
HttpEntity<String> rawrequest, @RequestHeader("Authorization") final String Authorization) {
最佳答案
我找到了在拦截器中使用 setAttribute 重置请求正文的解决方案。
request.setAttribute("com.xp.input", body);
然后我在我的过程中检索它:
Object body = request.getAttribute("com.xp.input");
关于java - 尝试登录 HandlerInterceptor 时请求正文为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51385944/