我正在尝试为我的web应用程序创建请求日志。我使用的是Spring3.0。
我实现了一个扩展HandlerInterceptorAdapter的类,并使用preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)来拦截请求。
在该方法中,我希望能够记录请求主体(我的参数是直接写入请求主体的XML中的对象),为此我使用request.getReader();
问题是-稍后当spring控制器试图读取请求时,我会得到一个IllegalStateException。
有没有办法做我想做的事?
发布于 2011-06-12 22:48:43
您可以使用筛选器来完成此操作。请求参数很容易处理。但是,处理请求正文要困难得多,需要包装servlet请求,参见:HttpServletRequest。
您需要查看传入的请求有多大,并决定是否要将请求正文存储为tmp文件或字符串。
您需要使用用于日志记录的文件或保存的字符串覆盖ServetRequest.getInputStream()。
如果请求正文很大,我建议将输入流放入缓冲输入流中,然后读取正文的开头。
public class LogRequest extends HttpServletRequestWrapper {
public LogRequest(HttpServletRequest request) {
super(request);
}
@Override
public ServletInputStream getInputStream() throws IOException {
//read from tmp file or string.
}
@Override
public BufferedReader getReader() throws IOException {
//read from tmp file or string
}
}发布于 2014-11-27 20:23:23
Spring有一个现成的过滤器可以帮您完成这项工作-请参阅this answer中描述的AbstractRequestLoggingFilter及其子类的用法。
请注意,使用此解决方案时,只有在完成请求处理并且应用程序读取了请求正文之后,才会记录请求正文。
发布于 2017-02-06 20:23:41
小请求的简单实现。请勿将其用于分块请求。
package ru.rbs.logger.web;
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
class CachedRequestWrapper extends HttpServletRequestWrapper {
private final byte[] cachedBody;
CachedRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(request.getInputStream(), bos);
cachedBody = bos.toByteArray();
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new CachedServletInputStream();
}
byte[] toByteArray(){
return cachedBody;
}
private class CachedServletInputStream extends ServletInputStream {
private InputStream baseInputStream;
CachedServletInputStream() throws IOException {
baseInputStream = new ByteArrayInputStream(cachedBody);
}
@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 baseInputStream.read();
}
}
}https://stackoverflow.com/questions/6322362
复制相似问题