Apache Camel Java 和 XPath
Posted
技术标签:
【中文标题】Apache Camel Java 和 XPath【英文标题】:Apache Camel Java and XPath 【发布时间】:2013-05-27 01:23:22 【问题描述】:所以我有一个带有多个命名空间的 Web 服务,我想通过一个 bean 进行路由以检查用户凭据。自从我使用 XPATH 以来已经有很长时间了,所以我可能只是遇到了 PICNIC(椅子上的问题不在计算机时刻)错误。
网络服务消息将始终具有以下结构/模式:
<Operation>
<header with the head name space where the user credentials are stored>
<record control>
<objXX>
</Operation>
这是一个示例消息(SOAP UI):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:list="http://www.insol.irix.com.au/IRIX_V1/Debtors/List" xmlns:head="http://www.insol.irix.com.au/IRIX_V1/Headers" xmlns:rec="http://www.insol.irix.com.au/IRIX_V1/RecordControl">
<soapenv:Header/>
<soapenv:Body>
<list:ListDebtorReq>
<head:MsgReqHdr>
<head:MsgGUID>$=java.util.UUID.randomUUID()</head:MsgGUID>
<head:MsgDateTime>$=javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar.getInstance())</head:MsgDateTime>
<head:ConsumerSystemIDInfo>
<head:ConsumerSystemID>ConsumerSystemID</head:ConsumerSystemID>
<head:ConsumerSystemUserID>AgentX</head:ConsumerSystemUserID>
</head:ConsumerSystemIDInfo>
<head:SecCredInfo>
<head:IRIXUserID>Some User ID</head:IRIXUserID>
<head:IRIXPassword>Some Password</head:IRIXPassword>
</head:SecCredInfo>
<head:CryptoInfo>
<head:DigitalSignatureInfo>
<head:DigitalSignatureValue>verrantque per auras</head:DigitalSignatureValue>
<head:DigitalSignatureAlgorithm>SHA-256</head:DigitalSignatureAlgorithm>
</head:DigitalSignatureInfo>
</head:CryptoInfo>
</head:MsgReqHdr>
<!--Optional:-->
<rec:RecCntrl>
<rec:StartRecordNumber>1</rec:StartRecordNumber>
<!--Optional:-->
<rec:NumberOfRecords>3</rec:NumberOfRecords>
</rec:RecCntrl>
</list:ListDebtorReq>
</soapenv:Body>
</soapenv:Envelope>
所以本质上我希望能够创建一个能够查询 MsgReq 标头以获取所有用户名和密码数据的 bean。为了简化事情,我只是想查询 MsgGUID 并从那里开始工作。但是我似乎无法正确使用 xpath。由于我使用了多个命名空间,因此我将它们包含在骆驼上下文文件中只是为了确保它们可用。
这是我的骆驼语境:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<import resource="classpath:META-INF/spring/camel-cxf.xml" />
<bean id="SecurityCheckBean" class="au.com.irix.insol.Security.IRIXSecurity"/>
<camelContext xmlns="http://camel.apache.org/schema/spring"
xmlns:list="http://www.insol.irix.com.au/IRIX_V1/Debtors/List"
xmlns:head="http://www.insol.irix.com.au/IRIX_V1/Headers"
xmlns:rec="http://www.insol.irix.com.au/IRIX_V1/RecordControl">
<route>
<from uri="cxf:bean:DebtorsService?dataFormat=PAYLOAD"/>
<bean ref="SecurityCheckBean"/>
</route>
</camelContext>
</beans>
如您所见,我正在将 Web 服务生产者的传入消息运行到 SecurityCheckBean。我的 SecurityCheckBean 目前非常简单,请参见下面的代码。
public class IRIXSecurity
public void CheckCredentials(
@XPath("//head:MsgGUID") String msgGUID,
@Body String body)
System.out.println(body);
System.out.println("Check Credentials Invoked");
System.out.println(msgGUID);
但是,当我通过soap UI 发送发送请求时,出现以下异常:
Invalid xpath: //head:MsgGUID. Reason: javax.xml.xpath.XPathExpressionException: net.sf.saxon.trans.XPathException: Prefix head has not been declared
那么我该如何检索这些信息呢?为什么即使我已经在我的 camel-context.xml 中声明了名称空间,它们仍被报告为缺失?
出于兴趣,我尝试了 XPATH 的几种变体,例如:
@XPath("//MsgGUID")
@XPath("//MsgReqHdr/head:MsgGUID")
@XPath("//head:MsgReqHdr/head:MsgGUID")
每当我得到上面列出的异常或 NULL 值时......
【问题讨论】:
【参考方案1】:正确的让它工作。在处理 bean 中的命名空间时,必须使用以下语法来包含命名空间。
public class IRIXSecurity
public void CheckCredentials(
//@Body ListDebtorReqType msgBody, @Headers Map hdr,
@XPath(value="//header:MsgGUID",namespaces = @NamespacePrefix(
prefix = "header",
uri = "http://www.insol.irix.com.au/IRIX_V1/Headers")) String msgGUID,
@Body Document xml)
System.out.println("Check Credentials Invoked");
System.out.println(msgGUID);
//exchange.getOut().setBody(debtorRsType);
【讨论】:
以上是关于Apache Camel Java 和 XPath的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 java.lang.NoClassDefFoundError: org/apache/camel/impl/DefaultComponent?
Payara中的Apache Camel:'java:/ TransactionManager'查找失败
如何读取HL7文件并使用Apache Camel,Hapi和Spring(Java配置)解析它