您的位置:首页 > 其它

Web Service_cxf(转载)

2015-08-06 15:53 423 查看
Web Service的优点:

1)平台无关。不管你使用什么平台,都可以使用Web service。

2)编程语言无关。只要遵守相关协议,就可以使用任意编程语言,向其他网站要求Web service。这大大增加了web service的适用性,降低了对程序员的要求。

3)对于Web service提供者来说,部署、升级和维护Web service都非常单纯,不需要考虑客户端兼容问题,而且一次性就能完成。

4)对于Web service使用者来说,可以轻易实现多种数据、多种服务的聚合(mashup),因此能够做出一些以前根本无法想像的事情。
CXF的优势:
Apache CXF是Apache旗下一个重磅的SOA简易框架,它实现了ESB(企业服务总线)。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,不仅提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format
的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。而且可以天然的和Spring进行无缝集成。Apache CXF已经是一个正式的Apache顶级项目。

Jar包下载:去Apache CXF官网http://cxf.apache.org/download.html下载apache-cxf-X.X.X.zip,解压获得apache-cxf-X.X.X/lib下所以jar包。

一:服务端开发

1.首先服务接口。

package com.demo;

import java.util.List;

import javax.jws.WebParam;

import javax.jws.WebService;

@WebService

public interface HelloWorld {

String sayHi(@WebParam(name="text")String text);

String sayHiToUser(User user);

String[] SayHiToUserList(List<User> userList);

}

2.编写服务实现

package com.demo;

import java.util.LinkedHashMap;

import java.util.List;

import java.util.Map;

import javax.jws.WebService;

@WebService(endpointInterface="com.demo.HelloWorld",serviceName="HelloWorld")

public class HelloWorldImpl implements HelloWorld {

Map<Integer, User> users = new LinkedHashMap<Integer, User>();

public String sayHi(String text) {

return "Hello " + text;

}

public String sayHiToUser(User user) {

users.put(users.size()+1, user);

return "Hello "+ user.getName();

}

public String[] SayHiToUserList(List<User> userList) {

String[] result = new String[userList.size()];

int i=0;

for(User u:userList){

result[i] = "Hello " + u.getName();

i++;

}

return result;

}

}

3.发布服务

方法一:使用Sun JAX-WS 2中Endpoint.publish进行发布。(不需要其他配置与

包)

Endpoint endpoint =

Endpoint.publish("http://localhost:8080/WSCXF/helloService", new HelloServiceImpl());//这里是实现类 System.out.println("WS发布成功!");

方法二:用CXF的JaxWsServerFactoryBean类进行发布。(需要CXF相关包)

HelloServiceImpl impl = new HelloServiceImpl();

JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); factoryBean.setAddress("http://localhost:8080/WSCXF/helloService"); factoryBean.setServiceClass(IHelloService.class);//接口类
factoryBean.setServiceBean(impl); factoryBean.create();

System.out.println("WS发布成功!");

方法三:利用cxf和spring整合在tomcat下进行发布。

具体方法在后面的spring整合cxf时讲到。

方法四:重写loadBus方法。

书写一个类覆盖org.apache.cxf.transport.servlet.CXFNonSpringServlet的loadBus方法指定BUS以及发布你的web服务。

具体可查阅资料:

http://blog.csdn.net/zq9017197/archive/2010/12/26/6099684.aspx

4.查看web服务是否发布成功:

方法一二四访问http://localhost:8080/WSCXF/helloService?wsdl 查看wsdl文件,方法三在后面的spring整合cxf时讲到。

二:客户端调用

方法一:使用标准的JAX-WS的API完成客户端调用(不需要导入任何CXF包)

//注意。此处http://service.jaxb.com/ 来源于wsdl文件中targetNamespace

QName qName =
new QName("http://service.jaxb.com/","HelloServiceImplService");

HelloServiceImplService helloServiceImplService = new HelloServiceImplService(

new URL("http://localhost:8080/WSCXF/helloService?wsdl"),qName);

IHelloService helloService
=(IHelloService)helloServiceImplService.getPort(IHelloService.class);

方法二:使用CXF中JaxWsProxyFactoryBean客户端代理工厂调用web服务(需要导入CXF相关包)

JaxWsProxyFactoryBean soapFactoryBean = new JaxWsProxyFactoryBean();

soapFactoryBean.setAddress("http:// localhost:8080/WSCXF/helloService");

soapFactoryBean.setServiceClass(IHelloService.class);

Object o = soapFactoryBean.create();

IHelloService helloService = (IHelloService)o;

方法三:

String endPointAddress = "http:// localhost:8080/WSCXF/helloService";

Service service = Service.create(

new QName("http://service.jaxb.com/","IHelloService"));

service.addPort(

new QName("http://service.jaxb.com/", "IHelloServicePort"), SOAPBinding.SOAP11HTTP_BINDING,
endPointAddress);

IHelloService helloService = service.getPort(IHelloService.class);

方法四:(需要导入CXF相关包)

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

org.apache.cxf.endpoint.Client client =
dcf.createClient("http://127.0.0.1:8080/WSCXF/helloService?wsdl");

//sayHello 为接口中定义的方法名称 张三为传递的参数 返回一个Object数组

Object[] objects=client.invoke("sayHello", "张三");

//输出调用结果

System.out.println(objects[0].toString());

三、CXF和Spring整合服务端开发

1)新建web项目,并添加相关包。(包括spring和cxf相关包) 2)写好一个接口和实现类。(见demo) 3)新建beans.xml文件。

<?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:jaxws="http://cxf.apache.org/jaxws"

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">

<!-- spring发布web服务配置 -->

<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" />

<bean id="helloService" class="com.jaxb.service.HelloServiceImpl" /> <!--

<bean id="helloService" class="com.aegis.service.HelloServiceImpl" /> -->

<!-- endpoint 方式发布web服务和 server方式一样 --> <!--

<jaxws:endpoint id="helloServiceWs" address="/helloService" implementor="#helloService" />

--> <!-- 另一种写法,建议不要用这种方法 ,如果实现类有的属性要通过spring依赖注入的话, 这种方法只是简单的new个实现类,他的属性没有通过spring依赖注入给注入值 --> <!--

<jaxws:endpoint id="helloServiceWs" address="/helloService" implementor="com.jaxb.service.HelloServiceImpl" />

-->

<!—下面这个是wss4j的配置,后面会讲到相关知识,需要配置在spring配置文件中 --> <!-- wss4j 服务端配置 -->

<bean id="wss4jInInterceptor"
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">

<constructor-arg>

<map>

<entry key="action" value="UsernameToken" />

<!-- <entry key="passwordType" value="PasswordText" /> --> <!-- 密码使用MD5密文发送 -->

<entry key="passwordDigest" value="PasswordText" />

<entry key="passwordCallbackClass"
value="com.security.service.ServerPasswordCallbackHandler" />

</map>

</constructor-arg>

</bean>

<jaxws:server id="helloServiceWs" address="/helloService"> <jaxws:serviceBean>

<ref bean="helloService" />

</jaxws:serviceBean><!-- 使用这种方法发布web服务 --> <jaxws:inInterceptors>

<ref bean="wss4jInInterceptor" />

</jaxws:inInterceptors><!—wss4j配置 --> <!-- <jaxws:serviceFactory>

<ref bean="jaxWsServiceFactoryBean" />

</jaxws:serviceFactory> --><!—数据绑定方式配置 -->

</jaxws:server>

<!-- 通过Spring创建数据绑定的类-->

<!-- <bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" /> <bean id="jaxWsServiceFactoryBean"

class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"> <property name="wrapped" value="true" /> <property name="dataBinding" ref="aegisBean"
/> </bean> --> </beans>

4)配置web.xml

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/beans.xml</param-value>

</context-param>

<listener>

<listener-class>
org.springframework.web.context.ContextLoaderListener </listener-class>

</listener>

<!—在tomcat中发布需要配置servlet -->

<servlet>

<servlet-name>CXFServlet</servlet-name>

<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

<load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/ws/*</url-pattern>

</servlet-mapping>

5)发布web项目

因为在web.xml里面配置了servlet,则可以将项目发布到tomcat下,启动tomcat即可。

6)访问wsdl
http://localhost:8080/WSCXF/ws/helloService?wsdl
四、CXF和Spring整合客户端调用

1)新建一个web客户端项目,用wsdl2java生成客户端代码。将生成的客户端代码拷贝到src下。添加spring相关包。

2)配置spring配置文件。

beans.xml存放在src目录下,具体配置如下:

<?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:jaxws="http://cxf.apache.org/jaxws"

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">

<!-- wss4j 配置在客户端,后面有讲到相关知识 -->

<!-- wss4j 客户端配置 --> <bean id="wss4jOutInterceptor"

class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">

<constructor-arg>

<map>

<entry key="action" value="UsernameToken" />

<entry key="user" value="Fetion" />

<!-- <entry key="passwordType" value="PasswordText" /> --> <!-- 密码使用MD5密文发送 -->

<entry key="passwordDigest" value="PasswordText" />

<entry key="passwordCallbackClass"
value="com.security.client.ClientPasswordCallbackHandler" />

</map>

</constructor-arg>

</bean>

<jaxws:client id="helloServeiceClient"
address="http://localhost:8080/WSCXF/ws/helloService" serviceClass="com.jaxb.client.IHelloService">

<jaxws:outInterceptors>

<ref bean="wss4jOutInterceptor" />

</jaxws:outInterceptors><!-- wss4j 客户端配置-->

</jaxws:client>

</beans>

2) 调用web服务 在main方法中运行:

ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");//此处beans.xml放在src下,也需要放在其他目录下,但需要注明清楚

//获取webservice服务的操作接口

IHelloService helloService = (IHelloService)app.getBean("helloServeiceClient");

五、基于soap的web服务的WS-Security安全规范
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: