CXF添加自定义拦截器

前面我们说到CXF添加内置的拦截器,今天的话,我们来实现如何添加自定义拦截器


实例是客户端访问服务端webservice接口要加权限认证


我们可以通过在SOAP消息的Header头信息中添加自定义信息,然后发送到服务端端,服务器端通过获取

Header头消息,然后进行认证;这里的添加消息,和获取消息认证,我们都是通过自定义拦截器来实现



我们自定义拦截器:MyInterceptor


package com.gcx.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 MyInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public MyInterceptor() {
		super(Phase.PRE_INVOKE);  // 在调用方法之前调用自定拦截器
		
	}

	@SuppressWarnings("null")
	public void handleMessage(SoapMessage message) throws Fault {
		List<Header> headers=message.getHeaders();
		if(headers==null && headers.size()==0){
			throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截"));
		}
		Header firstHeader=headers.get(0);
		Element ele=(Element) firstHeader.getObject();
		NodeList uList=ele.getElementsByTagName("userName");
		NodeList pList=ele.getElementsByTagName("password");
		if(uList.getLength()!=1){
			throw new Fault(new IllegalArgumentException("用户名格式不对"));
		}
		if(pList.getLength()!=1){
			throw new Fault(new IllegalArgumentException("密码格式不对"));
		}
		String userName=uList.item(0).getTextContent();
		String password=pList.item(0).getTextContent();
		
		if(!userName.equals("gcx")||!password.equals("123456")){
			throw new Fault(new IllegalArgumentException("用户名或者密码错误!"));
		}
	}

}

这里的话,我们主要是获取Header头消息,然后获取userName和password节点,然后获取值,进行权限判断,假如认证不通过,我们抛出异常


在Server类里,我们要添加一个in 拦截器,在进入的时候,我们要进行验证


package com.gcx.test;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

import com.gcx.interceptor.MyInterceptor;
import com.gcx.service.HelloWorld;
import com.gcx.service.impl.HelloWorldImpl;

public class ServerTest {
	public static void main(String[] args) {
		System.out.println("webService start");
		
		HelloWorld implementor=new 	HelloWorldImpl();
		String address="http://192.168.31.42/helloWorld";
		//通过JDK实现暴露webService接口
		//Endpoint.publish(address, implementor);
		JaxWsServerFactoryBean factoryBean=new JaxWsServerFactoryBean();
		factoryBean.setAddress(address);//设置暴露地址
		factoryBean.setServiceClass(HelloWorld.class);//接口类
		factoryBean.setServiceBean(implementor);//接口实现类
		factoryBean.getInInterceptors().add(new LoggingInInterceptor()); // 添加in拦截器 日志拦截器
		factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out拦截器 日志拦截器
		
		factoryBean.getInInterceptors().add(new MyInterceptor());
		factoryBean.create();//创建webService接口
		System.out.println("webService end");
	}
}


接下来是修改客户端代码:

我们同样要添加一个自定义拦截器:AddHeaderInterceptor


package com.gcx.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 AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	private String userName;
	private String password;
	
	public AddHeaderInterceptor(String userName,String password) {
		super(Phase.PREPARE_SEND); // 准备发送SOAP消息的时候调用拦截器
		this.userName=userName;
		this.password=password;
	}

	public void handleMessage(SoapMessage message) throws Fault {
		List<Header> headerList=message.getHeaders();
		
		Document doc=DOMUtils.createDocument();
		Element ele=doc.createElement("authHeader");
		Element uElement=doc.createElement("userName");
		uElement.setTextContent(userName);
		Element pElement=doc.createElement("password");
		pElement.setTextContent(password);
		
		ele.appendChild(uElement);
		ele.appendChild(pElement);
		
		headerList.add(new Header(new QName("java1234"),ele));
		
	}
	
	

}


这里的话,我们主要是在拦截器里创建头消息


Client类里我们要修改下,加下Out 拦截器

package com.gcx.service;

import java.util.List;

import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;

import com.gcx.interceptor.AddHeaderInterceptor;

public class Client {
	public static void main(String[] args) {
		HelloWorldService service=new HelloWorldService();
		HelloWorld helloWorld=service.getHelloWorldPort();
		org.apache.cxf.endpoint.Client client = ClientProxy.getClient(helloWorld);
		client.getOutInterceptors().add(new AddHeaderInterceptor("gcx","123456")); // 添加自定义拦截器
		client.getInInterceptors().add(new LoggingInInterceptor());
		client.getOutInterceptors().add(new LoggingOutInterceptor());
		MyRoleArray roles = helloWorld.getRoles();
		List<MyRole> item = roles.item;
		for(int i=0;i<item.size();i++){
			MyRole myRole = item.get(i);
			System.out.print(myRole.key+":");
			for(Role my:myRole.value){
				System.out.print(my.getId()+","+my.getRoleName());
			}
			System.out.println("==");
		}
	}
}


服务端日志:


客户端日志:




OK这样就完整了自定义拦截器实现权限认证



假如我们把  client.getOutInterceptors().add(new AddHeaderInterceptor("gcx","123")); // 添加自定义拦截器

密码改成 123


然后运行Client类,会报错




用户名或者密码不正确

OK这样就完整了自定义拦截器实现权限认证
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值