【问题标题】:java.lang.IllegalStateException: No thread-bound request found, exception in aspectjava.lang.IllegalStateException:未找到线程绑定请求,方面异常
【发布时间】:2014-07-24 10:10:20
【问题描述】:

以下是我的方面:

    @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);
        }

我没有收到任何编译时错误,但是当我启动我的码头服务器时出现以下异常:

嵌套异常是 java.lang.IllegalStateException: No thread-bound 找到请求:您是否指的是请求之外的属性 实际的 Web 请求,或处理原始请求之外的请求 接收线程?如果您实际上是在 Web 请求中操作 仍然收到此消息,您的代码可能在外面运行 DispatcherServlet/DispatcherPortlet:在这种情况下,使用 RequestContextListener 或 RequestContextFilter 暴露当前 请求。

这里要注意的一点是,如果我删除“logAroundService”方法,我不会得到任何异常。

【问题讨论】:

    标签: java spring spring-mvc aspectj


    【解决方案1】:

    如果您是因为在 2021 年左右或之后从 Internet 搜索错误消息而来到这里的……我也这样做了,最终意识到我有两个实现 WebMvcConfigurer@Configuration 类。删除副本解决了问题。

    【讨论】:

      【解决方案2】:

      为 RequestContextListener 创建 bean。 我在自动装配 HttpServletRequest 时遇到了同样的错误,以下两行代码对我有用

      @Bean
      public RequestContextListener requestContextListener() {
          return new RequestContextListener();
      }
      

      【讨论】:

      • 我遇到了同样的问题,这为我解决了这个问题。谢谢!
      【解决方案3】:

      @M。 Deinum 答案对我不起作用。我改用这些代码

      RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
      if (RequestContextHolder.getRequestAttributes() != null) {
          HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
          return request.getRemoteAddr();
      }
      

      【讨论】:

        【解决方案4】:

        您不应该在您的切面中自动装配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;
        }
        

        【讨论】:

        • 请将您的最终解决方案添加到您的问题中以供将来参考。
        • 记得在web.xml中添加如下监听器(否则attribs会为空):<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>
        【解决方案5】:

        如报错信息所说:这种情况下,使用RequestContextListener或者RequestContextFilter来暴露当前请求。

        要修复它,请在 web.xml 文件中注册一个 RequestContextListener 侦听器。

        <web-app ...>
           <listener>
            <listener-class>
                org.springframework.web.context.request.RequestContextListener
            </listener-class>
           </listener>
        </web-app>
        

        【讨论】:

        • 这适用于我在 weblogic 10.3.6 中使用相对较新版本的 spring boot (1.4)
        【解决方案6】:

        使用您的切入点表达式,您基本上是在代理每个 bean 并应用该建议。一些 bean 存在并在 HttpServletRequest 的上下文之外运行。这意味着它无法被检索。

        您只能在 Servlet 容器请求处理线程将通过的地方注入 HttpServletRequest

        【讨论】:

        • 所有切入点拦截的所有方法都在同一个servlet容器请求处理线程中调用。
        • 如果检索不出来,应该为null,为什么是非法状态?
        • @riship89 发布您的完整堆栈跟踪以证明这一点。另一种可能性是您的方面由ContextLoaderListener ApplicationContext 而不是DispatcherServlet 加载。
        • @riship89 使用@Autowired,您正在设置注入目标。你是说我希望这由 Spring 管理。好吧,在这种情况下,Spring 无法管理它,所以它崩溃了。
        • 好的,我现在明白了。我的许多 bean 都在应用程序上下文中,而不是在 servlet 上下文中。现在,如何在整个应用程序中公开 httpservlet 请求?
        猜你喜欢
        • 2020-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 2023-01-18
        相关资源
        最近更新 更多