当内容类型为 application/xml 时出现类中介错误

问题描述 投票:0回答:1

我收到错误:

ErrorCode = 0, ErrorMessage = Error occured in the mediation of the class mediator, 
ErrorDetail = org.apache.synapse.SynapseException: Error occured in the mediation of the class mediator

以下是我用于消费的代理服务:

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="UnicaProvConsumer" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
    <target>
        <inSequence>
            <sequence key="MainSequence"/>
        </inSequence>
        <outSequence/>
        <faultSequence>
            <sequence key="Hello"/>
        </faultSequence>
    </target>
    <parameter name="transport.jms.Destination">REQ</parameter>
    <parameter name="transport.jms.ContentType">application/xml</parameter>
    <parameter name="transport.jms.ConnectionFactory">Listener</parameter>
</proxy>

信息:如果内容类型设置为'text/xml',则效果很好。

<?xml version="1.0" encoding="UTF-8"?>
<sequence name="UnicaProvMainSequence" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
    <class description="UnicaProvSenderMediator" name="com.safaricom.mediator.UnicaProvSenderMediator"/>
</sequence>

有什么指导说明为什么会发生这种情况吗?

编辑:

以下是类代码供参考:

public class UnicaProvSenderMediator extends AbstractMediator implements ManagedLifecycle {

    private static final Logger logger = LogManager.getLogger(UnicaProvSenderMediator.class.getName());
    private static final Logger Errorlogger = LogManager.getLogger(ErrorHandling.class.getName());
    private static JDBCConnectionPool jdbcPool = new JDBCConnectionPool(Utility.getProperty(Constant.EAI_JDBC_DRIVER), Utility.getProperty(Constant.EAI_JDBC_STRING), Utility.getProperty(Constant.EAI_JDBC_USER_NAME), Utility.getProperty(Constant.EAI_JDBC_PASSWORD));

    static {
        System.setProperty("httpclient.hostnameVerifier", "AllowAll");
    }

    public boolean mediate(MessageContext context) {
        // TODO Implement your mediation logic here
        Connection connection = null;
        try {
            SOAPEnvelope envelope = context.getEnvelope();
            OMElement provNode = (OMElement) envelope.getBody().getFirstChildWithName(new QName("prov")).detach();
            String retryCount = (provNode.getFirstChildWithName(new QName("retryCount")) == null) ? null : provNode.getFirstChildWithName(new QName("retryCount")).getText();
            if (retryCount == null) {
                provNode.addChild(createOMElement("retryCount", "0"));
                context.setProperty("retryCount", "0");
            } else {
                provNode.getFirstChildWithName(new QName("retryCount")).detach();
                provNode.addChild(createOMElement("retryCount", String.valueOf(Integer.parseInt(retryCount) + 1)));
                context.setProperty("retryCount", String.valueOf(Integer.parseInt(retryCount) + 1));
            }
            String incomingTimestamp = (provNode.getFirstChildWithName(new QName("incomingTimestamp")) == null) ? null : provNode.getFirstChildWithName(new QName("incomingTimestamp")).getText();
            if (incomingTimestamp == null) {
                provNode.addChild(createOMElement("incomingTimestamp", String.valueOf(System.currentTimeMillis())));
            } else {
                provNode.getFirstChildWithName(new QName("incomingTimestamp")).detach();
                provNode.addChild(createOMElement("incomingTimestamp", String.valueOf(System.currentTimeMillis())));
            }
            envelope.getBody().addChild(provNode);
            context.setProperty("orgMessage", getPayloadText(context));
            msisdn = Utility.formatMSISDN(msisdn);
            String provisioningType = (provNode.getFirstChildWithName(new QName("provisioningType")) == null) ? null : provNode.getFirstChildWithName(new QName("provisioningType")).getText();
            context.setProperty("provisioningType", provisioningType);
            context.setProperty("msisdn", msisdn);

            logger.info("Incoming prov request|rowID:" + rowID + "|msisdn:" + msisdn + "|provisioningType:" + provisioningType);
            logger.debug("Incoming prov request|rowID:" + rowID + "|msisdn:" + msisdn + "|provisioningType:" + provisioningType + "|orgMessage:" + getPayloadText(context));
 

            return true;
        } catch (Exception ex) {
            logger.error(ErrorHandling.getMessage(ex));
            Errorlogger.error(ErrorHandling.getStackTrace(ex));
            jdbcPool.releaseConnection(connection);
            handleException(ex.getClass().getName(), ex, context);
        }
        return false;
    }

}
soap wso2 wso2-micro-integrator
1个回答
1
投票

问题似乎是您在类中介器中读取有效负载的方式,它似乎与 SOAP 消息结构紧密耦合。为了解决这个问题,请在类中介器之前添加以下内容。这将允许您使用 Content-Type 的 SOAP1.1 和 1.2 消息

application/xml

<enrich>
  <source clone="true" xpath="//prov"/>
  <target type="body"/>
</enrich>
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="UnicaProvConsumer" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
    <target>
        <inSequence>
            <enrich>
              <source clone="true" xpath="//prov"/>
              <target type="body"/>
            </enrich>
            <sequence key="MainSequence"/>
        </inSequence>
        <outSequence/>
        <faultSequence>
            <sequence key="Hello"/>
        </faultSequence>
    </target>
    <parameter name="transport.jms.Destination">REQ</parameter>
    <parameter name="transport.jms.ContentType">application/xml</parameter>
    <parameter name="transport.jms.ConnectionFactory">Listener</parameter>
</proxy>

解释

丰富中介器将允许您在进入类中介器时拥有正确的 SOAP 消息结构。详细来说,进入 WSO2 的所有消息都将在内部存储为 SOAP 消息。我认为你的问题出在这一行。

OMElement provNode = (OMElement) envelope.getBody().getFirstChildWithName(new QName("prov")).detach(); 
您期望 SOAP 消息的第一个子级是
prov
。当您使用 application/xml 构建器构建消息时,有效负载将略有不同(由于消息被处理为 XML 而不是 SOAP 消息,因此会发生额外的嵌套),因此 Enrich 将提取
prov
的内容并放置它在适当的 SOAP 主体中。

© www.soinside.com 2019 - 2024. All rights reserved.