如何将SyndEntryImpl转为JSON并通过Spring Integration发送至ActiveMQ
我配置了Spring Integration来拉取Stack Overflow的Feed,然后转换为JSON发送到ActiveMQ,但当前生成的JSON是硬编码的字符串值,不是从Feed条目中提取的实际内容。
我的Spring Integration配置:
<int-feed:inbound-channel-adapter id="feedAdapter" channel="feedChannel" auto-startup="true" url="https://stackoverflow.com/feeds/question/49479712"> <int:poller fixed-rate="10000" max-messages-per-poll="100"/> </int-feed:inbound-channel-adapter> <int:channel id="feedChannel"/> <int:chain input-channel="feedChannel" output-channel="feedOutputChannel"> <int:transformer id="transformer" expression="@confbean"/> <int:object-to-json-transformer/> </int:chain> <bean id="confbean" class="com.xml.urlfeed.Feed"> <property name="title" value="payload.title" /> <property name="author" value="payload.author" /> </bean> <int:channel id="feedOutputChannel"/> <jms:outbound-channel-adapter id="jmsOutGateway" channel="feedOutputChannel" destination="inputQueue"/>
Feed类代码:
public class Feed { private String title; private String author; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }
Feed条目示例:
SyndEntryImpl.title=Test123 SyndEntryImpl.authors[0].name=Quentin
当前生成的JSON是:{"title":"payload.title","author":"payload.author"},但我期望的是:{"title":"Test123","author":"Quentin"}。请问如何正确从SyndEntryImpl提取字段,并后续能消费JSON转换为Feed对象?
解决方案
你的问题核心在于:当前的transformer只是直接返回了confbean这个单例Bean实例,而这个Bean的属性是硬编码的字符串"payload.title"和"payload.author",并没有动态从每个消息的payload(也就是SyndEntryImpl对象)中提取实际值。下面提供几种简单有效的修改方式:
方式一:用SpEL表达式直接构造Feed对象(无需修改Feed类)
修改transformer的表达式,直接通过SpEL从payload中提取字段并创建Feed实例:
<int:chain input-channel="feedChannel" output-channel="feedOutputChannel"> <!-- 直接用SpEL构造Feed并赋值 --> <int:transformer expression="new com.xml.urlfeed.Feed() {{ setTitle(payload.title); setAuthor(payload.authors[0].name); }}"/> <int:object-to-json-transformer/> </int:chain>
这样每个消息都会根据当前的SyndEntryImpl payload生成对应的Feed对象,再转换为正确的JSON。
方式二:给Feed类添加转换方法(更优雅,便于维护)
在Feed类中添加一个静态方法,专门处理从SyndEntryImpl到Feed的转换:
public class Feed { private String title; private String author; // 原有的getter和setter // 添加转换方法,同时处理空指针风险 public static Feed fromSyndEntry(SyndEntryImpl entry) { Feed feed = new Feed(); feed.setTitle(entry.getTitle()); if (entry.getAuthors() != null && !entry.getAuthors().isEmpty()) { feed.setAuthor(entry.getAuthors().get(0).getName()); } return feed; } }
然后修改transformer,调用这个静态方法:
<int:chain input-channel="feedChannel" output-channel="feedOutputChannel"> <int:transformer expression="T(com.xml.urlfeed.Feed).fromSyndEntry(payload)"/> <int:object-to-json-transformer/> </int:chain>
这种方式把转换逻辑封装在实体类中,代码更清晰,也方便后续扩展字段。
方式三:使用自定义Transformer组件
如果你需要更复杂的转换逻辑,可以创建一个专门的Transformer类:
@Component public class FeedTransformer { public Feed transform(SyndEntryImpl entry) { Feed feed = new Feed(); feed.setTitle(entry.getTitle()); if (entry.getAuthors() != null && !entry.getAuthors().isEmpty()) { feed.setAuthor(entry.getAuthors().get(0).getName()); } return feed; } }
然后在配置中引用这个组件:
<int:chain input-channel="feedChannel" output-channel="feedOutputChannel"> <int:transformer ref="feedTransformer" method="transform"/> <int:object-to-json-transformer/> </int:chain>
后续消费JSON转换为Feed对象
当你从ActiveMQ消费消息时,可以使用Spring Integration的json-to-object-transformer把JSON转换回Feed对象:
<int:channel id="jmsInputChannel"/> <jms:inbound-channel-adapter channel="jmsInputChannel" destination="inputQueue"/> <int:chain input-channel="jmsInputChannel"> <int:json-to-object-transformer type="com.xml.urlfeed.Feed"/> <!-- 后续处理逻辑,比如调用业务方法 --> <int:service-activator ref="yourService" method="handleFeed"/> </int:chain>
内容的提问来源于stack exchange,提问作者uyuola

