Java发布webservice的方式很多,如CXF、XFire、Axis2等,这里介绍另外一种方式,JDK原生支持的一种方式,不需要额外引入任何jar包,那就是JAX-WS。
使用JAX-WS开发WebService只需要很简单的几个步骤:
1、写接口和实现(也可以不拆分,就是普通的不继承任何接口的业务处理类)
2、发布
3、使用命令wsimport构建WebService客户端。
4、服务调用
1、首先是接口的编写,
接口中只需要把类注明为@WebService,
把要暴露给客户端的方法注明为@WebMethod即可。
package com.service; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public class UserService { @WebMethod public String get(String name){ return "你好,"+name; } }
2、发布
import javax.xml.ws.Endpoint; import com.service.UserService; public class Test{ public static void main(String[] args) throws Exception { String address2 = "http://localhost/webservice/user"; Endpoint.publish(address2, new UserService()); System.out.println("webservice发布成功!"); } }
服务发布成功后,main方法并没有终止,而是会启动后端线程监听服务调用,并提供服务。
服务发布成功后,可以访问服务描述文件。
http://localhost/webservice/user?wsdl
<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://service.com/" name="UserServiceService"> <types> <xsd:schema> <xsd:import namespace="http://service.com/" schemaLocation="http://localhost/webservice/user?xsd=1"></xsd:import> </xsd:schema> </types> <message name="get"> <part name="parameters" element="tns:get"></part> </message> <message name="getResponse"> <part name="parameters" element="tns:getResponse"></part> </message> <portType name="UserService"> <operation name="get"> <input wsam:Action="http://service.com/UserService/getRequest" message="tns:get"></input> <output wsam:Action="http://service.com/UserService/getResponse" message="tns:getResponse"></output> </operation> </portType> <binding name="UserServicePortBinding" type="tns:UserService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding> <operation name="get"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal"></soap:body> </input> <output> <soap:body use="literal"></soap:body> </output> </operation> </binding> <service name="UserServiceService"> <port name="UserServicePort" binding="tns:UserServicePortBinding"> <soap:address location="http://localhost/webservice/user"></soap:address> </port> </service> </definitions>
3、使用命令wsimport构建WebService客户端。
任意处新建文件夹,并cmd到该路径下,执行命令:wsimport -keep http://localhost/webservice/user?wsdl
进入该文件夹下,可以看到生成的客户端代码。
生成的这些文件不需要修改,我们调用上面发布的webservice服务时,会用到。
4、借助自动生成的客户端代码调用webservice服务。
public class Test { public static void main(String[] args) { UserServiceService userServiceService = new UserServiceService(); UserService userService = userServiceService.getUserServicePort(); String result = userService.get("张三"); System.out.println(result); } }
上面代码中UserServiceService 和 UserService两个类就是自动生成的类。
上面代码输出结果:你好,张三
捕获请求数据说明:
上面调用webservice接口时,webservice客户端会自动发送两次请求,
第一次请求是拉取(GET)服务描述信息,
第二次请求是调用(POST)业务API。
抓包数据(为方便抓包,重新发布了服务地址:http://localhost:8080/cloud-web/user):
=====================首次请求========================
请求url http://localhost:8080/cloud-web/user
请求编码 UTF-8
请求method: GET
请求body:
=====================header信息==========
user-agent Java/1.8.0_131
host localhost:8080
accept text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
connection keep-alive
===================parameter信息==========
wsdl
=====================二次请求========================
请求url http://localhost:8080/cloud-web/user
请求编码 UTF-8
请求method POST
请求body
<?xml version="1.0" ?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:get
xmlns:ns2="http://service.com/">
<arg0>张三</arg0>
</ns2:get>
</S:Body>
</S:Envelope>
=====================header信息=========
accept text/xml, multipart/related
content-type text/xml; charset=utf-8
soapaction "http://service.com/UserService/getRequest"
user-agent JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
host localhost:8080
connection keep-alive
content-length 186
补充说明1;
业务类分为接口和实现类的示例:
接口代码
@WebService public interface HelloWorld { @WebMethod public String hello(String name); }
实现类代码
@WebService public class HelloWordImpl implements HelloWorld { @Override public String hello(String name) { System.out.println("接收到参数:"+name); return "hello :"+name; } }
发布服务代码
String address="http://localhost/webservice/hello"; Endpoint.publish(address, new HelloWordImpl());
补充说明2:
以上在jdk8下开发测试。