spring 集成 spel 表达式以从消息负载中提取字段
spring integration spel expression to extract fields from message payload
无法理解消息负载的 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?
首先,当您对对象具有完全访问权限时,不清楚为什么要在代码中手动使用 SpEL。另外,您应该记住,创建 StandardEvaluationContext
、解析表达式并在每次调用时对其进行求值是一种性能开销。您可能只需要更改 generateCardData()
签名以接受表达式的结果而不是整个地图。请参阅 @Payload.expression
属性。
无论如何,对于您的问题,这不是您想听到的。它在这里:
getValue(evaluationContext, payload, String.class)))
。根评估对象是您的 payload
- a Map
。因此,您只需要在表达式定义中假设您可以访问该根对象。因此表达式必须是这样的:fields.summary
、description
、key
.
您通常会在文档和示例中看到 payload
(或 header
)作为表达式中的第一个标记。那只是因为 Spring Integration 使用 Message
作为表达式计算的根对象。
现在关于性能。即使您的逻辑在运行时通过某个键 select 表达式 (issueDataMap.get(key)
),您仍然只能解析一次。
无法理解消息负载的 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?
首先,当您对对象具有完全访问权限时,不清楚为什么要在代码中手动使用 SpEL。另外,您应该记住,创建 StandardEvaluationContext
、解析表达式并在每次调用时对其进行求值是一种性能开销。您可能只需要更改 generateCardData()
签名以接受表达式的结果而不是整个地图。请参阅 @Payload.expression
属性。
无论如何,对于您的问题,这不是您想听到的。它在这里:
getValue(evaluationContext, payload, String.class)))
。根评估对象是您的 payload
- a Map
。因此,您只需要在表达式定义中假设您可以访问该根对象。因此表达式必须是这样的:fields.summary
、description
、key
.
您通常会在文档和示例中看到 payload
(或 header
)作为表达式中的第一个标记。那只是因为 Spring Integration 使用 Message
作为表达式计算的根对象。
现在关于性能。即使您的逻辑在运行时通过某个键 select 表达式 (issueDataMap.get(key)
),您仍然只能解析一次。