欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳談cxf和axis兩種框架下的webservice客戶端開發(fā)

 更新時間:2021年08月26日 10:15:59   作者:萬米高空  
這篇文章主要介紹了詳談cxf和axis兩種框架下的webservice客戶端開發(fā),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

客戶端相比服務端,基本沒啥配置。引入jar包就好。我這里為了看效果,是新建了maven工程來做客戶端。調用另一個webservice服務端maven工程.

環(huán)境:jdk1.7+maven3.3.9+tomcat7

框架:spring+cxf/spring+axis(這里不是axis2,是axis)

第一種:基于cxf的客戶端開發(fā)

1.引入依賴 pom.xml

這里把兩種框架的依賴一次到位。就不分開引入了。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zhanglf</groupId>
    <artifactId>cxfClientTest</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>cxfClientTest Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- 添加 Spring dependency -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!-- 添加CXF dependency -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.1.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.1.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.5</version>
        </dependency>
        <!-- 添加CXF dependency -->
        <!-- 另一種axis方法調用webservice依賴 -->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis-jaxrpc</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>axis</groupId>
            <artifactId>axis-wsdl4j</artifactId>
            <version>1.5.1</version>
        </dependency>
        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.2</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
    <!-- 另一種axis方法調用webservice -->
    </dependencies>
    <build>
        <finalName>cxfClient</finalName>
    </build>
</project>

2.cxf和axis都沒有spring配置

直接進入業(yè)務代碼CxfClientTest.java

package com.zhanglf;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class CxfClientTest {
    public static void main(String[] args) throws Exception {
        JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
        //通過wsdl服務描述文件創(chuàng)建客戶端工廠。
        Client client = factory.createClient("http://localhost:8080/springCXFWebserviceDemo01/service/HelloWorldService?wsdl");
        //嘗試使用不帶?wsdl的地址
        //Client client = factory.createClient("http://localhost:8080/springCXFWebserviceDemo01/service/HelloWorldService");
        //invoke(
        //String operationName:要調用的方法名
        //Object... params):方法的入參??梢允嵌鄠€。
        Object[] objs = client.invoke("sayHello", "阿福");
        //invoke方法是默認返回Object[]數組。取出數組的第一位值得值就是返回值。
        System.out.println(objs[0].toString());
    }
}

直接Run As Java Application.可以看到在控制臺打出訪問服務端的代碼。

這里寫圖片描述

拓展:這里的客戶端只是傳了一個簡單的人名,正常傳入的是個String類型的xml報文。然后服務端接收報文,進行報文解析,并對信息進行crud操作。并將執(zhí)行結果以報文形式發(fā)送到客戶端??蛻舳嗽谶M行報文解析。判斷執(zhí)行情況以便進行下一步操作。下面我們用axis框架進行稍微接近業(yè)務的代碼開發(fā)。

axis客戶端代碼和cxf都在一個maven工程里。我把工程結構貼出來供參考

這里寫圖片描述

第二種:基于axis框架的客戶端開發(fā)

AxisClientTest.java的code,所有涉及的點我都在代碼里說了。解釋的文字比較多,代碼并不多。

package com.zhanglf;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
/**
 * 
 說明:address="http://localhost:8080/HelloWorld/services/user?wsdl"
 * http://localhost:8080/HelloWorld:工程訪問路徑,
 * /services:此路徑在web.xml里面配置cxf攔截器前置訪問路徑
 * /user:此路徑在服務端的applicationContext.xml里配置的,要暴露給外部調用的接口,address:請求路徑
 * 
 * @author Administrator
 * 
 */
public class AxisClientTest {
    public static void main(String[] args) throws Exception {
        // namespaceURI
        // 為:一般可以認為是<wsdl:definitions>中的targetNamespace的值,最好還是<wsdl:definitions>標簽下的
        // xmlns:tns的值為準。
        // 也是webservice接口的類上注解的targetNamespace,效果如同spring中的requestMapping,用來區(qū)分請求定位到具體的那個接口。
        // 這里的命名空間對應的是接口上面的targetNamespace,而不是實現(xiàn)類上面的。故通過wsdl中的<wsdl:definitions
        // 里面的targetNamespace是不準的,應該以<wsdl:import 中的
        // namespace為準或者<wsdl:definitions>標簽下的 xmlns:tns的值為準
        String nameSpaceURI = "com.serviceTargetName";
        // 指出service所在URL,這個有沒有?wsdl均能正確訪問。。。,這里區(qū)別于cxf,cxf是不能少這個?wsdl
        String publishUrl = "http://localhost:8080/springCXFWebserviceDemo01/service/HelloWorldService?wsdl";
        // 創(chuàng)建一個服務(service)調用(call)
        Service service = new Service();
        // 通過service創(chuàng)建call對象
        Call call = (Call) service.createCall();
        // 設置webservice接口地址
        call.setTargetEndpointAddress(new URL(publishUrl));
        // 你需要遠程調用的方法new QName(定位類的targetnamespace,定位方法的方法名)
        /**
         * call.setOperationName(new QName("serviceTargetName", "sayHello"));
         * 方法中的QName方法的入參說明: new QName( String
         * namespaceURI-定位接口的命名空間:接口注解targetnamespace的值或者wsdl文件
         * <wsdl:definitions中的xmlns
         * :tns="com.serviceTargetName"來鎖定targetnamespace的值, 這里不能用wsdl文件<wsdl:
         * definitions中的targetNamespace來確定值的原因在于這里的值來源與接口實現(xiàn)類上的targetNamespace注解的值
         * 。如果你接口的實現(xiàn)類中的targetNamespace和接口的不一樣,豈不是搞錯了。 String
         * localPart-接口下定位方法的方法名
         * :就是這里的抽象方法sayHello方法名,或者wsdl文件<wsdl:binding標簽下<wsdl:operation
         * name="sayHello"中name的值。 )
         */
        call.setOperationName(new QName(nameSpaceURI, "sayHello"));
        // 方法參數,如果沒有參數請無視。這里如果接口沒有用@WebParam(name = "name"),則會報錯:Unmarshalling
        // Error: 意外的元素 (uri:"", local:"name")。所需元素為<{}arg0>
        call.addParameter("parameterName", XMLType.XSD_STRING, ParameterMode.IN);
        // call.addParameter(new QName(soapaction,"xxxx"), XMLType.XSD_STRING,
        // ParameterMode.IN);
        // 設置返回類型,一般用string接收
        call.setReturnType(XMLType.XSD_STRING);
        // 給方法傳遞參數,并且調用方法
        String name = "zhanglifeng";
        String temp = getXml(name);
        // 這里的obj{}是放入幾個入參,完全由service提供的接口方法的入參決定,且順序和你存放的順序一致!一般入參為String類型的xml報文,回參也是xml報文。
        Object[] obj = new Object[] { temp };
        String result = (String) call.invoke(obj);
        System.out.println(result);
    }
    private static String getXml(String name) {
        StringBuffer sb = new StringBuffer(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        sb.append("<userBean>");
        sb.append("<userName>" + name + "</userName>");
        sb.append("</userBean>");
        return sb.toString();
    }
}

運行方法:Run As Java Application.客戶端的請求的入參報文如下:

<?xml version="1.0" encoding="UTF-8"?>
    <userBean>
        <userName>" + 入參:人名 + </userName>
    </userBean>

下面我把調用服務端的方法也貼出來,這樣更好理解。昨天已經貼出了服務端的目錄結構,我就把其中的HelloWorldImpl.java中的sayHello方法改一下。code如下:

package com.zlf.impl;
import javax.jws.WebService;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.util.XMLUtils;
import com.zlf.HelloWorld;
/**
 * 由于實現(xiàn)類和接口不在同一個包中。所以要加上targetNamespace屬性。
 * 另外,這里的endpointInterface是實現(xiàn)類對應接口的全路徑
 * @author Administrator
 */
@WebService(targetNamespace="com.serviceTargetName",endpointInterface="com.zlf.HelloWorld")
@Component("HelloWord")//spring注入用
public class HelloWorldImpl implements HelloWorld {
    @Override
     public String sayHello(String str) {
        String username="aaa";
        Document document = XMLUtils.parse(str);
        //首先接口開發(fā)肯定是雙發(fā)都知道此方法要接受的報文格式的。我們獲取報文中人名對應的節(jié)點即可。
          Node node = document.getElementsByTagName("userName").item(0);
          if(node !=null){
              username=node.getTextContent();
          }
        return "你好,"+username+"  你已成功訪問了webservice服務端!" ;
    }
}

XMLUtils.java工具類我也貼出來,這個也比較常用。

package com.util;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
 * 解析器
 * @author Administrator
 *
 */
public class XMLUtils {
    private final static DocumentBuilder createDocumentBuilder(){
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        DocumentBuilder builder=null;
        try {
            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
            builder=factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return builder;
    }
    public final static Document parse(InputSource in){
        try {
            return createDocumentBuilder().parse(in);
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public final static Document parse(String xml){
        return parse(new InputSource(new StringReader(xml)));
    }
}

這樣就完成了客戶端對服務端的調用。畢竟是初步入門。對以后的開發(fā)還是有所裨益。

一個客戶端和服務端底層傳輸數據的了解

客戶端傳入參數,執(zhí)行String result = (String) call.invoke(new Object[] { “zhanglifeng”})后,實際發(fā)送給服務端的是一個soap底層協(xié)議自動生成的入參報文。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="com.serviceTargetName">
   <soapenv:Header/>
   <soapenv:Body>
      <com:sayHello>
         <!--Optional:-->
         <parameterName>zhanglifeng</parameterName>
      </com:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

服務端接收這個報文后自動解析,并把入參賦值給方法sayHello(String str)的入參str.經過處理數據返回給客戶端,也是soap底層自動生成的回參報文

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:sayHelloResponse xmlns:ns2="com.serviceTargetName">
         <return>你好,zhanglifeng  你已成功訪問了webservice服務端!</return>
      </ns2:sayHelloResponse>
   </soap:Body>
</soap:Envelope>

客戶端自動把從返回報文中取出返回值,并付值給String result。這樣底層已經處理過了報文。還有一種情況就是如果客戶端傳過來的參數本身就是xml時,底層封裝參數的問題。

如果客戶端的invoke()方法入參

String xml="
<?xml version=\"1.0\" encoding=\"UTF-8\"?><userBean><userName>zhanglifeng</userName></userBean>"

底層自動為xml加上<![CDATA[ xml ]]>:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="com.serviceTargetName">
   <soapenv:Header/>
   <soapenv:Body>
      <com:sayHello>
         <!--Optional:-->
         <parameterName><![CDATA[<?xml version="1.0" encoding="UTF-8"?><userBean><userName>zhanglifeng</userName></userBean> ]]></parameterName>
      </com:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

知道這個原理,在使用SoupUI進行調用webservice接口時就可以使用這種<![CDATA[ 入參xml ]]>格式進行調用。soupui調用的入參如下圖

這里寫圖片描述

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 使用Maven打包時包含資源文件和源碼到jar的方法

    使用Maven打包時包含資源文件和源碼到jar的方法

    這篇文章主要介紹了使用Maven打包時包含資源文件和源碼到jar的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java服務器端跨域問題解決方案

    Java服務器端跨域問題解決方案

    這篇文章主要介紹了java服務器端跨域問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Maven倉庫加載順序的實例解析

    Maven倉庫加載順序的實例解析

    Maven倉庫一般分為本地倉庫和遠程倉庫。那么在實際開發(fā)中,在配置了多個倉庫的情況下,他們之間的加載訪問順序是怎么樣的呢,本文就詳細的來介紹一下
    2021-12-12
  • SpringCloud?Alibaba環(huán)境集成之nacos詳解

    SpringCloud?Alibaba環(huán)境集成之nacos詳解

    Spring?Cloud?Alibaba提供了越來越完善的各類微服務治理組件,比如分布式服務配置與注冊中心nacos,服務限流、熔斷組件sentinel等,本篇先來介紹SpringCloud?Alibaba環(huán)境集成之nacos詳解,需要的朋友可以參考下
    2023-03-03
  • java類加載器和類反射使用示例

    java類加載器和類反射使用示例

    這篇文章主要介紹了java類加載器和類反射使用示例,需要的朋友可以參考下
    2014-03-03
  • 詳解自動注冊Gateway網關路由配置

    詳解自動注冊Gateway網關路由配置

    這篇文章主要為大家介紹了自動注冊Gateway網關路由配置的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Java中List排序的3種常見方法總結

    Java中List排序的3種常見方法總結

    在Java編程中List對象的排序是一個常見的需求,List接口提供了多種排序方法,這篇文章主要給大家介紹了關于Java中List排序的3種常見方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-08-08
  • 分布式鎖實例教程之防止重復提交

    分布式鎖實例教程之防止重復提交

    訂單重復問題已經是老生常談的問題了,下面這篇文章主要給大家介紹了關于分布式鎖實例教程之防止重復提交的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-11-11
  • Spring mvc是如何實現(xiàn)與數據庫的前后端的連接操作的?

    Spring mvc是如何實現(xiàn)與數據庫的前后端的連接操作的?

    今天給大家?guī)淼氖顷P于Spring mvc的相關知識,文章圍繞著Spring mvc是如何實現(xiàn)與數據庫的前后端的連接操作的展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • java實現(xiàn)哈弗曼編碼與反編碼實例分享(哈弗曼算法)

    java實現(xiàn)哈弗曼編碼與反編碼實例分享(哈弗曼算法)

    本文介紹java實現(xiàn)哈弗曼編碼與反編碼實例,大家參考使用吧
    2014-01-01

最新評論