【问题标题】:Grails 3 PluginDescriptor configurationGrails 3 PluginDescriptor 配置
【发布时间】:2020-07-08 06:31:43
【问题描述】:

我正在将现有的 Grails 2.5.6 项目转换为 Grails 3.3.11。

对于我现有的应用程序(Grails 2.5.6),插件描述符的代码如下:

def doWithApplicationContext = { applicationContext ->
    def config = applicationContext.grailsApplication.config
    def key = config.property.key
    key.put(Constants.RESULT_CONST, [controller: "results", action: "showData", templatePath: "/results/data"])
}

此代码适用于早期版本的 grails。但是在我升级到 grails 3.3.11 之后,它会抛出异常: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

这是在行:

key.put(Constants.RESULT_CONST, [controller: "results", action: "showData", templatePath: "/results/data"])

查看键的类型(即 config.property.key)后,它显示的类型为 org.grails.config.NavigableMap$NullSafeNavigator

旧版本是 LinkedHashMap。 property.key 在 /grails-app/conf/application.groovy 下的 application.groovy 上设置得很好 property.key = [:]

我还尝试在外部将插件描述符中的property.key 类型设置为java.util.HashMap。但是好像没有采用新的类型。

我在这里做错了什么?

【问题讨论】:

  • 您的目标仅仅是动态地将条目添加到应用程序的配置中吗?
  • 是的。根据规则添加条目。这些条目将从该插件和应用程序的其他部分引用。
  • resultsshowData 的值从何而来?
  • 对不起,它实际上是值而不是成员变量。更新问题...
  • 随着您对问题的最新更新,没有任何动态。这些值都是硬编码的,因此您可以消除所有这些代码并将配置设置放在插件的配置文件中。

标签: grails grails3 grails-3.3


【解决方案1】:

感谢@Jeff 的意见和建议。

这是用于设置配置参数并在控制器或任何其他 grails 组件中检索它们的统一代码。

插件描述符:

class ResultGrailsPlugin extends Plugin {
   void doWithApplicationContext() { 
      config.merge(['property': ['key': ["${Constants.RESULT_CONST}": [controller: "results", action: "showData", templatePath: "/results/data"]]]])
   }
}

控制器:

class ResultController {
   def index() {
      def resultConfigMap = grailsApplication.config.get('property.key.' + Constants.RESULT_CONST)
      ...
   }
}

【讨论】:

  • 那个控制器代码不是一个好主意。那是在请求处理期间检索配置值,这意味着它会一遍又一遍地发生。
  • 是的。这实际上仅用于表示目的。配置参数的实际使用将在服务中。
  • 如果您将该方法移动到在请求处理期间调用的服务中,您将遇到同样的问题。如果实际使用在服务中,为什么要显示控制器?
【解决方案2】:

而不是尝试通过以下方式动态执行此操作:

def doWithApplicationContext = { applicationContext ->
    def config = applicationContext.grailsApplication.config
    def key = config.property.key
    key.put(2, [controller: "results", action: "showData", templatePath: "/results/data"]) 
}

您可以像这样在grails-app/conf/plugin.yml 中定义这些值:

---
property:
  key:
    '2':
      controller: results
      action: showData
      templatePath: '/results/data`

编辑

问题已更改,以上内容不再有效。

不要这样做:

def config = applicationContext.grailsApplication.config
def key = config.property.key
key.put(Constants.RESULT_CONST, [controller: "results", action: "showData", templatePath: "/results/data"])

您可以将其简化为:

config.merge([property: [key: [Constants.RESULT_CONST, [controller: "results", action: "showData", templatePath: "/results/data"]]]])

【讨论】:

  • 使用config.merge,war 部署时不会出错。但是当我尝试从配置中访问值时,它不会将值设置为property.key。这是我尝试访问的方式:grailsApplication.config.property.key.get(Constants.RESULT_CONST); & grailsApplication.config.property.key.Constants.RESULT_CONST;。尝试从主 App 控制器(而不是插件控制器)访问。
  • 你不应该这样做grailsApplication.config.property.key.get(...)。请参阅guides.grails.org/grails-quickcasts-retrieving-config-values/… 的视频或objectcomputing.com/resources/publications/sett/… 的文章。
  • 谢谢@Jeff。此解决方案有效。已发布整合代码 sn-ps 以在下面设置和检索配置参数。
猜你喜欢
  • 2016-07-04
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 2017-01-15
  • 2017-12-02
  • 2017-07-21
  • 2016-06-25
  • 2016-06-27
相关资源
最近更新 更多