基于JAX的WebService实现demo(一)

来源:互联网 发布:linux中history d命令 编辑:程序博客网 时间:2024/05/29 14:00

JAX-WS(Java API for XML Web Services),它是Java程序设计语言一个用来创建Web服务的API。

       在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI(Service Endpoint Interface),并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。

       在客户端,调用者可以通过JAX-WS的API创建一个代理来实现对于远程服务器端的调用。

      

       以下给出一种简单的实现方式:

        一、服务端代码

      1.服务端接口PersonService.java

import javax.jws.WebService;import javax.jws.soap.SOAPBinding;import javax.jws.soap.SOAPBinding.*;@WebService(name = "myPersonService",//指定WSDL契约中的portType(定义服务的接口)元素的name属性的值,默认为实现类的类名        targetNamespace = "http://www.test.com",//指定目标命名空间在哪个服务下定义,默认由包名得到        wsdlLocation = "http://www.test.com/person?wsdl")//指定服务契约存储的URI,默认为部署的URI@SOAPBinding(style= Style.RPC, //指定SOAP消息的样式:RPC,DOCUMENT(默认)        use = Use.LITERAL,//指定SOAP消息数据如何传输        parameterStyle = ParameterStyle.WRAPPED)//指定方法参数在SOAP消息体中的显示方式(如果style使用RPC,那么必须使用WRAPPED)public interface PersonService {    public void eat();    public void sleep();}
      2.服务端接口实现类PersonServiceImpl.java
import com.dj.demo.ws.jax.PersonService;import javax.jws.WebService;@WebService(endpointInterface = "com.dj.demo.ws.jax.PersonService",//指定服务接口实现类全路径名        targetNamespace = "http://www.test.com",//指定服务在哪个命名空间下定义        portName = "person",//指定服务发布端的名称,即WSDL中port元素,默认为实现类名称        serviceName = "PersonService")//指定被发布的服务的名称,即WSDL中service元素,默认为实现类名称public class PersonServiceImpl implements PersonService {    @Override    public void eat() {        System.out.println("person eat");    }    @Override    public void sleep() {        System.out.println("person sleep");    }}
      3.发布服务PersonServer.java
import com.dj.demo.ws.jax.impl.PersonServiceImpl;import javax.xml.ws.Endpoint;public class PersonServer {    public static void main(String[] args){        String address = "http://localhost:8888/person";        Endpoint.publish(address, new PersonServiceImpl());    }}

     

      运行服务端,在浏览器中输入http://localhost:8888/person?wsdl,会出现以下的结果:

<definitions targetNamespace="http://www.test.com" name="PersonService"><types/><message name="eat"/><message name="eatResponse"/><message name="sleep"/><message name="sleepResponse"/><portType name="myPersonService"><operation name="eat"><input message="tns:eat"/><output message="tns:eatResponse"/></operation><operation name="sleep"><input message="tns:sleep"/><output message="tns:sleepResponse"/></operation></portType><binding name="personBinding" type="tns:myPersonService"><soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/><operation name="eat"><soap:operation soapAction=""/><input><soap:body use="literal" namespace="http://www.test.com"/></input><output><soap:body use="literal" namespace="http://www.test.com"/></output></operation><operation name="sleep"><soap:operation soapAction=""/><input><soap:body use="literal" namespace="http://www.test.com"/></input><output><soap:body use="literal" namespace="http://www.test.com"/></output></operation></binding><service name="PersonService"><port name="person" binding="tns:personBinding"><soap:address location="http://localhost:8888/person"/></port></service></definitions>

      二、客户端代码

      1.客户端接口(和服务端相同)PersonService.java

import javax.jws.WebService;import javax.jws.soap.SOAPBinding;import javax.jws.soap.SOAPBinding.*;@WebService(name = "myPersonService",//指定WSDL契约中的portType(定义服务的接口)元素的name属性的值,默认为实现类的类名        targetNamespace = "http://www.test.com",//指定目标命名空间在哪个服务下定义,默认由包名得到        wsdlLocation = "http://www.test.com/person?wsdl")//指定服务契约存储的URI,默认为部署的URI@SOAPBinding(style= Style.RPC, //指定SOAP消息的样式:RPC,DOCUMENT(默认)        use = Use.LITERAL,//指定SOAP消息数据如何传输        parameterStyle = ParameterStyle.WRAPPED)//指定方法参数在SOAP消息体中的显示方式(如果style使用RPC,那么必须使用WRAPPED)public interface PersonService {    public void eat();    public void sleep();}
      2.客户端调用服务端测试类PersonClient.java
import javax.xml.namespace.QName;import javax.xml.ws.Service;import java.net.MalformedURLException;import java.net.URL;public class PersonClient {    public static void main(String[] args){        URL url = null;        try {            url = new URL("http://localhost:8888/person?wsdl");        } catch (MalformedURLException e) {            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.        }        if(null != url){            QName qName = new QName("http://www.test.com", "PersonService");            Service service = Service.create(url, qName);            PersonService personService = service.getPort(PersonService.class);            while(true){                //调用了Server端提供的服务                personService.eat();                personService.sleep();                try {                    Thread.sleep(3000);                } catch (Exception e){                    e.printStackTrace();                }            }        }    }}

      运行后,我们发现,客户端调用服务端发布的服务成功了!

      以上实例中,细心一点,我们会发现,客户端的调用仍然依赖于服务端的接口(必须定义和服务端相同的接口才能访问)。我们将在后续的学习中,对该程序进行改进。