webservice系统学习笔记9-使用契约优先的方式的一个服务端demo(隐式传Header信息)

时间:2023-03-08 18:46:25

服务器端:

1、编写wsdl文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.org/mywsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="MyServiceImplService"
targetNamespace="http://www.example.org/mywsdl/"> <!-- 定义类型 -->
<wsdl:types>
<xsd:schema targetNamespace="http://www.example.org/mywsdl/">
<xsd:element name="add" type="tns:add"/>
<xsd:element name="addResponse" type="tns:addResponse"/>
<xsd:element name="divide" type="tns:divide"/>
<xsd:element name="divideResponse" type="tns:divideResponse"/>
<xsd:element name="licenseInfo" type="xsd:string"/> <xsd:complexType name="add">
<xsd:sequence>
<xsd:element name="a" type="xsd:int"/>
<xsd:element name="b" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="addResponse">
<xsd:sequence>
<xsd:element name="addResult" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType> <xsd:complexType name="divide">
<xsd:sequence>
<xsd:element name="num1" type="xsd:int"/>
<xsd:element name="num2" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="divideResponse">
<xsd:sequence>
<xsd:element name="divideResult" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType> </xsd:schema>
</wsdl:types> <!-- 定义消息 -->
<wsdl:message name="add">
<wsdl:part name="add" element="tns:add"/>
</wsdl:message>
<wsdl:message name="addResponse">
<wsdl:part name="addResponse" element="tns:addResponse"></wsdl:part>
</wsdl:message>
<wsdl:message name="divide">
<wsdl:part name="divide" element="tns:divide"/>
</wsdl:message>
<wsdl:message name="divideResponse">
<wsdl:part name="divideResponse" element="tns:divideResponse"/>
</wsdl:message> <!-- 头消息 -->
<wsdl:message name="licenseInfo">
<wsdl:part name="licenseInfo" element="tns:licenseInfo"></wsdl:part>
</wsdl:message> <!-- 定义port -->
<wsdl:portType name="IMyService">
<wsdl:operation name="add">
<wsdl:input message="tns:add"/>
<wsdl:output message="tns:addResponse"/>
</wsdl:operation> <wsdl:operation name="divide">
<wsdl:input message="tns:divide"/>
<wsdl:output message="tns:divideResponse"/>
</wsdl:operation>
</wsdl:portType> <!-- 绑定服务 -->
<wsdl:binding name="myServiceSOAP" type="tns:IMyService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="add">
<wsdl:input>
<soap:body use="literal"/>
<!-- 为add添加隐式的头信息 -->
<soap:header use="literal" part="licenseInfo" message="tns:licenseInfo"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation> <wsdl:operation name="divide">
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding> <!-- 发布服务 -->
<wsdl:service name="MyServiceImplService"><!-- 这里的名字必须和<wsdl:definitions里的name一致 -->
<wsdl:port binding="tns:myServiceSOAP" name="MyServiceImplPort">
<soap:address location="http://localhost:8989/ms"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

2、使用wsimport命令生成服务端接口类(IMyService.java)
备注:生成的其他文件都可以删除

在add方法的参数定义上加上

@WebParam(name="licenseInfo")String licenseInfo

3、编写服务接口的实现类MyServiceImpl.java

package org.example.mywsdl;

import javax.jws.WebService;

//这里必须制定wsdlLocation来约定参数等名称等
//endpointInterface可写也可不写,写它主要是用到自动生成的一些注解信息
@WebService(endpointInterface="org.example.mywsdl.IMyService",
targetNamespace="http://www.example.org/mywsdl/",
wsdlLocation="META-INF/wsdl/mywsdl.wsdl",
name="MyServiceImpl"
)
public class MyServiceImpl implements IMyService { @Override
public int add(int a, int b, String licenseInfo) {
return a+b;
} @Override
public int divide(int num1, int num2) {
return num1/num2;
} }

4、服务启动类

package org.example.mywsdl;

import javax.xml.ws.Endpoint;

public class RunService {

    public static void main(String[] args) {
//这里的发布地址必须和wsdl中定义的一样
Endpoint.publish("http://localhost:8989/ms", new MyServiceImpl());
}
}

访问服务:http://localhost:8989/ms?wsdl

客户端直接用上面的地址生成即可,生成的wsdl文件即是我们编写的那个wsdl文件

<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --><wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/mywsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="MyServiceImplService" targetNamespace="http://www.example.org/mywsdl/">

    <!-- 定义类型 -->
<wsdl:types>
<xsd:schema targetNamespace="http://www.example.org/mywsdl/">
<xsd:element name="add" type="tns:add"></xsd:element>
<xsd:element name="addResponse" type="tns:addResponse"></xsd:element>
<xsd:element name="divide" type="tns:divide"></xsd:element>
<xsd:element name="divideResponse" type="tns:divideResponse"></xsd:element>
<xsd:element name="licenseInfo" type="xsd:string"></xsd:element> <xsd:complexType name="add">
<xsd:sequence>
<xsd:element name="a" type="xsd:int"></xsd:element>
<xsd:element name="b" type="xsd:int"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="addResponse">
<xsd:sequence>
<xsd:element name="addResult" type="xsd:int"></xsd:element>
</xsd:sequence>
</xsd:complexType> <xsd:complexType name="divide">
<xsd:sequence>
<xsd:element name="num1" type="xsd:int"></xsd:element>
<xsd:element name="num2" type="xsd:int"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="divideResponse">
<xsd:sequence>
<xsd:element name="divideResult" type="xsd:int"></xsd:element>
</xsd:sequence>
</xsd:complexType> </xsd:schema>
</wsdl:types> <!-- 定义消息 -->
<wsdl:message name="add">
<wsdl:part name="add" element="tns:add"></wsdl:part>
</wsdl:message>
<wsdl:message name="addResponse">
<wsdl:part name="addResponse" element="tns:addResponse"></wsdl:part>
</wsdl:message>
<wsdl:message name="divide">
<wsdl:part name="divide" element="tns:divide"></wsdl:part>
</wsdl:message>
<wsdl:message name="divideResponse">
<wsdl:part name="divideResponse" element="tns:divideResponse"></wsdl:part>
</wsdl:message> <!-- 头消息 -->
<wsdl:message name="licenseInfo">
<wsdl:part name="licenseInfo" element="tns:licenseInfo"></wsdl:part>
</wsdl:message> <!-- 定义port -->
<wsdl:portType name="IMyService">
<wsdl:operation name="add">
<wsdl:input message="tns:add"></wsdl:input>
<wsdl:output message="tns:addResponse"></wsdl:output>
</wsdl:operation> <wsdl:operation name="divide">
<wsdl:input message="tns:divide"></wsdl:input>
<wsdl:output message="tns:divideResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType> <!-- 绑定服务 -->
<wsdl:binding name="myServiceSOAP" type="tns:IMyService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>
<wsdl:operation name="add">
<wsdl:input>
<soap:body use="literal"></soap:body>
<!-- 为add添加隐式的头信息 -->
<soap:header use="literal" part="licenseInfo" message="tns:licenseInfo"></soap:header>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"></soap:body>
</wsdl:output>
</wsdl:operation> <wsdl:operation name="divide">
<wsdl:input>
<soap:body use="literal"></soap:body>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"></soap:body>
</wsdl:output>
</wsdl:operation>
</wsdl:binding> <!-- 发布服务 -->
<wsdl:service name="MyServiceImplService"><!-- 这里的名字必须和<wsdl:definitions里的name一致 -->
<wsdl:port binding="tns:myServiceSOAP" name="MyServiceImplPort">
<soap:address location="http://localhost:8989/ms"></soap:address>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

使用该wsdl生成客户端java代码后的add方法如下:

@WebMethod
@WebResult(name = "addResult", targetNamespace = "")
@RequestWrapper(localName = "add", targetNamespace = "http://www.example.org/mywsdl/", className = "com.ws04.Add")
@ResponseWrapper(localName = "addResponse", targetNamespace = "http://www.example.org/mywsdl/", className = "com.ws04.AddResponse")
public int add(@WebParam(name = "a", targetNamespace = "") int a,
@WebParam(name = "b", targetNamespace = "") int b);

此时方法的参数里没有看到有头信息参数的定义,调用该方法可以使用handler或者soap来编码传递头信息