No thread-bound request found: Are you referring to request attributes outside of an actual web requ 淩亂°似流年 2021-06-22 15:38 2694阅读 0赞 今天收到一个bug,乍一看是个陌生面孔。 #### 报错信息 #### 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. 看了一下是在spring-web中RequestContextHolder.currentRequestAttributes方法抛出来的。 /** * Return the RequestAttributes currently bound to the thread. * <p>Exposes the previously bound RequestAttributes instance, if any. * Falls back to the current JSF FacesContext, if any. * @return the RequestAttributes currently bound to the thread * @throws IllegalStateException if no RequestAttributes object * is bound to the current thread * @see #setRequestAttributes * @see ServletRequestAttributes * @see FacesRequestAttributes * @see javax.faces.context.FacesContext#getCurrentInstance() */ public static RequestAttributes currentRequestAttributes() throws IllegalStateException { RequestAttributes attributes = getRequestAttributes(); if (attributes == null) { if (jsfPresent) { attributes = FacesRequestAttributesFactory.getFacesRequestAttributes(); } if (attributes == null) { throw new 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."); } } return attributes; } 看了方法注释说,如果当前线程没有绑定请求request的属性,就会报这个错。 #### 问题排查 #### 可是我们有用到HttpServletRequest相关的属性,怎么会报这个错呢? 最终发现,我们私库里的代码,根据国际化获取提示信息的一段。 /** * 获取国际化消息. * * @param code * 代码 * @param args * 参数 * @return 国际化消息 */ public String getMessage(String code, Object... args) { Locale locale = localeResolver.resolveLocale(WebUtil.getRequest()); return messageSource.getMessage(code, args, locale); } 其中WebUtil.getRequest()就是获取这个RequestAttributes的方法。 /** * Gets the request. * * @return the request */ public static HttpServletRequest getRequest() { ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); return attr.getRequest(); } 发现问题所在了。 #### 问题分析 #### 在之前的方法调用的没有发现这个问题,原因是请求中会包含HttpServletRequest对象,不会报错。而我这次的调用是将流程移到异步线程中执行,中途丢失了HttpServletRequest对象,所以就获取不到,报这个错。 #### 解决方法 #### 本次我是直接调了另外一个方法,跳过了获取Locale的步骤。 /** * 获取国际化消息. * @param code 代码 * @param args 参数 * @return 国际化消息 */ public String getMessageWithDefaultLocale(String code, Object... args) { return messageSource.getMessage(code, args, Locale.SIMPLIFIED_CHINESE); } 另外就需要考虑将HttpServletRequest对象设置到异步线程池的线程中。
还没有评论,来说两句吧...