Web Service应用之CXF开发

Web Service应用之CXF开发

web service应用之JAX-WS开发链接:http://blog.csdn.net/sinat_32366329/article/details/79085602

简介

Apache CXF =Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First,根据已经存在的代码进行约定、描述服务)或者 WSDL 优先(WSDL First,以wsdl等描述服务,从头开始构建实现服务)来轻松地实现 Web Services 的发布和使用。官网地址:http://cxf.apache.org

Apache CXF 是一个开源的Services 框架,像JAX-WS。它的特点:

l 支持多种协议SOAP1.1,1,2、Http

l 可以与Spring进行快速无缝整合部署灵活

l 可以运行在Tomcat,Jboss,Jetty(内置),IBMWS,BeaWS上面

技术支持

1.jax-ws的支持

CXF实现了jax-ws 的API使得构建web服务更加简单。jax-ws包含许多不同的领域。例如:1)从Java类生成WSDL和从WSDL生成Java类。2)提供的API允许创建简单的消息接收服务器端点。3)允许发送原始的XML格式消息服务器端点等。

2.spring的支持

CXF支持了Spirng 2.0的XML语法,使得更加容易与Spring整合注入项目。可以通过Spring的配置文件发布接口。

3.RESTful服务

CXF通过使用HTTP绑定的注释支持rest式服务的开发。使用URL模板和注解,可以将服务绑定到URL或者VERB组合中。例如可以使用@Get@HttpResource("/customers/{id}")来注解自定义方法。CXF将监听URL上的GET请求,使用{id}位置的参数作为服务器参数。

4.WS-*的支持

CXF还支持多种的web service协议包括:1)WS-Addressing。2)WS-Policy。3)WS-ReliableMessaging。4)WS-Security。

5.支持模块一览

CXF应用

1.   服务端

2.wsdl2java

在cxf中,也提供了一个用于生成客户端调用代码的工具wsdl2java。它的功能和wsimport一样,都可以生成客户端代码。常用的参数有:

 

-d 生成的代码所在目录,不指定则为当前目录

-p 生成的代码所在包

-h 查看帮助

 

【注意】该工具在cxf的bin目录下,如果想在其它目录中使用则需要设置cxf的bin目录在环境变量中。

2.1.wsdl2java安装与配置

下载“apache-cxf-x.x.x.zip”包,解压后包括如下文件:

bin:批处理执行文件,是 CXF 框架中所提供的代码生成、校验、管理控制台等

docs:api文档

etc:配置信息文件

lib:cxf与使用到的依赖包;WHICH_JARS文件中有详细说明。

licenses:授权说明

samples:示例

 

【配置】若使用cxf提供的代码生成工具,需要配置cxf的bin目录到系统环境变量path中。

3.客户端

利用wsdl2java生成客户端代码:

wsdl2java-p com.rabbit.ws.client.hello http://127.0.0.1:9085/ws/hello?wsdl

客户端代码调用:


1.   总结

使用cxf与jax-ws一样可以发布Web Service服务,步骤如下:

1、编写服务实现类并添加@WebService注解;

2、使用cxf自带的客户端代码生成工具wsdl2java,生成客户端代码;

3、利用客户端代码调用服务

2.   拦截器

Cxf有2种拦截器,InInterceptor、OutInterceptor,顾名思义,InInterceptor可以处理soap请求消息,OutInterceptor可以处理soap响应消息。

所有的拦截器都继承自AbstractPhaseInterceptor<?>,此抽象拦截器实现了Interceptor接口!这个类可以指定继承它的拦截器在什么阶段被启用,阶段属性可以通过org.apache.cxf.phase.Phase 中的常量指定值。CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处理。

Cxf的拦截器是可以在客户端和服务端都可以使用的,in/out都是soap消息相对于客户端或服务器端而言。


日志拦截器

LoggingInInterceptor 信息输入时的拦截器(请求);LoggingOutInterceptor信息输出时的拦截器(响应)。可以在客户端和服务器端都添加这两个拦截器;查看在请求和响应时的消息。

 

服务端添加日志拦截器:

客户端添加日志拦截器:

自定义拦截器

一般拦截器可以用于鉴权,在客户端发送消息之前对soap消息添加头部信息(包含权限信息);然后在服务器端接收到消息后对头部信息进行权限判断是否正确,如果对则调用服务,否则返回失败信息。以此;需要在服务器端添加输入拦截器,而在客户端添加输出拦截器。

服务端输入拦截器

在服务器端的输入拦截器主要在调用方法之前,校验soap消息的头部是否存在约定的权限相关信息。

鉴权输入拦截器:


package com.rabbit.ws.cxf.interceptor;

import java.util.List;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class AuthInInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	private String uid;
	private String psw;

	public AuthInInterceptor(String uid, String psw) {
		//在调用服务类中的方法之前进行拦截
		super(Phase.PRE_INVOKE);
		
		this.uid = uid;
		this.psw = psw;
	}

	@Override
	public void handleMessage(SoapMessage soapMessage) throws Fault {
		List<Header> headers = soapMessage.getHeaders();
		
		if(headers == null || headers.size() < 1){
			throw new Fault(new IllegalArgumentException("没有鉴权消息。"));
		}
		
		Header header = headers.get(0);
		
		//获取auth标签
		Element authElement = (Element)header.getObject();
		//获取uid标签
		NodeList uidList = authElement.getElementsByTagName("uid");
		String uid = uidList.item(0).getTextContent();
		
		//获取psw标签
		NodeList pswList = authElement.getElementsByTagName("psw");
		String psw = pswList.item(0).getTextContent();
		
		if(!(this.uid.equals(uid) && this.psw.equals(psw))){
			throw new Fault(new IllegalArgumentException("鉴权失败。"));
		}
		
	}

}


在发布时添加鉴权输入拦截器:
客户端输出拦截器

在客户端的输出拦截器主要是在发送soap请求前,自动的为soap消息头部添加权限相关信息。

鉴权输出拦截器:

Package com.rabbit.ws.client.interceptor;

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class AuthOutInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
	
	private String uid;
	private String psw;

	public AuthOutInterceptor(String uid, String psw) {
		//准备发送时拦截
		super(Phase.PREPARE_SEND);
		this.uid = uid;
		this.psw = psw;
	}


	@Override
	public void handleMessage(SoapMessage soapMessage) throws Fault {
		
		//对soap消息添加头部信息,添加如下信息:
		/**
		 * <auth>
		 *    <uid>liao</uid>
		 *    <psw>123456</psw>
		 * </auth>
		 */
		List<Header> headers = soapMessage.getHeaders();
		
		//创建document文档对象
		Document document = DOMUtils.createDocument();
		Element authEle = document.createElement("auth");
		
		Element uidEle = document.createElement("uid");
		uidEle.setTextContent(this.uid);
		Element pswEle = document.createElement("psw");
		pswEle.setTextContent(this.psw);
		
		//添加节点
		authEle.appendChild(uidEle);
		authEle.appendChild(pswEle);
		
		headers.add(new Header(new QName(""),authEle));
	}

}

在发送消息之前添加鉴权输出拦截器:

Spring整合CXF核心配置         

服务端

服务类


@WebService
public interface IHelloWeb {

	public String sayHello(String name);
}
public class HelloWebImpl implements IHelloWeb {

	@Override
	public String sayHello(String name) {
		return "Hello Spring,"+name;
	}

}

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xmlns:cxf="http://cxf.apache.org/core" 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-4.1.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
	http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<!-- 引入cxf配置 
	<import resource="classpath:META-INF/cxf/cxf.xml" />-->

	<!-- 配置ws的服务端 -->
	<jaxws:server id="springID" serviceClass="com.rabbit.ws.IHelloWeb"
		address="/spring">
		<jaxws:serviceBean>
			<!-- 服务端类实现类 -->
			<bean class=" com.rabbit.ws.impl.HelloWebImpl"></bean>
		</jaxws:serviceBean>
	</jaxws:server>

</beans>

使用tomcat部署项目启动,然后访问项目wsdl看是否正常显示。例如:http://127.0.0.1:8080/ws-spring-cxf-server/services/spring?wsdl

Web.xml


<?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">
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<servlet>
		<servlet-name>cxf</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>cxf</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>
</web-app>

客户端

生成客户端代码:

wsdl2java –p com.rabbit.ws.client.byehttp://127.0.0.1:8080/ws-spring-cxf-server/ws/spring?wsdl

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xmlns:cxf="http://cxf.apache.org/core" 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-4.1.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
	http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<jaxws:client id="helloClient" 
			serviceClass="com.rabbit.ws.IHelloWeb" //具体类路径
			address="http://localhost:8080/server/services/spring"></jaxws:client>

</beans>

测试

public class Demo {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext.xml");
		IHelloWeb helloWeb = (IHelloWeb)ac.getBean("helloClient");
		System.out.println(helloWeb.sayHello("eric"));
	}
}


展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie
应支付0元
点击重新获取
扫码支付

支付成功即可阅读