概要:
实现Java SOAP WebService目前有多种API/框架实现(JAX-WS,CXF,Axis2,XFire),记录一下仅通过JAX-WS库实现SOAP WebService 服务/客户端的过程;
如果使用IDE插件这个过程更简单,下面记录不通过IDE实现客户端及部署开放服务端接口。
环境:
JDK1.7,
Tomcat7,
jaxws-ri-2.2.8\jaxws-ri\lib\*,
Apache CXF wsdl2java.bat(cxf3.1.6)。
基本流程:
1,服务端:建立Dynamic Java Web Project,加入必要的类库(jaxws-ri-2.2.8\jaxws-ri\lib\*)
2,服务端:建立WebService服务类和服务方法
3,服务端:配置web.xml WSServlet和WSServletContextListener
4,服务端:配置sun-jaxws.xml的endpoint
5,服务端:部署WebService的Project,运行
6,客户端:使用cxf的wsimport.bat根据wsdl(URL)生成客户端调用代理代码。
7,客户端:测试。
详细流程:
1,略
2,步骤代码:
package wsgen.test1;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService(targetNamespace = "http://merrick.wsgen.test/", serviceName = "WSGen1Service", portName = "WSGen1Port")
public class WSGen1 {
@WebMethod
public String method1(String par1){
return par1 + ",hello!";
}
}
3,配置代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<servlet>
<description>
JAX-WS endpoint
</description>
<servlet-name>WSIMPORTtest</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener
</listener-class>
</listener>
</web-app>
4,配置Endpoint
<?xml version = "1.0"?>
<endpoints version="2.0"
xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
<endpoint name="WSGen1Port" implementation="wsgen.test1.WSGen1"
url-pattern="/WSGen1Port">
</endpoint>
</endpoints>
5,略
6,生成步骤,因为直接使用jdk的wsimport.exe产生了问题,原因及过程引用如下,改用cxf的wsimport.bat:
JDK提供了一个wsimport.exe的命令,主要是用于将WebService生成客户端代码,然后好调用WebService。
wsimport 是根据JDK1.6.0_21及以上的生成本地代码的,它只能解析服务器端的SOAP协议为1.1,不能解析SOAP1.2的协议。如果解析SOAP1.2 将会解析不完全。
用法:前提是已经将JDK配置为了path环境变量 C:\Documents and Settings\Administrator>wsimport -s F:\ -p com.client.jdk.wsimport http://localhost:1111/hello?wsdl
-s 后面指定生成文件的路径,-p 自定义类包 http://localhost:1111/hello?wsdl 是wsdl的路径。
CXF也提供了根据WSDL生成客户端代码的命令wsdl2java(bat)。它是根据jdk1.7生成的本地代码,所以,需要对生成的代码做一点点修改。
它可以支持SOAP1.1 和SOAP1.2的协议。前提是你已经下载了Apache CXF 并且将wsdl2java.exe配置为了path环境变量。
用法:C:\Documents and Settings\Administrator>wsdl2java -d F:\ -p com.client.cxf http://localhost:1111/hello?wsdl
-d 后面指定生成文件的路径,-p 自定义类包 http://localhost:1111/hello?wsdl 是wsdl的路径。
-------------------------采用jdk1.7的wsimport.exe的错误日志,如下:
D:\>wsimport -keep -p a.b.c http://localhost:8080/wsgenwsimporttest1/WSGen1Port?wsdl
parsing WSDL...
[ERROR] Server returned HTTP response code: 403 for URL: http://localhost:8080/wsgenwsimporttest1/WS
Gen1Port?wsdl
Failed to read the WSDL document: http://localhost:8080/wsgenwsimporttest1/WSGen1Port?wsdl, because
1) could not find the document; /2) the document could not be read; 3) the root element of the docum
ent is not <wsdl:definitions>.
[ERROR] failed.noservice=Could not find wsdl:service in the provided WSDL(s):
At least one WSDL with at least one service definition needs to be provided.
Failed to parse the WSDL.
------------------------------------采用cxf的wsdl2java.bat正确日志,如下:
D:\SDK_java\apache-cxf-3.1.6\bin>wsdl2java -d e:\wsimporttest1 -p a.b.c http://localhost:8080/wsgenwsimporttest1/WSGen1Port?wsdl
D:\SDK_java\apache-cxf-3.1.6\bin>
------------------------说明
wsimport,用于根据jax-ws标准的wsdl文件生成客户端调用基础类及客户端jaxb
-d 生成客户端执行类的class文件的存放目录
-s 生成客户端执行类的源文件的存放目录
-p 定义生成类的包名
-------------------生成的客户端代码:
package a.b.c中代码包括
Client1.java
Method1.java
Method1Response.java
ObjectFactory.java
package-info.java
WSGen1.java
WSGen1Service.java
7,调用,测试
根据Service Port调用接口方法:
public class Client1 {
public static void main(String[] args) {
URL u;
try {
u = new URL("http://localhost:8080/wsgenwsimporttest1/WSGen1Port?wsdl");
WSGen1Service c = new WSGen1Service(u);
String r = c.getWSGen1Port().method1("merrick");
System.out.println(r);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
后记:
可以使用wsgen.exe生成wsdl文件,再使用该文件生成客户端。
D:\>wsgen -verbose -keep -cp D:\workspace_ElipseJEE_mars2\prj201601\bin wsgen.test1.WSGen1 -r E:\wsgentest1 -s E:\wsgentest1\src -d E:\wsgentest1\bin -wsdl
--------------------------------------说明
wsgen用于根据jax-ws的初始服务接口类(@WebService指定)生成对应用于部署WebService服务的WSDL文件及其他jaxb文件(xml bean)
-cp 定义classpath[指定java类编译后的.class文件所在的主包路径]
-r 生成 bean的wsdl文件的存放目录
-s 生成发布Web Service的源代码文件的存放目录(如果方法有抛出异常,则会生成该异常的描述类源文件)
-d 生成发布Web Service的编译过的二进制类文件的存放目录(该异常的描述类的class文件)
-verbose 编译信息
-wsdl 生成wsdl文件