【问题标题】:Grails Message source bug in Service服务中的 Grails 消息源错误
【发布时间】:2021-06-27 17:35:16
【问题描述】:

我在 Grails 3.3.11 中遇到了一点问题,我需要帮助。

我正在 grails 3.3.11 中开发一个 rest-api,但我不能在服务中使用 i18n 的消息源。它只适用于我的控制器。

message = messageSource.getMessage('documentProperties.notFound', [partId,jsonRequestDoc.get("typeId")] as Object[], LocaleContextHolder.locale)

当我在上面执行此操作时,我会在服务中收到它。

Cannot invoke method getMessage() on null object

我的 messageSource 在我的服务类的开头定义如下:

 @Autowired
 def messageSource

为了解决这个问题,我手动创建了一个从控制器接收消息源的服务构造函数。

class CmbIdService {
 public CmbIdService(def messageSource){
        this.messageSource = messageSource
    }
}

It was working as expected, but when I started running my integration tests, I noticed that Grails did not know how to instantiate my service considering the presence of the constructor. This the message I receive when I run the Grails Integration tests.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cmbIdService': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'java.lang.Object' available: more than one 'primary' bean found among candidates... continue.

谁能帮帮我。我不知道该怎么办。我需要使用消息源进行国际化。我需要在服务中做到这一点,而不仅仅是在控制器中。我的测试需要继续进行。

谢谢!

阿尔弗雷多

【问题讨论】:

    标签: rest grails service


    【解决方案1】:

    而不是这个...

    class CmbIdService {
     public CmbIdService(def messageSource){
            this.messageSource = messageSource
        }
    }
    

    这样做...

    class CmbIdService {
        def messageSource
    }
    

    如果该类是在grails-app/services/[whatever your package is]/CmbIdService.groovy 中定义的,那么将自动为您创建一个实例,将其作为 bean 添加到应用程序上下文中,并且该实例将受到 autowire-by-name 的约束。

    编辑

    以下评论表明 OP 仍在获得 NPE。我在https://github.com/jeffbrown/dnunesmessagesource 提供了一个工作示例。

    https://github.com/jeffbrown/dnunesmessagesource/blob/d05fe05a6679351fd5ff6779aebf30b6e6f3790d/grails-app/services/dnunesmessagesource/CmbIdService.groovy

    package dnunesmessagesource
    
    import org.springframework.context.i18n.LocaleContextHolder
    
    class CmbIdService {
        def messageSource
    
        String getCustomMessage() {
            messageSource.getMessage('my.custom.message', [] as Object[], LocaleContextHolder.locale)
        }
    }
    

    https://github.com/jeffbrown/dnunesmessagesource/blob/d05fe05a6679351fd5ff6779aebf30b6e6f3790d/grails-app/controllers/dnunesmessagesource/DemoController.groovy

    package dnunesmessagesource
    
    
    class DemoController {
        CmbIdService cmbIdService
        
        def index() {
            String message = cmbIdService.customMessage
            [customMessage: message]
        }
    }
    

    https://github.com/jeffbrown/dnunesmessagesource/blob/d05fe05a6679351fd5ff6779aebf30b6e6f3790d/grails-app/i18n/dnunes.properties

    my.custom.message=This Is My Custom Message
    

    https://github.com/jeffbrown/dnunesmessagesource/blob/d05fe05a6679351fd5ff6779aebf30b6e6f3790d/grails-app/views/demo/index.gson

    model {
        String customMessage
    }
    
    json {
        message customMessage
    }
    

    这一切似乎都按设计工作。

    $ http :8080/demo
    HTTP/1.1 200 
    Content-Language: en-US
    Content-Type: application/json;charset=UTF-8
    Date: Wed, 31 Mar 2021 18:31:37 GMT
    Transfer-Encoding: chunked
    X-Application-Context: application:development
    
    {
        "message": "This Is My Custom Message"
    }
    

    【讨论】:

    • 当我运行应用程序并请求端点时它不起作用。
    • 无法在空对象上调用方法 getMessage()
    • “无法在空对象上调用 getMessage() 方法” - 您是否正在使用 new CmbIdService() 创建 CmbIdService 的实例?
    • 是的,我是。 new CmbIdService().saveDocument(params.partId,jsonRequestDoc)
    • “是的,我是。new CmbIdService()”——这就是问题所在。您不应该自己创建该类的实例。如果你这样做,它将不会受到依赖注入,这就是你得到NullPointerException的原因。让 DI 容器为您注入实例,就像我创建的示例一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2014-01-29
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多