EalenXie / aop-log

项目正式命名为aop-log,基于Spring AOP,ThreadLocal实现方法埋点信息收集与处理。
Apache License 2.0
116 stars 54 forks source link

解决No thread-bound request found: Are you referring to request attributes outside of an actual web request #16

Closed wjw465150 closed 2 years ago

wjw465150 commented 2 years ago

DataExtractor代码的getRequest()方法中 在其中使用RequestContextHolder来获取request信息,发现异步调用时,主线程结束后,子线程就获取不到request,会报以上错误信息。 """" com.fasterxml.jackson.databind.JsonMappingException: 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: In this case, use RequestContextListener or RequestContextFilter to expose the current request. (through reference chain: com.github.LogData["args"]->com.google.gson.internal.LinkedTreeMap[3]->com.google.gson.internal.LinkedTreeMap["request"]->com.sun.proxy.$Proxy163["secure"]) """" 解决办法是: .在开启新线程之前,将servletRequestAttributes设置为子线程共享

/**
 * 获取HttpServletRequest对象
 *
 * @return HttpServletRequest
 */
public static HttpServletRequest getRequest() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    RequestContextHolder.setRequestAttributes(attributes,true);//设置子线程共享

    return attributes != null ? attributes.getRequest() : null;
}
wjw465150 commented 2 years ago
/**
 * 获取HttpServletRequest对象
 *
 * @return HttpServletRequest
 */
public static HttpServletRequest getRequest() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    RequestContextHolder.setRequestAttributes(attributes,true);//设置子线程共享

    return attributes != null ? attributes.getRequest() : null;
}

/**
 * 获取HttpServletResponse对象
 *
 * @return HttpServletResponse
 */
public static HttpServletResponse getResponse() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    RequestContextHolder.setRequestAttributes(attributes,true);//设置子线程共享

    return attributes != null ? attributes.getResponse() : null;
}
EalenXie commented 2 years ago

是在什么样的使用场景下导致这个问题的呢?

wjw465150 commented 2 years ago

aop-log默认的是使用异步来处理收集的数据,异步子线程还没开始,主线程可能就结束了的情况下.还有异步线程池你是写死了最大,最小数的,我进行了扩展可以在属性文件里来配置.

EalenXie commented 2 years ago

aop-log默认的是使用异步来处理收集的数据,异步子线程还没开始,主线程可能就结束了的情况下.还有异步线程池你是写死了最大,最小数的,我进行了扩展可以在属性文件里来配置.