1

Grails 2.4.5 を使用すると、次のサービスがあります。

class CartService {

    static scope = 'session'
    static proxy = true

    def items = []

    def getItemCount() {
        items.size()
    }

}

コントローラーでこのサービスを使用したい:

class CartController {

    def cartService // unique per session

    def addItem = {
        cartService.items << new CartItem(product: Product.get(params.id))
    }

}

Grails scoped-proxy pluginのバージョン 0.3 を試しました。しかし、次のエラーが表示されます。

Error creating bean with name 'cartService': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; 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.
    Line | Method
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run       in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'cartService': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; 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.
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run       in java.lang.Thread
Caused by 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.
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run       in java.lang.Thread

Grails コントローラーにセッション スコープを持つサービスを含めるにはどうすればよいですか?

4

1 に答える 1

0

Grails 2.4.x のプラグインで 1 つまたは 2 つの問題 (および報告) を見つけたようです。その場合は、プラグインの作成者によるブログ投稿を参照できます: Scoped Services & Proxies in Grails

そこで彼は、プラグインなしでそれを行う方法を示しています。試してみたところ、2.4.5 で動作します。

resources.groovy:

import org.springframework.aop.scope.ScopedProxyFactoryBean

beans = {
    cartServiceProxy(ScopedProxyFactoryBean) {
        targetBeanName = 'cartService'
        proxyTargetClass = true
    }
}

プロキシは手動で行うため、削除できますstatic proxy

class CartService {
    static scope = 'session'
    def items = []

    def getItemCount() {
        items.size()
    }
}

次に、コントローラーはプロキシを参照します

class CartController {
    def cartServiceProxy 
    ... 
}

混乱の 1 つのポイント (少なくとも私にとって) は、2.4.x のコントローラーのドキュメントではデフォルトのスコープprototypesingleton

お役に立てれば。

更新: 少し明確にするために、デフォルトのコントローラースコープはまだprototypeGrails 2.3 以降ですが、grails によって新しいアプリケーションが生成されると、デフォルトのコントローラースコープを設定する構成が生成されますsingleton(これは、Burt が以下で述べているように、可能であれば実際に撮影する必要があるものです) )。

Config.groovy で生成された構成

// The default scope for controllers. May be prototype, session or singleton.
// If unspecified, controllers are prototype scoped.
grails.controllers.defaultScope = 'singleton'
于 2015-08-30T15:11:23.217 に答える