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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24025924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:46:42  来源:igfitidea点击:

java.lang.IllegalStateException: No thread-bound request found, exception in aspect

javaspringspring-mvcaspectj

提问by riship89

Following is my aspect:

以下是我的方面:

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

I do not get any compile time errors but I do following exception when I start my jetty server:

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

nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

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

One thing to note here is, if I remove "logAroundService" method, I do not get any exceptions.

这里要注意的一件事是,如果我删除“logAroundService”方法,则不会出现任何异常。

采纳答案by M. Deinum

You shouldn't autowire a HttpServletRequestin your aspect as this will tie your aspect to be only runnable for classes that are called from within an executing HttpServletRequest.

你不应该HttpServletRequest在你的方面自动装配 a ,因为这会将你的方面绑定到只能对从执行中调用的类运行HttpServletRequest

Instead use the RequestContextHolderto get the request when you need one.

而是RequestContextHolder在需要时使用来获取请求。

private String getRemoteAddress() {
    RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
    if (attribs instanceof NativeWebRequest) {
        HttpServletRequest request = (HttpServletRequest) ((NativeWebRequest) attribs).getNativeRequest();
        return request.getRemoteAddr();
    }
    return null;
}

回答by Sotirios Delimanolis

With your pointcut expression, you're basically proxying every bean and applying that advice. Some beans exist and operate outside the context of an HttpServletRequest. This means it cannot be retrieved.

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

You can only inject the HttpServletRequestin places where a Servlet container request handling thread will pass through.

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

回答by Nicholas Lu

As the error message said: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

正如错误信息所说:在这种情况下,使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。

To fix it, register a RequestContextListener listener in web.xml file.

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

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

回答by user1686407

@M. Deinum answer doesn't work for me. I use these code instead

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

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

回答by Avijit Biswas

Create bean for RequestContextListener. I got the same error for autowiring HttpServletRequest And the following two lines of code works for me

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

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