Java 从Spring拦截器打印HTTP时,HTTP状态(0)错误-应用程序在独立TOMCAT中部署为WAR时
我想使用拦截器将HTTP请求记录到RESTful web服务。我使用SpringBoot,版本1.1.5.0 这是我的拦截器:Java 从Spring拦截器打印HTTP时,HTTP状态(0)错误-应用程序在独立TOMCAT中部署为WAR时,java,spring,rest,interceptor,spring-boot,Java,Spring,Rest,Interceptor,Spring Boot,我想使用拦截器将HTTP请求记录到RESTful web服务。我使用SpringBoot,版本1.1.5.0 这是我的拦截器: import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.serv
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler;
public class WebRequestsInterceptor extends HandlerInterceptorAdapter {
private static final Logger logger = LoggerFactory
.getLogger(WebRequestsInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime;
logger.info(request.getMethod() + " " + request.getRequestURL() + "?"
+ request.getQueryString() + " Http Status "
+ response.getStatus() + " elapsed time : " + executeTime
+ "ms");
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new WebRequestsInterceptor());
}
}
添加拦截器的类:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler;
public class WebRequestsInterceptor extends HandlerInterceptorAdapter {
private static final Logger logger = LoggerFactory
.getLogger(WebRequestsInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime;
logger.info(request.getMethod() + " " + request.getRequestURL() + "?"
+ request.getQueryString() + " Http Status "
+ response.getStatus() + " elapsed time : " + executeTime
+ "ms");
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new WebRequestsInterceptor());
}
}
我遇到的问题是,当我在独立的Tomcat(7.0.50版)中部署打包为war的应用程序时,我尝试记录的HTTP状态始终为0。当我使用嵌入式tomcat(由spring boot提供)运行应用程序时,HTTP状态是正确的
在调试模式下,当我检查响应时,我可以看到错误以某种方式发生:org.springframework.boot.context.web.ErrorPageFilter$ErrorWrapperResponse@4456be6c事实上,状态是0
最后,我不得不使用方面来记录对我的web服务的访问,但是拦截器方法也应该起作用
有人遇到过同样的问题吗?多谢各位
编辑
一个虚拟rest控制器,我想截获它的请求:
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello-world")
public class HelloWorldController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody
ResponseEntity<Greeting> sayHello(
@RequestParam(value = "name", required = false, defaultValue = "Stranger")
String name) {
switch (name) {
case "test":
return new ResponseEntity<>(new Greeting(counter.incrementAndGet(),
String.format(template, name)), HttpStatus.FORBIDDEN);
case "name":
return new ResponseEntity<>(new Greeting(counter.incrementAndGet(),
String.format(template, name)), HttpStatus.NOT_FOUND);
case "spring":
return new ResponseEntity<>(new Greeting(counter.incrementAndGet(),
String.format(template, name)), HttpStatus.OK);
default:
return new ResponseEntity<>(new Greeting(counter.incrementAndGet(),
String.format(template, name)), HttpStatus.BAD_REQUEST);
}
}
}
import java.util.concurrent.AtomicLong;
导入org.springframework.http.HttpStatus;
导入org.springframework.http.ResponseEntity;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RequestMethod;
导入org.springframework.web.bind.annotation.RequestParam;
导入org.springframework.web.bind.annotation.ResponseBody;
导入org.springframework.web.bind.annotation.RestController;
@RestController
@请求映射(“/hello world”)
公共类HelloWorldController{
私有静态最终字符串模板=“您好,%s!”;
私有最终AtomicLong计数器=新的AtomicLong();
@RequestMapping(method=RequestMethod.GET)
公共@ResponseBody
回答说你好(
@RequestParam(value=“name”,required=false,defaultValue=“陌生人”)
字符串名称){
交换机(名称){
案例“测试”:
返回新的ResponseEntity(新问候语)(counter.incrementAndGet(),
String.format(模板,名称)),HttpStatus.FORBIDDEN);
案例“名称”:
返回新的ResponseEntity(新问候语)(counter.incrementAndGet(),
String.format(模板,名称)),HttpStatus.NOT_FOUND);
案例“弹簧”:
返回新的ResponseEntity(新问候语)(counter.incrementAndGet(),
格式(模板,名称)),HttpStatus.OK);
违约:
返回新的ResponseEntity(新问候语)(counter.incrementAndGet(),
String.format(模板,名称)),HttpStatus.BAD_请求);
}
}
}
已在此处修复:(即将在1.1.6中)此信息也已存在于从DispatcherServlet发出的事件中。您可以创建ApplicationListener
并侦听ServletRequestHandledEvent
事件。虽然这不会给你状态码(只有成功或失败)。我也建议这样做,因为这对我来说似乎是一个错误/副作用。嗨,玛丽亚,我也面临着同样的问题。我已经向spring注册了这个问题。如果你有其他选择,请告诉我。我使用的是spring boot 1.1.10和Jetty 8.1.16Hi Dave。我已经升级了我的应用程序,以便它使用新版本的SpringBoot(1.1.6),并测试了WebRequestInterceptor。现在状态是200还是400,成功还是失败,但这不是我所期望的。当使用嵌入式Tomcat运行应用程序时,我可以根据对服务的请求看到正确的状态,但是当我在独立的Tomcat中部署应用程序时,我得到的是200而不是403。为什么执行应用程序的两种方式的行为不同?我如何解决这个状态问题?非常感谢。它对我很有用(例如,我从一个安全的应用程序中获得了401)。你能分享你的项目和一些复制的步骤吗?当你在独立的Tomcat中部署war时,它对你有用吗?因为这对我不起作用的时候就是这样。使用嵌入式Tomcat运行应用程序时一切正常。我无法共享该项目,而且两个类(拦截器和注册它的类)都没有更改。请尝试使用最新的快照。如果这不起作用,你需要解决如何共享一些代码。无论如何,我对2到3门课都不感兴趣,所以你可以不用透露任何秘密。