以下是我的方面:
@Configurable
@Aspect
public class TimingAspect {
@Autowired
private HttpServletRequest httpServletRequest;
// Generic performance logger for any mothod
private Object logPerfomanceInfo(ProceedingJoinPoint joinPoint, String remoteAddress) {
StringBuilder tag = new StringBuilder();
if (joinPoint.getTarget() != null) {
tag.append(joinPoint.getTarget().getClass().getName());
tag.append(".");
}
tag.append(joinPoint.getSignature().getName());
StopWatch stopWatch = new StopWatch(tag.toString());
Object result = joinPoint.proceed(); // continue on the intercepted method
stopWatch.stop();
PerformanceUtils.logInPerf4jFormat(stopWatch.getStartTime(), stopWatch.getElapsedTime(), stopWatch.getTag(), stopWatch.getMessage(), remoteAddress);
return result;
}
@Around("execution(* $$$.$$$.$$$.api.controller.*.*(..))")
public Object logAroundApis(ProceedingJoinPoint joinPoint) throws Throwable {
String remoteAddress = null;
if (httpServletRequest != null) {
remoteAddress = httpServletRequest.getRemoteAddr();
}
return logPerfomanceInfo(joinPoint, remoteAddress);
}
@Around("execution(* $$$.$$$.$$$.$$$.$$$.$$$.*(..))")
public Object logAroundService(ProceedingJoinPoint joinPoint) throws Throwable {
String remoteAddress = null;
if (httpServletRequest != null) {
remoteAddress = httpServletRequest.getRemoteAddr();
}
return logPerfomanceInfo(joinPoint, remoteAddress);
}
我没有得到任何编译时错误,但是当我启动我的jetty服务器时,我做了以下异常:
嵌套异常是java.lang.IllegalStateException:没有线程绑定 发现的请求:你指的是一个以外的请求属性 实际的Web请求,或处理原始的请求 接收线程?如果您实际在Web请求中操作 并且仍然收到此消息,您的代码可能正在外面运行 DispatcherServlet / DispatcherPortlet:在这种情况下,请使用 RequestContextListener或RequestContextFilter公开当前 请求。
这里要注意的一件事是,如果我删除" logAroundService"方法,我没有任何例外。
答案 0 :(得分:14)
您不应该在自己的方面自动装配HttpServletRequest
因为这会使您的方面仅对在执行HttpServletRequest
内调用的类可以运行。
而是在需要时使用RequestContextHolder
来获取请求。
private String getRemoteAddress() {
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (attribs instanceof NativeWebRequest) {
HttpServletRequest request = (HttpServletRequest) ((NativeWebRequest) attribs).getNativeRequest();
return request.getRemoteAddr();
}
return null;
}
答案 1 :(得分:7)
@M。 Deinum的回答对我不起作用。我改用这些代码
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (RequestContextHolder.getRequestAttributes() != null) {
HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
return request.getRemoteAddr();
}
答案 2 :(得分:6)
正如错误消息所述:在这种情况下,使用RequestContextListener或RequestContextFilter来公开当前请求。
要修复它,请在web.xml文件中注册一个RequestContextListener侦听器。
<web-app ...>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
</web-app>
答案 3 :(得分:2)
为RequestContextListener创建bean。 我在自动装配HttpServletRequest时遇到了相同的错误,以下两行代码对我有用
@Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
答案 4 :(得分:0)
使用切入点表达式,您基本上代理每个bean并应用该建议。有些bean存在并在HttpServletRequest
的上下文之外运行。这意味着无法检索它。
您只能在Servlet容器请求处理线程将通过的位置注入HttpServletRequest
。
答案 5 :(得分:0)
如果您来到这里是因为您在 2021 年左右或之后从 Internet 搜索了错误消息……我也这样做了,并最终意识到我有两个 @Configuration
类实现了 WebMvcConfigurer
。删除重复项解决了问题。