CXF通過攔截器修改請求報文


最近一位做Siebel的同事需要通過Web Service接口調用另外一個系統,對方的Web Service使用的是CXF框架,並提供了WSDL文件。

Siebel通過WSDL生成請求報文時報錯,而直接通過SoapUI導入WSDL測試是OK的。通過抓取報文發現,兩者生成的報文namespace有所不同,Siebel生成的namespace放在節點上,SoapUI生成的namespace放在頭上,具體如下:

Siebel生成的報文: 

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <SOAP-ENV:Body>
      <handleCallCenterWarningInfo xmlns="http://service.webservice.kora.com/">
         <arg0>
            <handleDepartment/>
            <handleResult/>
            <handleStatus>1</handleStatus>
            <handleTime/>
            <realWarningCaseId/>
            <rescueOrderNumber>121212121</rescueOrderNumber>
         </arg0>
      </handleCallCenterWarningInfo>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Siebel調用時報錯信息如下:

Unmarshalling Error: unexpected element (uri:"http://service.webservice.kora.com/", local:"arg0"). Expected elements are &lt;{}arg0>

 

SoapUI生成的報文:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://server.webservice.mycompany.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:haha>
         <arg0>
            <handleDepartment>1</handleDepartment>
            <handleResult>2</handleResult>
            <handleStatus>3</handleStatus>
            <handleTime>4</handleTime>
            <realWarningCaseId>5</realWarningCaseId>
            <rescueOrderNumber>6</rescueOrderNumber>
         </arg0>
      </ser:haha>
   </soapenv:Body>
</soapenv:Envelope>

 

針對報文格式問題,准備兩種嘗試方式:

1、攔截請求報文,把報文修改成符合WS命名空間的結構。

2、通過CXF框架的設置,設成不校驗命名空間。(此方式沒有技術參考,憑空想象的。后經測試驗證也沒有發現該配置選項,具體的WS規范以及CXF實現后續需要更深一步的查閱文檔以及源碼)

 

后經測試驗證,最終選擇了方式1解決,具體調整步驟如下:

1、在WS配置文件中增加紅色區域內容。
<jaxws:endpoint implementor="com.kora.webservice.service.CallCenterServiceImplPortImpl" address="/callCenterService" >
   <jaxws:inInterceptors>
       <bean class="com.info.CAbstractPhaseInterceptor">
           <constructor-arg><value>receive</value></constructor-arg>
       </bean>
   </jaxws:inInterceptors>
</jaxws:endpoint>
 
2、增加一個攔截類CallCenterServiceImplPortImpl修改報文:
/**
 * CAbstractPhaseInterceptor.java
 * Created at 2017-4-13
 * Created by hff
 * Copyright (C) 2017 SHANGHAI XXX, All rights reserved.
 */
package com.info;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.cxf.binding.soap.Soap11;
import org.apache.cxf.binding.soap.SoapVersion;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;

/**
 * <p>ClassName: CAbstractPhaseInterceptor</p>
 * <p>Description: cxf攔截器</p>
 * <p>Author: hff</p>
 * <p>Date: 2017-4-13</p>
 */
public class CAbstractPhaseInterceptor extends AbstractPhaseInterceptor<Message> {

    /**
     * <p>Description: TODO</p>
     * @param phase
     */
    public CAbstractPhaseInterceptor(String phase) {
        super(phase);
    }

    /* (non-Javadoc)
     * <p>Title: handleMessage</p>
     * <p>Description: </p>
     * @param message
     * @throws Fault
     * @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message)
     */
    @Override
    public void handleMessage(Message message) throws Fault {
        InputStream is = message.getContent(InputStream.class);
        if (is != null) {
            try {
                String str = IOUtils.toString(is);
                // 原請求報文
                System.out.println("====> request xml=\r\n" + str);
                
                // 把siebel格式的報文替換成符合cxf帶前綴的命名空間
                str = str.replace("<handleCallCenterWarningInfo xmlns=\"http://service.webservice.kora.com/\">", 
                        "<ser:handleCallCenterWarningInfo xmlns:ser=\"http://service.webservice.kora.com/\">").replace(
                                "</handleCallCenterWarningInfo>", "</ser:handleCallCenterWarningInfo>").replace(
                                        "xmlns=\"http://service.webservice.kora.com/\"", "");
                // 替換后的報文
                System.out.println("====> replace xml=\r\n" + str);
                
                InputStream ism = new ByteArrayInputStream(str.getBytes());
                message.setContent(InputStream.class, ism);
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM