`

用cxf生成的方式,开发web service应用

阅读更多
这次开发web service对接,用的是cxf2.0.13

本来只用了cxf的框架,没有使用cxf提供的工具,比如wsdl2java等

这种方式比较简单,主要是根据得到的wsdl文件,手工写接口类以及model类。详细说明见另外一篇博客:http://kyfxbl.iteye.com/blog/1432952

不过发现这种方式生成的wsdl,和原始的wsdl文件有些不一样,担心真正联调的时候跑不通,所以准备了另一套替代方案,就是用wsdl2java工具,来生成代码,保证wsdl完全一致

1、首先用wsdl2java命令,生成所需的java文件,当然前提是已经得到了wsdl文件

wsdl2java -p com.huawei.wfm.czekh.webservice.remedy -d ../../src/remedy -all fileName.wsdl

用上面这个命令,就可以根据wsdl文件,生成所需的所有java文件,参数说明如下:

-p 指定生成java文件的package name
-d 生成java文件的存放路径
-all 生成客户端和服务端代码,这里还可以用-client生成客户端,用-server生成服务端,不过实际上区别不大,只要用-all就可以了
最后一个参数就是目标wsdl文件

2、查看生成的文件列表,可以看到有以下文件:



大部分都是model类,可以不管。以下文件是比较特殊的:

ObjectFactory.java
package-info.java
这2个文件我也不知道是干嘛的,不过反正是不能删的

以_Client结尾的那个文件,是一个客户端,没有用,可以删除
以_Server结尾的那个文件,是启动服务端(貌似是内置的jetty),没有用,可以删除

以Service结尾的那个文件,不但没有用,还要坏事,因为其中有以下代码:
@WebServiceClient(name = "CIP-B2B_ServiceAssuranceWorkForceClientManagementService", wsdlLocation = "file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl", targetNamespace = "http://cz.o2.com/systems/integrationinfrastructure/CIP-B2B/CIP-B2B_ServiceAssuranceWorkForceClientManagement/1.0")

里面有一个"file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl",因为这些类是根据一个本地的wsdl文件生成的,但是实际部署的时候一般不会放这个文件,所以在加载cxf配置的时候,是会出错的
实际上试验发现,这个文件可以直接删掉

以PortType结尾的文件,很关键,是接口类

以PortTypeImpl结尾的文件,是接口类的实现类,其中也有一行注解:
@javax.jws.WebService(
                      serviceName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementService",
                      portName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementPort",
                      targetNamespace = "http://cz.o2.com/systems/integrationinfrastructure/CIP-B2B/CIP-B2B_ServiceAssuranceWorkForceClientManagement/1.0",
                      wsdlLocation = "file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl",
                      endpointInterface = "com.huawei.wfm.czekh.webservice.remedy.CIPB2BServiceAssuranceWorkForceClientManagementPortType")

要把这里的
wsdlLocation = "file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl",

删除

所以在用wsdl2java命令生成java类之后,只需要把XXXService.java、XXX_Client.java、XXX_Server.java删除,把XXXPortTypeImpl.java改一下,就能用了

然后如果是要做客户端的话,就把除了XXXPortTypeImpl.java以外的所有文件拷贝到工程里;如果是做服务端的话,就把所有文件拷贝到工程里,然后根据实际情况修改XXXPortTypeImpl.java就可以了


3、最后是cxf的配置文件,这里和http://kyfxbl.iteye.com/blog/1432952提到的方式是一样的,没有区别

首先是服务端:
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       						http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       						http://www.springframework.org/schema/context 
      			 			http://www.springframework.org/schema/context/spring-context-3.0.xsd
      			 			http://cxf.apache.org/jaxws 
        					http://cxf.apache.org/schemas/jaxws.xsd">

	<context:component-scan base-package="com.huawei.wfm.czekh" />

	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<jaxws:endpoint id="remedy" implementor="#MyWebserviceServer"
		address="/RemedyWebService" />

</beans>

@Component("MyWebserviceServer")
@WebService(serviceName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementService", portName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementPort", targetNamespace = "http://cz.o2.com/systems/integrationinfrastructure/CIP-B2B/CIP-B2B_ServiceAssuranceWorkForceClientManagement/1.0", endpointInterface = "com.huawei.wfm.czekh.webservice.remedy.CIPB2BServiceAssuranceWorkForceClientManagementPortType")
public class CIPB2BServiceAssuranceWorkForceClientManagementPortTypeImpl
		implements CIPB2BServiceAssuranceWorkForceClientManagementPortType {

	@Autowired
	private Test test;

        // 省略无关方法	

	public AcknowledgeResponse acknowledge(
			AcknowledgeRequest body) {

		test.sayHi("somebody");

		AcknowledgeResponseBody responseBody = new AcknowledgeResponseBody();
		responseBody.setStatus(true);
		responseBody.setErrorDescription("wcnm");

		AcknowledgeResponse result = new AcknowledgeResponse();
		result.setResponseBody(responseBody);

		return result;
	}

}

可以看到,配置方式没有变化,也可以用spring进行依赖注入

然后是客户端:
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://cxf.apache.org/jaxws 
						http://cxf.apache.org/schemas/jaxws.xsd">

	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:webservice_address.properties</value>
			</list>
		</property>
	</bean>

	<jaxws:client id="client"
		serviceClass="com.huawei.wfm.remedy.CIPB2BServiceAssuranceWorkForceClientManagementPortType"
		address="${remedy_address}" />

</beans>

public class Main {

	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext(
				"cxf.xml");
		CIPB2BServiceAssuranceWorkForceClientManagementPortType client = (CIPB2BServiceAssuranceWorkForceClientManagementPortType) context
				.getBean("client");

		AcknowledgeRequestBody body = new AcknowledgeRequestBody();
		body.setCustSysId("123456");

		AcknowledgeRequest request = new AcknowledgeRequest();
		request.setRequestBody(body);

		AcknowledgeResponse response = client.acknowledge(request);
		String desc = response.getResponseBody().getErrorDescription();
		System.out.println(desc);

	}

}

客户端的配置也是一样的。有一点要注意,好像只能通过getBean("client")拿到实例化的bean,通过@Autowired可能是搞不定的

4、自动生成的代码,当然是冗余很多的。有时间的话,可以手工进行清理
  • 大小: 67.8 KB
分享到:
评论
9 楼 kyfxbl 2013-01-20  
是的,生成以后原封不动搬过去就好
8 楼 konlin 2013-01-20  
kyfxbl 写道
konlin 写道
我想问下 生成的这些java文件是怎么去分类呢?是一个服务就放一个包,还是把每个服务的bean类,接口或者实现类这样分开放呢?


这并不是我们能控制的,是wsdl2java工具实现的

生成以后,你再自己手工去调整位置,这是强烈不推荐的。我可以理解你的想法,你希望它分类得更清楚一点,但是这些包和类的路径信息,都是在package-info里要用的,在生成的时候就已经规定了,你手工改以后,很可能会有问题

实际上,既然选择了wsdl2java的方式,还是就让工具自己去处理吧,你自己眼不见心不烦就好了

那么就是说,每个服务生成的类就放一个包里面是吧?不要再去调他的位置?因为服务太多了,服务端和客户端加起来有70多个
7 楼 kyfxbl 2013-01-19  
konlin 写道
我想问下 生成的这些java文件是怎么去分类呢?是一个服务就放一个包,还是把每个服务的bean类,接口或者实现类这样分开放呢?


这并不是我们能控制的,是wsdl2java工具实现的

生成以后,你再自己手工去调整位置,这是强烈不推荐的。我可以理解你的想法,你希望它分类得更清楚一点,但是这些包和类的路径信息,都是在package-info里要用的,在生成的时候就已经规定了,你手工改以后,很可能会有问题

实际上,既然选择了wsdl2java的方式,还是就让工具自己去处理吧,你自己眼不见心不烦就好了
6 楼 konlin 2013-01-19  
我想问下 生成的这些java文件是怎么去分类呢?是一个服务就放一个包,还是把每个服务的bean类,接口或者实现类这样分开放呢?
5 楼 konlin 2013-01-19  
我想问下 生成的这些java文件是怎么去分类呢?是一个服务就放一个包,还是把每个服务的bean类,接口或者实现类这样分开放呢?
4 楼 kyfxbl 2013-01-10  
生成这么多类,因为这个服务的参数比较多

这个确实是个问题,我也不太喜欢。不过这个过程是自动的,并不需要你人工干预。生成的类,用户只需要关注接口,以及作为参数的模型类

其他类是用不到的
3 楼 konlin 2013-01-09  
那么每一个服务都要生成这么多的类?是不是太庞大了啊?管理和查找都很麻烦呀
2 楼 kyfxbl 2012-06-11  
这个也是无奈之举,因为WSDL是客户提供的,我们只能自动生成

然后生成以后又不好使,只好手工干预

不过WSDL是相对比较稳定的
1 楼 xiaguangme 2012-06-11  
自动生成代码 手工干预后  会不会不太好?
当这个wsdl有变动 更新,  就要重新生成代码
那么手动更改的那部分代码就麻烦了

相关推荐

Global site tag (gtag.js) - Google Analytics