基于XML的Web服务Java接口(JAX-WS)、Jakarta XML Web Services Eclipse 实现

简介

JAX-WS(Java API for XML-Based Web Services),是创建web服务的Java编程接口,特别是SOAP服务。是Java XML编程接口之一,是Java SE 和Java EE 平台的一部分。
JAX-WS 2.0 规范是代替JAX-RPC 1.0的下一代Web服务API。JAX-RPC(The Java API for XML Based RPC)是基于XML的RPC(远程过程调用)的Java API。
JAX-WS 2.0 使用JAXB(The Java Architecture for XML Binding)进行XML数据绑定,所谓绑定就是指XML请求和XML响应如何映射成java对象。

参考资源

JAX-WS 2.0参考资源

https://jcp.org/en/jsr/detail?id=224

https://jakarta.ee/specifications/xml-web-services/2.3/

JAX-WS 3.0参考资源

https://jakarta.ee/specifications/xml-web-services/3.0/

JAX-WS 4.0参考资源

https://jakarta.ee/specifications/xml-web-services/4.0/

Jakarta Web Services Metadata

Jakarta Web Services Metadata项目是Jakarta XML Web Services 项目的一部分,它用Java为web 服务定义了一个编程模型。

代码库:https://github.***/jakartaee/jws-api

Jakarta Web Services Metadata 3.0 Specification Document (HTML):
https://jakarta.ee/specifications/web-services-metadata/3.0/ws-metadata-spec-3.0

Jakarta Web Services Metadata 3.0 Javadoc:
https://jakarta.ee/specifications/web-services-metadata/3.0/apidocs/jakarta.jws/module-summary.html

参考实现

旧项目(已经归档、只读)

https://javaee.github.io/metro-jax-ws/

https://github.***/javaee/metro-jax-ws

新项目(Jakarta XML Web Services Eclipse 实现)

主页:
https://eclipse-ee4j.github.io/metro-jax-ws/

代码库:
https://github.***/eclipse-ee4j/metro-jax-ws

XML web服务的Eclipse 实现是一个web服务框架,它为最终用户和中间件开发者开发web服务解决方案提供了工具和基础设施(infrastructure)。
使用XML web服务的Eclipse 实现,客户端和web有一个大的优势:Java编程语言的平台无关性。

Jakarta XML Web Services Eclipse 实现需要的软件

JRE版本

Java SE 11或以后版本

Ant 版本

Ant 1.10.6或以后版本

servlet容器

在GlassFish v7.x 、Apache Tomcat 10.1.x下测试过

安装Jakarta XML Web Services Eclipse 实现

下载Jakarta XML Web Services Eclipse实现独立zip发布包

打开主页:https://eclipse-ee4j.github.io/metro-jax-ws/

点击右侧的Download就可以下载独立发布包,例如,下载jaxws-ri-4.0.0.zip。
解压后的目录:

bin子目录下的内容:

docs子目录下的内容:

lib子目录下的内容:

samples子目录下的内容:

安装到Tomcat中

设置CATALINA_HOME环境变量,指向Tomcat的安装目录,例如:


在cmd窗口,切换到Jakarta XML Web Services Eclipse实现解压后的目录,例如:D:\jaxws-ri-4.0.0\jaxws-ri

这个目录下有build.xml文件:

运行ant install命令。这个命令其实执行了两个大的操作:

  • 拷贝Jakarta XML Web Services Eclipse实现lib子目录下的jar文件到Tomcat安装目录下面的/shared/lib子目录中
  • 更新Tomcat安装目录下面/conf/catalina.properties文件中的属性shared.loader,使之等于${catalina.home}/shared/lib/*.jar

build.xml文件片段:

<target name="install" depends="update-catalina-props" description="Install XML-WS RI 4.0.0 jars">
    <echo message="Installing XML-WS RI 4.0.0 for ${catalina.home} ..."/>

    <mkdir dir="${catalina.lib.home}"/>
    <copy toDir="${catalina.lib.home}" overwrite="true">
        <fileset dir="${basedir}/lib" includes="*.jar"/>
    </copy>

</target>

<target name="update-catalina-props">
    <echo message="Backing up ${catalina.home}/conf/catalina.properties..."/>
    <copy file="${catalina.home}/conf/catalina.properties" tofile="${catalina.home}/conf/catalina.properties.backup"/>
    <echo message="Adding XML-WS RI jars to shared.loader property in ${catalina.home}/conf/catalina.properties..."/>
    <replace file="${catalina.home}/conf/catalina.properties" token="shared.loader=" value="shared.loader=$${catalina.home}/shared/lib/*.jar,"/>
</target>

执行ant install命令的窗口输出信息:

Jakarta XML Web Services Eclipse 实现依赖的jar包

https://eclipse-ee4j.github.io/metro-jax-ws/4.0.0/docs/release-documentation.html#jar-dependency

SOAP1.1+HTTP样例:运行fromjava样例(来自Jakarta XML Web Services Eclipse实现发布包)

说明

fromjava这个样例演示了从一个Java service endpoint的实现开始,如何构建、部署、调用一个简单的web服务。其中Java service endpoint的实现使用了Java注释。

fromjava的目录结构:

服务实现类只有一个方法addNumbers,输入两个整数,返回一个整数,抛出AddNumbersException异常:

运行web服务有两种方式:

  • 在servlet容器中运行
  • 作为一个j2se webservice endpoint运行(不需要servlet容器)

运行方式一:在tomcat容器中运行web服务

设置环境变量JAXWS_HOME指向JAX-WS的安装目录

在cmd窗口切换到fromjava的目录

运行ant clean

运行ant clean的作用是删掉${build.home}目录。其中${build.home}目录指向${basedir}/build,就是fromjava/build目录。(其实这个命令不运行也可以,因为下一步运行ant server命令的时候其中含有ant clean的步骤)

运行ant server -Dtomcat=true

运行ant server -Dtomcat=true的作用是构建、部署web服务的WAR包,因为要将web服务运行在tomcat中,所以加了-Dtomcat=true这个属性。这个命令做了四个工作:

<target name="server" depends="setup">

    <antcall target="clean"/>

    <antcall target="build-server-java"/>

    <antcall target="create-war"/>

    <antcall target="deploy"/>
</target>

运行输出:

现在fromjava目录下的文件布局(注:照理${env.AS_HOME}这个目录不应该生成的,对我们没有什么用):

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\FROMJAVA
│  build.xml
│  Readme.txt
│  
├─${env.AS_HOME}
│  └─domains
│      └─domain1
│          └─autodeploy
│                  jaxws-fromjava.war
│                  
├─build
│  ├─classes
│  │  └─fromjava
│  │      └─server
│  │          │  AddNumbersException.class
│  │          │  AddNumbersImpl.class
│  │          │  AddWebservice.class
│  │          │  EndpointStopper$1.class
│  │          │  EndpointStopper.class
│  │          │  
│  │          └─jaxws
│  │                  AddNumbers.class
│  │                  AddNumbers.java
│  │                  AddNumbersExceptionBean.class
│  │                  AddNumbersExceptionBean.java
│  │                  AddNumbersResponse.class
│  │                  AddNumbersResponse.java
│  │                  
│  └─war
│          jaxws-fromjava.war
│          
├─etc
│      deploy-targets.xml
│      sun-jaxws.xml
│      web.xml
│      
└─src
    └─fromjava
        ├─client
        │      AddNumbersClient.java
        │      
        └─server
                AddNumbersException.java
                AddNumbersImpl.java
                AddWebservice.java
                EndpointStopper.java

<tomcat安装目录>/webapps下查看,war包已经拷贝过来了:

运行tomcat

因为生成客户端代码的时候要访问web服务动态生成的wsdl文件,所以要先启动tomcat。

<tomcat安装目录>/webapps下查看,war包已经被自动部署了:

部署以后的文件布局:

D:\APACHE-TOMCAT-10.1.13\WEBAPPS\JAXWS-FROMJAVA
├─META-INF
│      MANIFEST.MF
│      war-tracker
│      
└─WEB-INF
    │  sun-jaxws.xml
    │  web.xml
    │  
    └─classes
        └─fromjava
            └─server
                │  AddNumbersException.class
                │  AddNumbersImpl.class
                │  AddWebservice.class
                │  EndpointStopper$1.class
                │  EndpointStopper.class
                │  
                └─jaxws
                        AddNumbers.class
                        AddNumbers.java
                        AddNumbersExceptionBean.class
                        AddNumbersExceptionBean.java
                        AddNumbersResponse.class
                        AddNumbersResponse.java

看看wsdl文件能否正常生成

访问http://localhost:8080/jaxws-fromjava/addnumbers?wsdl
可以看到,正常生成了wsdl文件。生成客户端代码的时候,就要访问这个wsdl的地址。

<?xml version='1.0' encoding='UTF-8'?><!-- Published by XML-WS Runtime (https://github.***/eclipse-ee4j/metro-jax-ws). Runtime's version is XML-WS Runtime 4.0.0 git-revision#129f787. --><!-- Generated by XML-WS Runtime (https://github.***/eclipse-ee4j/metro-jax-ws). Runtime's version is XML-WS Runtime 4.0.0 git-revision#129f787. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.fromjava/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://server.fromjava/" name="AddNumbersImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://server.fromjava/" schemaLocation="http://localhost:8080/jaxws-fromjava/addnumbers?xsd=1"/>
</xsd:schema>
</types>
<message name="addNumbers">
<part name="parameters" element="tns:addNumbers"/>
</message>
<message name="addNumbersResponse">
<part name="parameters" element="tns:addNumbersResponse"/>
</message>
<message name="AddNumbersException">
<part name="fault" element="tns:AddNumbersException"/>
</message>
<portType name="AddNumbersImpl">
<operation name="addNumbers">
<input wsam:Action="http://server.fromjava/AddNumbersImpl/addNumbersRequest" message="tns:addNumbers"/>
<output wsam:Action="http://server.fromjava/AddNumbersImpl/addNumbersResponse" message="tns:addNumbersResponse"/>
<fault message="tns:AddNumbersException" name="AddNumbersException" wsam:Action="http://server.fromjava/AddNumbersImpl/addNumbers/Fault/AddNumbersException"/>
</operation>
</portType>
<binding name="AddNumbersImplPortBinding" type="tns:AddNumbersImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="addNumbers">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="AddNumbersException">
<soap:fault name="AddNumbersException" use="literal"/>
</fault>
</operation>
</binding>
<service name="AddNumbersImplService">
<port name="AddNumbersImplPort" binding="tns:AddNumbersImplPortBinding">
<soap:address location="http://localhost:8080/jaxws-fromjava/addnumbers"/>
</port>
</service>
</definitions>

运行ant clean

运行ant clean:

运行ant client

运行ant client的目的是为了生成客户端代码并编译:

<target name="generate-client" depends="setup">
    <wsimport
            debug="true"
            verbose="${verbose}"
            keep="true"
            destdir="${build.classes.home}"
            package="fromjava.client"
            wsdl="http://localhost:8080/jaxws-fromjava/addnumbers?wsdl">
    </wsimport>
</target>

<target name="client" depends="generate-client">
    <javac
            fork="true"
            srcdir="${basedir}/src"
            destdir="${build.classes.home}"
            includes="**/client/**,**/***mon/**">
        <classpath refid="jaxws.classpath"/>
    </javac>
</target>

运行后,客户端代码布局:

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\FROMJAVA\BUILD
├─classes
│  └─fromjava
│      └─client
│              AddNumbers.class
│              AddNumbers.java
│              AddNumbersClient.class
│              AddNumbersException.class
│              AddNumbersException.java
│              AddNumbersException_Exception.class
│              AddNumbersException_Exception.java
│              AddNumbersImpl.class
│              AddNumbersImpl.java
│              AddNumbersImplService.class
│              AddNumbersImplService.java
│              AddNumbersResponse.class
│              AddNumbersResponse.java
│              ObjectFactory.class
│              ObjectFactory.java
│              package-info.class
│              package-info.java
│              
└─war

运行ant run

执行ant run表示运行客户端。

<target name="run">
    <java fork="true" classname="fromjava.client.AddNumbersClient">
        <classpath>
            <path refid="jaxws.classpath"/>
            <pathelement location="${build.classes.home}"/>
            <pathelement location="${basedir}/etc"/>
        </classpath>
    </java>
</target>

在运行ant run前,启动Wireshark抓包工具,在环回接口上抓包,目的是看看调用web服务的协议是否用了SOAP协议(用http过滤):

计算10+20的请求:

计算10+20的响应:

计算-10+20的请求:

计算-10+20的响应:

运行方式二:作为一个j2se webservice endpoint运行(不运行在servlet容器中)

运行ant clean server-j2se

运行ant clean server-j2se生成服务端代码,并且用Endpoint API来部署:

<target name="server-j2se" depends="setup">
    <antcall target="clean"/>

    <antcall target="build-server-java"/>

    <echo message="Starting endpoint... To stop: ant server-j2se-stop "/>

    <java fork="true" classname="fromjava.server.AddWebservice">
        <classpath>
            <path refid="jaxws.classpath"/>
            <pathelement location="${build.classes.home}"/>
        </classpath>
    </java>
</target>

生成的文件布局:

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\FROMJAVA\BUILD
├─classes
│  └─fromjava
│      └─server
│          │  AddNumbersException.class
│          │  AddNumbersImpl.class
│          │  AddWebservice.class
│          │  EndpointStopper$1.class
│          │  EndpointStopper.class
│          │  
│          └─jaxws
│                  AddNumbers.class
│                  AddNumbers.java
│                  AddNumbersExceptionBean.class
│                  AddNumbersExceptionBean.java
│                  AddNumbersResponse.class
│                  AddNumbersResponse.java
│                  
└─war

访问http://localhost:8080/jaxws-fromjava/addnumbers?wsdl
可以正常生成wsdl文件:

运行ant clean client run

另外打开一个cmd窗口,运行ant clean client run,目的是在根据endpoint发布的wsdl文件生成客户端代码、编译、并且运行。

运行后,客户端的代码布局:
D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\FROMJAVA\BUILD
├─classes
│ └─fromjava
│ └─client
│ AddNumbers.class
│ AddNumbers.java
│ AddNumbersClient.class
│ AddNumbersException.class
│ AddNumbersException.java
│ AddNumbersException_Exception.class
│ AddNumbersException_Exception.java
│ AddNumbersImpl.class
│ AddNumbersImpl.java
│ AddNumbersImplService.class
│ AddNumbersImplService.java
│ AddNumbersResponse.class
│ AddNumbersResponse.java
│ ObjectFactory.class
│ ObjectFactory.java
│ package-info.class
│ package-info.java

└─war

运行ant server-j2se-stop,停止web服务

<target name="server-j2se-stop" depends="setup">
    <get src="http://localhost:9090/stop" dest="stop.status"/>
</target>

REST风格的web服务样例(使用XML/HTTP绑定 )

说明

本样例来自Jakarta XML Web Services Eclipse实现发布包中的restful样例:

这个样例展示了基于REST风格的web服务,利用XML/HTTP绑定。在这种情况下,不需要发布wsdl文件。

服务端实现了一个web服务的Provider:

客户端访问web服务,样例演示了两种访问方式:

  • 方式一:使用Jakarta XML Web Services Dispatch,利用HTTP GET请求方法,以及Jakarta XML Web Services MessageContext 的属性 PATH_INFO 和 QUERY_STRING。

  • 方式二:使用URLConnection。

  • 另外,也可以直接在浏览器中访问,就作为方式三吧。

restful样例的目录结构:

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\RESTFUL
│  build.xml
│  Readme.txt
│  
├─etc
│      deploy-targets.xml
│      sun-jaxws.xml
│      web.xml
│      
└─src
    └─restful
        ├─client
        │      AddNumbersClient.java
        │      DispatchAddNumbersClient.java
        │      
        └─server
                AddNumbersImpl.java

web服务需要两个输入参数,然后求和,将计算结果返回。

运行服务端

设置环境变量JAXWS_HOME,指向JAX-WS的安装目录

在cmd窗口切换到restful的目录

运行ant clean server -Dtomcat=true

运行ant clean server -Dtomcat=true,其中tomcat=true这个系统属性表示将服务端的web服务部署到tomcat上。
运行输出信息:


现在restful目录下的文件布局:

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\RESTFUL
│  build.xml
│  Readme.txt
│  
├─build
│  ├─classes
│  │  └─restful
│  │      └─server
│  │              AddNumbersImpl.class
│  │              
│  └─war
│          jaxws-restful.war
│          
├─etc
│      deploy-targets.xml
│      sun-jaxws.xml
│      web.xml
│      
└─src
    └─restful
        ├─client
        │      AddNumbersClient.java
        │      DispatchAddNumbersClient.java
        │      
        └─server
                AddNumbersImpl.java

到<tomcat安装目录>/webapps下查看,war包已经拷贝过来了:

运行tomcat


到<tomcat安装目录>/webapps下查看,war包已经被自动部署了:

部署以后的文件布局:

D:\APACHE-TOMCAT-10.1.13\WEBAPPS\JAXWS-RESTFUL
├─META-INF
│      MANIFEST.MF
│      war-tracker
│      
└─WEB-INF
    │  sun-jaxws.xml
    │  web.xml
    │  
    └─classes
        └─restful
            └─server
                    AddNumbersImpl.class

(客户端访问web服务方式三)直接在浏览器中访问web服务、抓包分析

直接在浏览器中访问,服务已经正常启动:

用Wireshark在本地环回接口上开启抓http的包,在浏览器中重新访问。

响应报文是HTTP/XML形式的:

(客户端访问web服务方式一)在cmd窗口基于Dispatch方式运行客户端

运行ant clean client run-dispatch:

客户端运行以后的输出目录布局:

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\RESTFUL\BUILD
├─classes
│  └─restful
│      └─client
│              AddNumbersClient.class
│              DispatchAddNumbersClient.class
│              
└─war

运行客户端的时候,同步用Wireshark在本地环回接口抓到的http的包:

请求参数放在URL的查询部分::

响应:

请求参数放在URL的路径部分::

响应:

(客户端访问web服务方式二)在cmd窗口使用URLConnection方式访问web服务

运行ant clean client run-url:

客户端运行以后的输出目录布局:

D:\JAXWS-RI-4.0.0\JAXWS-RI\SAMPLES\RESTFUL\BUILD
├─classes
│  └─restful
│      └─client
│              AddNumbersClient.class
│              DispatchAddNumbersClient.class
│              
└─war

用WireShark在本地环回接口上同步抓到的包:

请求参数放在URL的查询部分:

响应:

请求参数放在URL的路径中:

响应:

Jakarta XML Web Services Eclipse实现下载方式二:用maven下载

这种方式不需要安装Jakarta XML Web Services Eclipse实现单独的发布包。

创建一个maven工程,在maven工程的pom.xml文件中增加如下依赖:

  <dependencies>
    <dependency>
      <groupId>jakarta.xml.ws</groupId>
      <artifactId>jakarta.xml.ws-api</artifactId>
      <version>4.0.0</version>
    </dependency>
    <dependency>
      <groupId>***.sun.xml.ws</groupId>
      <artifactId>jaxws-rt</artifactId>
      <version>4.0.0</version>        
    </dependency>
  </dependencies>

因为将web服务部署servlet容器(例如tomcat)的时候,依赖的包是放在一个目录下面的。所以,要部署的时候,可以先使用maven的dependency插件,将项目依赖从maven仓库中提取出来,拷贝到一个指定的位置(如果使用ant构建的话,方便ant的build文件编写)。

例如,在cmd窗口,切换到maven工程的根目录下面,运行mvn dependency:copy-dependencies -Dmdep.stripVersion=true -DoutputDirectory=lib,指定将依赖包拷贝到项目根目录下面的lib子目录下,拷贝时去掉了依赖包文件名中的版本号:



<项目根目录>/lib子目录下查看,内容拷贝过来了:

转载请说明出处内容投诉
CSS教程_站长资源网 » 基于XML的Web服务Java接口(JAX-WS)、Jakarta XML Web Services Eclipse 实现

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买