使用jdbc出站通道适配器从xml负载插入记录
我们将JDBC出站通道适配器与insert查询语句一起使用。消息负载是XML。 我们希望从有效负载中提取某些元素,以便在insert语句中使用: 如何做到这一点 1-一种尝试是使用带有#xpath spEL函数的标头enricher(参见下面的代码)。但这导致了这一例外: org.springframework.expression.spel.SpelEvaluationException:EL1023E:(位置0):尝试调用函数“xpath”:“null”时出现问题。 你知道这里怎么了吗 2-如果可能的话,我希望避免同时使用头文件,而只是在 ExpressionEvaluationSqlParameterSourceFactorybean。这可能吗?如何实现 3-有没有关于实现这一目标的最佳方法的建议使用jdbc出站通道适配器从xml负载插入记录,jdbc,spring-integration,Jdbc,Spring Integration,我们将JDBC出站通道适配器与insert查询语句一起使用。消息负载是XML。 我们希望从有效负载中提取某些元素,以便在insert语句中使用: 如何做到这一点 1-一种尝试是使用带有#xpath spEL函数的标头enricher(参见下面的代码)。但这导致了这一例外: org.springframework.expression.spel.SpelEvaluationException:EL1023E:(位置0):尝试调用函数“xpath”:“null”时出现问题。 你知道这里怎么了吗 2-
<int-jdbc:outbound-channel-adapter
query="insert into foo(xmlElement1,xmlElement2, xmlMessage) values(:elementVal1,:elementVal2, :payload)"
data-source="dataSource"
sql-parameter-source-factory="spelSource"
channel="jdbcOutputChannel"/>
<bean id="spelSource" class="org.springframework.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
<property name="parameterExpressions">
<map>
<entry key="elementVal1" value="headers['elementVal1']"/>
<entry key="elementVal2" value="headers['elementVal2']"/>
</map>
</property>
</bean>
<int:header-enricher input-channel="jdbcOutputEnricherChannelPO" output-channel="jdbcOutputChannelPO">
<int:header name="elementVal1" expression="#xpath(payload, '/order/element1')"/>
<int:header name="elementVal2" expression="#xpath(payload, '/order/element2')"/>
</int:header-enricher>
谢谢你的支持 现在我们可以看到它告诉你:
Caused by: org.springframework.messaging.MessagingException: unsupported payload type [[B]
at org.springframework.integration.xml.DefaultXmlPayloadConverter.convertToDocument(DefaultXmlPayloadConverter.java:91)
at org.springframework.integration.xml.DefaultXmlPayloadConverter.convertToNode(DefaultXmlPayloadConverter.java:110)
at org.springframework.integration.xml.xpath.XPathUtils.evaluate(XPathUtils.java:93)
实际上,从XPathUtils
使用的DefaultXmlPayloadConverter
具有以下代码:
public Node convertToNode(Object object) {
Node node = null;
if (object instanceof Node) {
node = (Node) object;
}
else if (object instanceof DOMSource) {
node = ((DOMSource) object).getNode();
}
else {
node = convertToDocument(object);
}
return node;
}
其中convertToDocument(object)代码>类似于:
if (object instanceof Document) {
return (Document) object;
}
if (object instanceof Node) {
return nodeToDocument((Node) object);
}
else if (object instanceof DOMSource) {
Node node = ((DOMSource) object).getNode();
if (node instanceof Document) {
return (Document) node;
}
else {
return nodeToDocument(node);
}
}
if (object instanceof File) {
try {
return getDocumentBuilder().parse((File) object);
}
catch (Exception e) {
throw new MessagingException("failed to parse File payload '" + object + "'", e);
}
}
if (object instanceof String) {
try {
return getDocumentBuilder().parse(new InputSource(new StringReader((String) object)));
}
catch (Exception e) {
throw new MessagingException("failed to parse String payload '" + object + "'", e);
}
}
throw new MessagingException("unsupported payload type [" + object.getClass().getName() + "]");
用于xPath计算的字节[]
无效
因此,在调用存储过程之前,请确保您确实拥有正确的XML负载
是的:您不需要标题enricher
,只需要使用表达式EvaluationSqlParameterSourceFactory
定义中的任何SpEL表达式。请使用XML示例和异常的完整堆栈跟踪编辑您的问题。XML有效负载的源是入站HTTP网关,该网关设置为使用application/xml。因此,有效负载是字节[]。我求助于使用ServiceActivator将负载转换为字符串,并将其发送回JDBC出站适配器。有了它,我可以使用SpEL表达式expressionEvaluationSqlParameterSourceFactory定义。问题解决了。谢谢阿泰姆和加里,你的意见帮我找到了正确的方向。那很好。但是我向您展示了限制,您应该看到,byte[]
不会被接受,您应该将其转换为适合DefaultXmlPayloadConverter
的格式。我认为反对串变压器最适合您。尽管您可以使用DocumentBuilderFactory
直接将其转换为文档
:。OTOH不清楚为什么不能从入站HTTP网关
返回比原始字节[]
更有用的内容……哦,是的。这就是我一直在寻找的。我之前试过一个普通的变压器。我的搜索并没有导致我反对串联变压器。我喜欢这个框架的另一个原因是:)没有编码。很高兴听到这个消息。但我仍然认为您可以从HTTP网关返回一些有意义的内容。它完全基于Spring MVC,因此您可以配置例如request payload type=“javax.xml.transform.dom.DOMSource”
,适当的SourceHttpMessageConverter
将为您提供一个实例作为下游流的有效负载。摆脱了变压器。我使用的是请求有效负载类型。这太棒了。谢谢
public Node convertToNode(Object object) {
Node node = null;
if (object instanceof Node) {
node = (Node) object;
}
else if (object instanceof DOMSource) {
node = ((DOMSource) object).getNode();
}
else {
node = convertToDocument(object);
}
return node;
}
if (object instanceof Document) {
return (Document) object;
}
if (object instanceof Node) {
return nodeToDocument((Node) object);
}
else if (object instanceof DOMSource) {
Node node = ((DOMSource) object).getNode();
if (node instanceof Document) {
return (Document) node;
}
else {
return nodeToDocument(node);
}
}
if (object instanceof File) {
try {
return getDocumentBuilder().parse((File) object);
}
catch (Exception e) {
throw new MessagingException("failed to parse File payload '" + object + "'", e);
}
}
if (object instanceof String) {
try {
return getDocumentBuilder().parse(new InputSource(new StringReader((String) object)));
}
catch (Exception e) {
throw new MessagingException("failed to parse String payload '" + object + "'", e);
}
}
throw new MessagingException("unsupported payload type [" + object.getClass().getName() + "]");