我在我的java webserver(实际上是appengine)中创建了一个过滤器,用于记录传入请求的参数.我还想记录我的网络服务器写的结果响应.虽然我可以访问响应对象,但我不确定如何从中获取实际的字符串/内容响应.
有任何想法吗?
我正在Spring 3.1上构建一个REST服务.我正在使用@EnableWebMVC注释.由于我的服务只接受JSON请求,我还想将传入的请求转储到MongoDB集合中以进行日志记录(以及稍后的数据转换).我想访问原始JSON请求(我可以使用"@Content HttpServletRequest请求"作为方法参数在非spring实现上执行).
我是一个春天的新手.所以,请帮助我指明实现这一目标.谢谢!
更新:问题没有完全解决.只有我在GET上的测试才有效.它失败了POST.因此,取消选中接受的答案
问题是,即使我创建了一个HttpServletRequestWrapper,我也无法在处理并包装请求后转发请求.这是发生的事情:
拦截器:
public class DBLogInterceptor extends HandlerInterceptorAdapter {
MyRequestWrapper requestWrapper;
private final static Logger logger = Logger.getLogger(DBLogInterceptor.class);
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception
{
requestWrapper = new MyRequestWrapper(request);
// Code removed, but it just dumps requestWrapper.getBody() into DB
return super.preHandle(requestWrapper, response, handler);
}
}
Run Code Online (Sandbox Code Playgroud)
HTTP POST服务方法
@RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
@ResponseBody
public String updateEntity(@RequestBody Employee emp) {
// Do some DB Stuff. Anyway, the control …Run Code Online (Sandbox Code Playgroud) 我是servlet的新手,并阅读有关过滤器和包装器的一些文本.我可以理解过滤器,但对包装器感到困惑.在书中,作者给出了一个例子:
如果没有包装:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
String name = request.getParameter("name").trim();
try {
chain.doFilter(request, response);
PrintWriter out = response.getWriter();
if (name.length() == 0) {
out.println("Some message");
out.println("</body>");
out.println("</html>");
out.close();
}
} catch (Throwable t) {
}
}
Run Code Online (Sandbox Code Playgroud)
如果是包装:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
String name = request.getParameter("name").trim();
HttpServletResponse httpRes = (HttpServletResponse) response;
HttpServletResponseWrapper resWrapper = new HttpServletResponseWrapper(httpRes);
try {
chain.doFilter(request, response);
PrintWriter out = resWrapper.getWriter(); // …Run Code Online (Sandbox Code Playgroud) 我目前正在使用Spring Boot将请求/响应日志记录集成到REST服务中。对于请求,我选择了Spring提供的CommonsRequestLoggingFilter:
@Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
loggingFilter.setIncludeClientInfo(false);
loggingFilter.setIncludeQueryString(true);
loggingFilter.setIncludePayload(true);
loggingFilter.setMaxPayloadLength(1024);
return loggingFilter;
}
Run Code Online (Sandbox Code Playgroud)
并在配置文件中:
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG
Run Code Online (Sandbox Code Playgroud)
但是,对于响应,似乎没有相应的课程?有没有类似的方式在Spring中记录服务器响应?
编辑:具体地说,我在以上设置中看到的内容在BeforeRequest中一无所有:
2017-06-28 09:32:32.258 DEBUG 22872 --- [http-nio-8081-exec-2] o.s.w.f.CommonsRequestLoggingFilter : Before request [uri=/someApp/someObject]
Run Code Online (Sandbox Code Playgroud)
请求有效载荷为AfterRequest:
2017-06-28 09:32:32.272 DEBUG 22872 --- [http-nio-8081-exec-2] o.s.w.f.CommonsRequestLoggingFilter :
After request [uri=/someApp/someResource;payload={
"someObject": {
"lastName": "Doe",
"reference": "123456789"
}
}
]
Run Code Online (Sandbox Code Playgroud)
实际的响应不在日志中。
HttpServletResponse由于两天后我仍然不知道如何在 中打印身体HandlerInterceptorAdapter,我会再问一次:)
HttpServletRequest我可以轻松地做类似的事情,并且request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));我有完整的身体,但如何做同样的事情HttpServletResponse?
我在 StackOverflow 上发现了很多关于此问题的问题,但似乎没有一个有效。
这是处理程序:
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
//how to print here the "response" by using the "response" parameter
super.afterCompletion(request, response, handler, ex);
}
Run Code Online (Sandbox Code Playgroud)
这个答案是完全相同的,并链接到这个,但他们使用ServletResponseand NOTHttpServletResponse以及FilterChain我的afterCompletion处理程序中没有的东西。即使这看起来最完整的一个也不适合(我认为)我的情况。
有人可以为我提供一个简单的序列化示例吗HttpServletResponse?
我有控制器将JSON返回给客户端.控制器方法使用mvc注释进行标记,例如:
@RequestMapping("/delete.me")
public @ResponseBody Map<String, Object> delete(HttpServletRequest request, @RequestParam("ids[]") Integer[] ids) {
Run Code Online (Sandbox Code Playgroud)
Spring知道返回JSON,因为Jackson在类路径上并且客户端正在请求JSON响应.我想记录这些请求和所有其他控制器的响应.在过去,我使用拦截器来做到这一点.但是,我从ModelAndView获得了响应主体.现在我正在使用@ResponseBody,如何在交织器中获取响应主体?具体来说,如何在此方法中获取响应主体?
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
Run Code Online (Sandbox Code Playgroud) 我试图在我的应用程序中记录每个传入请求和传出响应。我正在使用 jee 6,所以我没有 ContainerRequestFilter 和 ContainerResponseFilter 类。所以我决定使用过滤器。
我用 @WebFilter("/*") 注释了一个类并实现了 Filter 接口。我成功读取了请求标头和请求正文。有一些困难,我还阅读了响应标头和响应正文。下面是一个代码片段
MyHttpServletResponseWrapper wrapper = new MyHttpServletResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, wrapper);
Run Code Online (Sandbox Code Playgroud)
MyHttpServletResponseWrapper 类
public class MyHttpServletResponseWrapper extends HttpServletResponseWrapper {
private StringWriter sw = new StringWriter();
public MyHttpServletResponseWrapper(HttpServletResponse response) { super(response); }
public PrintWriter getWriter() { return new PrintWriter(sw); }
public ServletOutputStream getOutputStream() {
return new ServletOutputStream (){
public void write(int B) { sw.append((char) B); }
};
}
public String getCopy() { sw.toString(); }
}
Run Code Online (Sandbox Code Playgroud)
记录响应后,我将响应写回输出流,以便客户端可以接收响应。下面是代码
logResponse(wrapper);
response.getOutputStream().write(wrapper.getCopy().getBytes());
Run Code Online (Sandbox Code Playgroud)
我无法理解的是,如何在阅读后将请求正文放回输入流中。
在 Jersey 等标准 …
java ×5
servlets ×4
spring ×3
logging ×2
rest ×2
spring-mvc ×2
http ×1
httpresponse ×1
interceptor ×1
jakarta-ee ×1
java-ee-6 ×1
json ×1
wrapper ×1