一、简介
什么是Web Services
Web service 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web来调用这个应用程序。
基于浏览器的瘦客户应用程序,即BS 结构,是目前流行的,使得Web Services的应用越来越广泛。Web Services 是一种构建应用程序的模型,并能在所有支持 Internet 通讯的操作系统上实施运行。Web Services 令基于组件的开发和 Web 的结合达到最佳,基于组件的对象模型,利用 SOAP 和 XML对这些模型在通讯方面作了进一步的扩展以消除特殊对象模型的障碍。因为是使用XML作为传输的介质,所以可以跨平台跨语言。
Web Services 实现远程访问,有点类似RMI(远程方法调用)。 但它是利用 HTTP 和 SOAP 协议是商业数据在 Web 上传输,SOAP通过 HTTP 调用商业对象执行远程功能调用,Web 用户能够使用 SOAP 和 HTTP通过 Web 调用的方法来调用远程对象。
Web Services结构
客户根据WSDL描述文档,会生成一个 SOAP 请求消息。Web Services 都是放在Web服务器上面,客户生成的SOAP请求会被嵌入在一个HTTP POST请求中,发送到 Web 服务器来。Web 服务器再把这些请求转发给 Web Services 请求处理器。请求处理器的作用在于,解析收到的 SOAP 请求,调用 Web Services,然后再生成相应的 SOAP 应答。Web 服务器得到 SOAP 应答后,会再通过 HTTP应答的方式把信息送回到客户端。
什么是WSDL
WSDL是WebServicesDescriptionLanguage的缩写,是一个用来描述Web服务和说明如何与Web服务通信的XML语言。Web Services服务器把一个对像绑定到一个URL 上(如http://localhost:8080/webservices/hello),客户端就可以能过绑定的地址(如:http://localhost:8080/webservices/hello?wsdl)取得WSDL文件,该文件是标准的XML 格式,描述了被绑定对像的信息,包括可调用的方法,参数,及参数类型,返回值类型,异常类型等。客户端就是通过这些信息调用服务器的方法。
二、JDK6对Web Services的支持
JDK6提供了对Web Service原生的支持,对Web Service进行了完美的封装,完全隐藏了底层内容,甚至可以不用了解wsdl的具体规范。使用Web Service就像使用本地方法一样简单。下面来举个例子,依然从最简单的例子入手。
?
?
package test1; import java.io.Serializable; /** * @author zhuc * @version 2012-5-20 下午7:48:52 */ public class Car implements Serializable{ /** * */ private static final long serialVersionUID = 606544377239576049L; private String name; private Integer capacity; /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the capacity */ public Integer getCapacity() { return capacity; } /** * @param capacity the capacity to set */ public void setCapacity(Integer capacity) { this.capacity = capacity; } }?
?
?
package test1; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; /** * @author zhuc * @version 2012-5-20 下午7:47:52 */ @WebService @SOAPBinding(style = SOAPBinding.Style.RPC) public class Message { /** * @param userName * @return */ @WebMethod(operationName = "toSayHello", action = "sayHello", exclude = false) @WebResult(name = "returnWord") // 自定义该方法返回值在WSDL中相关的描述 public String sayHello(@WebParam(name = "userName") String userName) { return "Hello:" + userName; } /** * @param name * @return * @throws Exception */ @WebMethod(operationName = "getCar", action = "getCar") @WebResult(name = "returnCar") public Car getCar(String name) throws Exception{ Car c = new Car(); c.setName(name); c.setCapacity(100); System.out.println("return a Car: " + name); return c; } }?
使用命令 wsgen -cp ./bin -r ./src/test1/wsgen -s ./src -d ./bin -wsdl test1.Message ,得到wsdl文件
(需要先在工程目录下src/test1下新建目录wsgen)
如果发布webservice的java类的方法中有异常声明,wsgen命令会在test1目录下自动新建目录jaxws,并生成Exception实体bean类,如本例中生成ExceptionBean.java (在指定的wsgen目录中生成wsdl文件和xsd文件)
?
?
?
而后发布Web Service
?
?
package test1; import javax.xml.ws.Endpoint; /** * @author zhuc * @version 2012-5-20 下午7:53:00 */ public class StartServer { /** * @param args */ public static void main(String[] args) { Endpoint.publish("http://localhost:8080/Message", new Message()); System.out.println("Server已启动"); // wsgen -cp ./bin -r ./src/test1/wsgen -s ./src -d ./bin -wsdl test1.Message // wsimport -d ./bin -s ./src -p wsimport.url http://localhost:8080/Message?wsdl // wsimport -d ./bin -s ./src -p wsimport.file ./src/test1/wsgen/MessageService.wsdl } }
?
?
在浏览器中输入url? http://localhost:8080/Message?wsdl? 即可发现WebServices 已发布成功。
?
客户端调用
还是在工程目录下使用wsimport命令,根据wsdl描述生成的客户端执行类,下面2种方式都可以。
wsimport -d ./bin -s ./src -p wsimport.url http://localhost:8080/Message?wsdl
wsimport -d ./bin -s ./src -p wsimport.file ./src/test1/wsgen/MessageService.wsdl?
(关于wsgen和wsimport的具体和使用方法清参考文章 http://zhuchengzzcc.iteye.com/blog/1535066 )
?我们发现2种方式wsimport生成的客户端文件完全一样,接着我们只要新建一个客户端测试类执行(RunClient.java)。
package wsimport.url; /** * @author zhuc * @version 2012-5-20 下午8:20:23 */ public class RunClient { /** * @param args * @throws Exception_Exception */ public static void main(String[] args) throws Exception_Exception { MessageService ms = new MessageService(); Message m = ms.getMessagePort(); System.out.println("客户端打印:"); System.out.println(m.toSayHello("hello, java6 webservice")); Car c = m.getCar("zhuc-car"); System.out.println(c.getName()); System.out.println(c.getCapacity()); } }?
输出结果:
客户端打印:
Hello:hello, java6 webservice
zhuc-car
100
Hello:hello, java6 webservice
zhuc-car
100