首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >记录HttpRequest参数和请求正文

记录HttpRequest参数和请求正文
EN

Stack Overflow用户
提问于 2011-06-12 22:03:32
回答 3查看 24.5K关注 0票数 13

我正在尝试为我的web应用程序创建请求日志。我使用的是Spring3.0。

我实现了一个扩展HandlerInterceptorAdapter的类,并使用preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)来拦截请求。

在该方法中,我希望能够记录请求主体(我的参数是直接写入请求主体的XML中的对象),为此我使用request.getReader();

问题是-稍后当spring控制器试图读取请求时,我会得到一个IllegalStateException

有没有办法做我想做的事?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-12 22:48:43

您可以使用筛选器来完成此操作。请求参数很容易处理。但是,处理请求正文要困难得多,需要包装servlet请求,参见:HttpServletRequest

您需要查看传入的请求有多大,并决定是否要将请求正文存储为tmp文件或字符串。

您需要使用用于日志记录的文件或保存的字符串覆盖ServetRequest.getInputStream()。

如果请求正文很大,我建议将输入流放入缓冲输入流中,然后读取正文的开头。

代码语言:javascript
运行
复制
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
    }

}
票数 6
EN

Stack Overflow用户

发布于 2014-11-27 20:23:23

Spring有一个现成的过滤器可以帮您完成这项工作-请参阅this answer中描述的AbstractRequestLoggingFilter及其子类的用法。

请注意,使用此解决方案时,只有在完成请求处理并且应用程序读取了请求正文之后,才会记录请求正文。

票数 4
EN

Stack Overflow用户

发布于 2017-02-06 20:23:41

小请求的简单实现。请勿将其用于分块请求。

代码语言:javascript
运行
复制
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();
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6322362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档