天天看点

webservice——通过契约优先开发webservice

一、基本概念

有代码优先和契约优先两种开发webService的方式,本例介绍契约优先的webService。

编写WSDL有三种方式:基于document的Wrapper方式,基于document的Bare方式,基于RPC方式。本例介绍Wraper方式,也是默认方式和推荐方式。Wrapper有包起来的意思,将所有对象通过element封装。

二、编写步骤

一、服务端:

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/hello/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

name="HelloService"

targetNamespace="http://www.example.org/hello/">

<wsdl:types>

<xsd:schema targetNamespace="http://www.example.org/hello/">

<xsd:element name="add" type="tns:add"></xsd:element>

<xsd:element name="addResponse" type="tns:addResponse"></xsd:element>

<xsd:element name="licenceInfo" type="tns:licenceInfo"></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:element name="addResponse" type="xsd:int"></xsd:element>

<xsd:complexType name="licenceInfo">

<xsd:element name="licenceInfo" type="xsd:string"></xsd:element>

</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 name="licenceInfo">

<wsdl:part name="licenceInfo" element="tns:licenceInfo"></wsdl:part>

<wsdl:portType name="IHelloService">

<wsdl:operation name="add">

<wsdl:input message="tns:add"></wsdl:input>

<wsdl:output message="tns:addResponse"></wsdl:output>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="HelloServiceSOAP" type="tns:IHelloService">

<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

<wsdl:input>

<soap:body use="literal" />

<soap:header use="literal" part="licenceInfo" message="tns:licenceInfo"></soap:header>

</wsdl:input>

<wsdl:output>

</wsdl:output>

</wsdl:binding>

<wsdl:service name="HelloService">

<wsdl:port binding="tns:HelloServiceSOAP" name="HelloServicePort">

<soap:address location="http://localhost:8080/hello" />

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

2、通过wsimport生成java文件,将生成的java类文件复制到项目中。一般在src下新建MATE-INF/WSDL两层文件夹,将文件放进去。

3、删除生成的java文件,只保留生成的接口的.java文件,删除该文件中不需要的代码。注意不要拷贝.class文件进去,因为将来如果要在tomcat里面部署,多余的.class文件会让程序报错。

import javax.jws.WebMethod;

import javax.jws.WebParam;

import javax.jws.WebResult;

import javax.jws.WebService;

import javax.xml.bind.annotation.XmlSeeAlso;

import javax.xml.ws.RequestWrapper;

import javax.xml.ws.ResponseWrapper;

/**

* This class was generated by the JAX-WS RI.

* JAX-WS RI 2.1.1 in JDK 6

* Generated source version: 2.1

*

*/

@WebService(name = "Hello", targetNamespace = "http://www.example.org/hello/")

@XmlSeeAlso({ ObjectFactory.class})

public interface IHelloService {

@WebMethod

@WebResult(name = "addResponse", targetNamespace = "")

@RequestWrapper(localName = "add", targetNamespace = "http://www.example.org/hello/", className = "org.example.hello.Add")

@ResponseWrapper(localName = "addResponse", targetNamespace = "http://www.example.org/hello/", className = "org.example.hello.AddResponse")

public int add(

@WebParam(name = "a", targetNamespace = "")

int a,

@WebParam(name = "b", targetNamespace = "")

int b ,

@WebParam(name="licenceInfo" , header=true) String licenceInfo);

}

4、编写HelloServiceImpl类

@WebService(endpointInterface = "org.example.hello.Hello",

serviceName = "HelloService" , wsdlLocation = "META-INF/wsdl/hello.wsdl" ,

targetNamespace = "http://www.example.org/hello/", portName="HelloServicePort")

public class HelloServiceImpl implements IHelloService {

public int add(int a, int b, String licenceInfo) {

System.out.println(a+b);

System.out.println("licenceInfo:" + licenceInfo );

return a + b;

5、发布service

import javax.xml.ws.Endpoint;

import org.example.hello.HelloServiceImpl;

public class ServiceTest {

public static void main(String[] args) {

Endpoint.publish("http://localhost:8080/mywebservice", new HelloServiceImpl());

二、编写客户端

将wsimort生成的java类添加到客户端。

1、普通方式访问(无法传递头信息,当然可以通过另外编写Handler添加头信息)

import java.net.URL;

import javax.xml.namespace.QName;

import javax.xml.ws.Service;

import org.example.hello.Hello;

public class Client01 {

public static void main(String[] args) throws Exception{

URL url = new URL("http://localhost:8080/mywebservice?wsdl");

String namespace = "http://www.example.org/hello/";

QName sname = new QName(namespace, "HelloService");

Service service = Service.create(url, sname);

IHelloService hello = service.getPort(IHelloService.class);

int result = hello.add(1, 100);

System.out.println(result);

// 或直接调用生成的方法(这是另一个例子,可以仿照写)

// MyServiceImplService mis = new MyServiceImplService();

// IMyService ms = mis.getMyServiceImplPort();

// System.out.println(ms.add(29, 3));

2、拼装SOAPMessage方式访问 (有头信息)

import javax.xml.soap.MessageFactory;

import javax.xml.soap.SOAPBody;

import javax.xml.soap.SOAPBodyElement;

import javax.xml.soap.SOAPEnvelope;

import javax.xml.soap.SOAPHeader;

import javax.xml.soap.SOAPMessage;

import javax.xml.ws.Dispatch;

public class Client02 {

* 带Header的请求

*/

QName sname = new QName(namespace , "HelloService");

QName protName = new QName(namespace, "HelloServicePort");

Dispatch<SOAPMessage> dispatch = service.createDispatch(protName,SOAPMessage.class, Service.Mode.MESSAGE);

SOAPMessage msg = MessageFactory.newInstance().createMessage() ;

SOAPEnvelope env = msg.getSOAPPart().getEnvelope() ;

SOAPBody body = env.getBody() ;

SOAPHeader header = env.getHeader() ;

if(header == null) header = env.addHeader() ;

// 一定要加ns前缀

QName addName = new QName(namespace , "add" , "myprefix");

// 添加Body信息

SOAPBodyElement bodyEle = body.addBodyElement(addName);

bodyEle.addChildElement("a").setValue("1");

bodyEle.addChildElement("b").setValue("2");

// 添加头信息

QName headerName = new QName(namespace , "licenceInfo");

// 设置头信息的值

header.addHeaderElement(headerName).setTextContent("admin");

// 发送前将soap消息打印出来

msg.writeTo(System.out);

System.out.println("----------------relult---------------");

SOAPMessage resultMsg = dispatch.invoke(msg);

// 将返回的soap消息打印出来

resultMsg.writeTo(System.out) ;

继续阅读