【问题标题】:spring integration spel expression to extract fields from message payloadspring integration spel 表达式从消息有效负载中提取字段
【发布时间】:2021-01-23 07:45:03
【问题描述】:

对于消息有效负载,我无法理解 SPEL。我想从我的消息有效负载的某些字段中提取数据,这些字段本质上是将以下 JSON 转换为 Map<String, Object> 并传递给 @Transformer

{
  "expand":"renderedFields,names,schema,transitions,operations,editmeta,changelog,versionedRepresentations",
  "id":"14730",
  "self":"https://jira.foo.com/rest/api/2/issue/14730",
  "key":"SDP-145",
  "fields":{
    "issuetype":{
      "self":"https://jira.foo.com/rest/api/2/issuetype/10200",
      "id":"10200",
      "description":"gh.issue.epic.desc",
      "iconUrl":"https://jira.foo.com/ghanghor/viewkaka?size=xsmall&kakaId=10501&kakaType=issuetype",
      "name":"Epic",
      "subtask":false,
      "kakaId":10501
    },
    "priority":{
      "self":"https://jira.foo.com/rest/api/2/priority/3",
      "iconUrl":"https://jira.foo.com/images/icons/priorities/major.svg",
      "name":"Major",
      "id":"3"
    },
    "labels":[
      "Lizzy",
      "kanban",
      "rughani"
    ],
    "updated":"2021-01-21T10:33:38.000+0000",
    "status":{
      "self":"https://jira.foo.com/rest/api/2/status/1",
      "description":"The issue is open and ready for the assignee to start work on it.",
      "iconUrl":"https://jira.foo.com/images/icons/statuses/open.png",
      "name":"Open",
      "id":"1",
      "statusCategory":{
        "self":"https://jira.foo.com/rest/api/2/statuscategory/2",
        "id":2,
        "key":"new",
        "colorName":"blue-gray",
        "name":"To Do"
      }
    },
    "summary":"new epic for Tazzy",
    "creator":{
      "self":"https://jira.foo.com/rest/api/2/user?username=skadmin",
      "name":"skadmin",
      "key":"skadmin",
      "emailAddress":"Lizzy.t@foo.com",
      "displayName":"Lizzy Rughani",
      "active":true,
      "timeZone":"Asia/Kolkata"
    },
    "subtasks":[

    ],
  }
}

我对这里的三个嵌套值感兴趣,我试图通过以下表达式获取它们

issueDataMap = {LinkedHashMap@4867}  size = 3
 "name" -> "#payload['fields']['summary']"
 "description" -> "#payload['description']"
 "text3" -> "#payload['key']"

应用表达式时出现此错误

org.springframework.expression.spel.SpelEvaluationException: EL1012E: Cannot index into a null value

这是我如何在我的转换器的 as 参数中获取有效负载

@Transformer
public Map<String, Object> generateCardData(Map<String, Object> payload,
                                            @Header("X-UPSTREAM-WEBHOOK-SOURCE") String projectId) {

紧随其后

StandardEvaluationContext evaluationContext = evaluationContextFactory.getObject();

我是这样评价的

new SpelExpressionParser().parseExpression(issueDataMap.get(key)).getValue(
                            evaluationContext, payload, String.class)));

我有使用@SpringBootApplication@EnableInegration 注释的应用程序,并且我自动装配IntegrationEvaluationContextFactoryBean 的实例以获取StandardEvaluationContext

我也试过变种

issueDataMap = {LinkedHashMap@4867}  size = 3
 "name" -> "payload['fields']['summary']"
 "description" -> "payload['description']"
 "text3" -> "payload['key']"

然后我明白了

EL1008E: Property or field 'payload' cannot be found on object of type 'java.util.LinkedHashMap' - maybe not public or not valid?

【问题讨论】:

    标签: java spring-boot spring-integration spring-expression-language


    【解决方案1】:

    首先,当您拥有对对象的完全访问权限时,为什么要在代码中手动使用 SpEL 尚不清楚。另外,您应该记住,创建StandardEvaluationContext、解析表达式并在每次调用时对其进行评估对性能来说是一种开销。您可能只需要更改您的 generateCardData() 签名以接受表达式的结果而不是整个地图。请参阅@Payload.expression 属性。

    无论如何,对于您的问题,这不是您想听到的。它在这里: getValue(evaluationContext, payload, String.class)))。根评估对象是您的payload - Map。因此,您只需要在表达式定义中假设您可以访问该根对象。因此表达式必须是这样的:fields.summarydescriptionkey

    您通常会在文档中看到 payload(或 header)作为表达式中的第一个标记。这只是因为 Spring Integration 使用 Message 作为表达式求值的根对象。

    现在关于性能。即使您的逻辑是在运行时通过某个键选择表达式 (issueDataMap.get(key)),您仍然只能解析一次。

    【讨论】:

    • 虽然我理解您的担忧,但我无法添加注释的原因是因为负载会因不同类型的上游而异,现在我们要么在每次添加新上游时编写一个带有其注释的转换器并完成构建、测试、部署、发布周期或使其可配置。我会在任何一天运行时,以避免我必须添加到这个系统的每个上游的循环。
    • 明白。无论如何,issueDataMap 可以带有预解析的表达式。我的回答还有什么不清楚的地方吗?
    • 是的,我注意到,我会重构,回到原来的问题,很明显,我误解了表达语言。
    • 好,现在是时候赚取积分并让社区中的其他人知道这是一个答案:stackoverflow.com/help/someone-answers
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 2011-09-29
    • 1970-01-01
    • 2013-12-10
    • 2021-12-02
    • 1970-01-01
    相关资源
    最近更新 更多