Java6开发WebService例子
1.新建一个web工程wstest
? 用Eclipse,点击右键新建一个web工程即可。
2.创建包
com.test.ws
3.创建服务端类文件 com.test.ws.Hello.java
package com.test.ws;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;import javax.xml.ws.Endpoint;import javax.jws.soap.SOAPBinding.Style;@WebService@SOAPBinding(style = Style.RPC)public class Hello {/** * Web服务中的业务方法 * * @return 一个字符串 */public String sayHi(String name) {return "hi," + name;}public static void main(String[] args) {// 发布一个WebServiceEndpoint.publish("http://localhost:81/hello", new Hello());}}
?
注意:由于JDK版本的关系,我所用的版本必须加上@SOAPBinding(style=Style.RPC)?,否则会报错"Wrapper class com.test.ws.jaxws.SayHi is not found. Have you run APT to generate them?"。
4.测试服务器端程序
??? (1)运行Hello.java
??? (2)在浏览器中输入:http://localhost:81/hello?wsdl? 即可看到相应的描述信息
?
5.创建客户端?
? (一)方式一,自动创建
????? (1)进入DOS命令行状态,并进入wstest项目的src目录?
????? (2)执行如下命令:
??????? D:\workspace\wstest\src>wsimport -p com.test.ws.client -keep http://localhost:81/hello?wsdl
??????? 注意:一定要先运行Hello.java,保持服务先开启,否则会报错
????? (3)进入Eclipse中,按F5刷新wstest项目,会发现com.test.ws会多了一个目录client,并且client目录下自动创建了四个文件:Hello.class、Hello.java、HelloService.class、HelloService.java?
????? (4)新建一个客户端测试类com.test.ws.client.TestClient.java
package com.test.ws.client;public class TestClient {public static void main(String args[]) {Hello hello = new HelloService().getHelloPort();String msg = hello.sayHi("tom");System.out.println(msg);}}
????? (5)运行TestClient.java, 会输出如下结果:
??????????? hi, tom
?
(二)方式二,手工创建客户端
(1)创建服务端对应的接口com.test.ws.client.HelloInte.java
package com.test.ws.client;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;@WebService(name = "Hello", targetNamespace = "http://ws.test.com/")@SOAPBinding(style = SOAPBinding.Style.RPC)public interface HelloInte {@WebMethod@WebResult(partName = "return")public String sayHi(@WebParam(name = "arg0", partName = "arg0") String arg0);}
(2)创建客户端测试类 com.test.ws.client.TestClient.java
package com.test.ws.client;import javax.xml.namespace.QName;import javax.xml.ws.Service;import java.net.URL;public class TestClient {public static void main(String[] args) throws Exception {URL url = new URL("http://localhost:81/hello?wsdl");// 第一个参数是服务的URI// 第二个参数是在WSDL发布的服务名QName qname = new QName("http://ws.test.com/", "HelloService");// 创建服务Service service = Service.create(url, qname);// 提取端点接口,服务“端口”。HelloInte h = service.getPort(HelloInte.class);System.out.println(h.sayHi("michael"));System.out.println(h.sayHi("tom"));}}
(3)运行 TestClient, 会出现如下结果:?
??????? hi,michael
??????? hi,tom
补充:为了验证服务端与客户端的相关性,停掉Hello.java后,再次执行TestClient.java,则会报错。说明客户端的访问是与服务器端相关的。
6.WEB方式部署
(1)创建com.test.ws.client.servlet.PubServlet.java
package com.test.ws.servlet;import java.io.IOException;import javax.servlet.GenericServlet;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.xml.ws.Endpoint;import com.test.ws.Hello;public class PubServlet extends GenericServlet {public PubServlet() {super();}public void destroy() {super.destroy();}@Overridepublic void init() throws ServletException {super.init();System.out.println("start run webservice...");Endpoint.publish("http://localhost:81/hello", new Hello());System.out.println("Webservice is running...");}@Overridepublic void service(ServletRequest arg0, ServletResponse arg1)throws ServletException, IOException {}}
(2)修改web.xml
<servlet> <servlet-name>PubServlet</servlet-name> <servlet-class>com.test.ws.servlet.PubServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>PubServlet</servlet-name> <url-pattern>/servlet/PubServlet</url-pattern> </servlet-mapping>
?
注意:此处要让PubServlet自动启动,所以要设load-on-startup为1。
(3)发布完成,启动web服务
(4)运行TestClient.java测试
7.小结
(1)不管是直接通过main()方法运行,还是通过servlet来发布,其实都是在执行Endpoint.publish()方法
(2)在web中发布时,webservice所用的端口必须跟web容器所用的端口分开
(3)与xfire相比,通过此种方式不用再倒入第三方包,开发起来比较方便。不过,我个人还是比较喜欢xfire的方式。目前这种客户端的实现让我觉得不太爽。另外,它在web容器中的发布也没有xfire方便。