jdk的wsgen.exe和cxf的wsimport.bat建立简单JAX-WS客户端服务端实践

概要:

实现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文件

猜你喜欢

转载自fall10.iteye.com/blog/2332066