【问题标题】:Grails No thread-bound request found when accessing request/session from threadGrails 从线程访问请求/会话时未找到线程绑定请求
【发布时间】:2017-11-04 12:54:42
【问题描述】:

我正在使用 Grails 2.5.6。

我有一个以前连续执行的任务列表,需要引用我在会话中拥有的“lang”属性。

现在我从控制器调用一个创建线程的类,每个任务一个线程来加速执行。添加线程后,当代码尝试访问会话时开始出现此错误:

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

我认为需要在我创建的线程中设置一些东西才能访问请求/会话,但找不到任何文档。

会话的访问方式是:

RequestContextHolder.currentRequestAttributes().session.lang

在添加线程之前这工作正常。

有什么想法可以让那行代码在新线程上工作吗?

顺便说一句,我尝试了两种创建线程的方法,经典的 Thread.start/treads*.join() 和使用 grails.async.Promises (http://docs.grails.org/2.5.6/guide/async.html)。在两者上我都会收到相同的错误消息。

【问题讨论】:

  • stackoverflow.com/questions/43250539/… 但根据下面可能需要克隆参数或 properties.collect{it} 所以你将它捕获为一个新列表并尝试将元素存储在一个新的平面地图中通过这个过程发送它 - 听起来快速或懒惰的方式有时会咬人 - 如果只有 session.lang 为什么不抓住它并让它 map.something=params.lang 或 session.lang 就是我的意思

标签: multithreading session grails


【解决方案1】:

params 对象从控制器传递到线程 run() 方法时,我也遇到了同样的问题, 像params、request和response这样的对象,当我们将它们传递给线程时,它们没有更长的引用,所以我们需要将它保存在另一个变量中,我做了如下,

def  paramsData = params // you can declare other objects like request and eesponse 

现在您可以将变量 paramsData 传递给您的线程。

您可以尝试在 web.xml 中添加 requestContext 侦听器并按如下方式重置应用程序,

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

【讨论】:

  • 问题是使用请求的类不是直接在线程中,而是用作类,由从线程调用的类使用。我看到的唯一选择是更改所有方法以通过会话,这是我真的不喜欢的解决方案。 IMO 应该有某种方法可以将请求实际绑定到线程,但它没有记录在 Grails 文档中,也无法在 Spring 文档中找到。
  • 您是否尝试在 web.xml 中添加 requestContext Lister?
  • 我也尝试了很多解决方案,但对我没有任何效果,最后我做了上述方法,这对我来说真的很有效!问题是我们需要暴露请求对象的范围,比如 Thread 类。
  • 我没有,你有关于应该如何做的样本吗?谢谢!
  • 只需在一个变量中获取您传递给线程的任何数据,该变量可以是 Map 类型,也可以只是在您的控制器或类中定义,正如我在回答中解释的那样,并将该新变量传递给线程,这将具有在线程中使用的范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-12
  • 2019-01-02
  • 1970-01-01
  • 2014-07-24
  • 2011-12-22
相关资源
最近更新 更多