java.lang.IllegalStateException:未找到线程绑定请求,方面有异常

时间:2014-06-03 22:18:51

标签: java spring spring-mvc aspectj

以下是我的方面:

    @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"方法,我没有任何例外。

6 个答案:

答案 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。删除重复项解决了问题。