玩转aop之cxf配置拦截器

一、客户端写法

1、配置


<jaxrs:outInterceptors>
			<bean
				class="com.xxx.base.interceptor.CxfOutMessageInterceptor"></bean>
		</jaxrs:outInterceptors>

2、CxfOutMessageInterceptor

cxf客户端将公共参数放在头信息里面传递到cxf的服务器端


import javax.ws.rs.core.MultivaluedMap;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iflashbuy.base.common.CommonParams;
import com.iflashbuy.base.common.ContextThread;
import com.iflashbuy.base.util.ParamUtils;
import com.iflashbuy.base.util.StringUtil;
import com.iflashbuy.util.F2BUtil;

/**
 * cxf拦截器,在请求服务前生效<br>
 * 1、将公共参数通过header传到服务器端cxf
 * 
 * @author 漂泊者及其影子
 * @date 2016年1月13日
 */
public class CxfOutMessageInterceptor extends AbstractPhaseInterceptor<Message> {
	private Logger logger = LoggerFactory.getLogger(getClass());

	public CxfOutMessageInterceptor() {
		super(Phase.WRITE);
	}

	@Override
	public void handleMessage(Message message) throws Fault {
		String sysid = "";
		String key = "";
		CommonParams params = ContextThread.getCurrentParams();
		if (params != null) {
			sysid = params.getSysid();
			key = params.getKey();
		} else {
			sysid = ParamUtils.get("sysid");
			key = ParamUtils.get("key");
		}

		@SuppressWarnings("unchecked")
		MultivaluedMap<String, Object> headers = (MultivaluedMap<String, Object>) message.get(Message.PROTOCOL_HEADERS);
		headers.putSingle("sysid", sysid);
		headers.putSingle("key", key);

	}
	


}



二、cxf服务器端写法


1、配置

<jaxrs:inInterceptors>
			<bean class="com.xxx.base.util.CxfInMessageInterceptor"></bean>
		</jaxrs:inInterceptors>
       
       	<jaxrs:outInterceptors>
			<bean
				class="com.xxx.base.util.CxfOutMessageInterceptor"></bean>
		</jaxrs:outInterceptors>



2、CxfInMessageInterceptor

cxf服务器端在接受请求的时候从请求的头信息中获取公共参数

import java.util.List;
import java.util.TreeMap;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iflashbuy.base.common.ContextThread;
import com.iflashbuy.base.constant.BaseConstant;

/**
 * cxf拦截器,在接受服务时候生效<br>
 * 1、获取从客户端传来的sysid<br>
 * 
 * @author 漂泊者及其影子
 * @date 2016年1月13日
 */
public class CxfInMessageInterceptor extends AbstractPhaseInterceptor<Message> {
	private Logger logger = LoggerFactory.getLogger(getClass());

	public CxfInMessageInterceptor() {
		super(Phase.RECEIVE);
	}

	@Override
	public void handleMessage(Message message) throws Fault {
		@SuppressWarnings("unchecked")
		TreeMap<String, Object> headers = (TreeMap<String, Object>) message.get(Message.PROTOCOL_HEADERS);
		String sysid = "";
		@SuppressWarnings("unchecked")
		List<String> sysidList = (List<String>) headers.get("sysid");
		if (CollectionUtil.isNotEmpty(sysidList)) {
			logger.info("sysid:" + sysidList.get(0));
			sysid = sysidList.get(0);
		}
		ContextThread.setCurrentSysid(sysid);
		log(message);
	}

	private void log(Message message) {
		if(BaseConstant.DEBUG_ENABLED) {
			String requestUri = (String) message.get(Message.REQUEST_URI);
			logger.info("requestUri:" + requestUri);
		}

	}
}



3、CxfOutMessageInterceptor

出于保险考虑,在cxf服务器端的请求完成后将ThreadLocal里面的对象销毁

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import com.iflashbuy.base.common.ContextThread;

/**
 * cxf服务器端拦截器,在请求完成后生效<br>
 *
 * 
 * @author 漂泊者及其影子
 * @date 2016年1月13日
 */
public class CxfOutMessageInterceptor extends AbstractPhaseInterceptor<Message> {
	public CxfOutMessageInterceptor() {
		super(Phase.WRITE);
	}

	@Override
	public void handleMessage(Message message) throws Fault {
		// 在请求完成后销毁contextThread里面的内容
		ContextThread.setCurrentSysid(null);
	}

}



三、ContextThread

cxf服务器端将公共参数放在ThreadLocal里面,以便cxf服务器端具体的业务方法能够拿到这些公共参数

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * @author limanman
 * @date 2015年11月24日
 */
public class ContextThread {
	/**
	 * ThreadLocal确保高并发下每个请求的request,response都是独立的
	 */
	private static ThreadLocal<HttpServletRequest> currentRequest = new ThreadLocal<HttpServletRequest>();
	private static ThreadLocal<HttpServletResponse> currentResponse = new ThreadLocal<HttpServletResponse>();
	private static ThreadLocal<CommonParams> currentParams = new ThreadLocal<CommonParams>();
	private static ThreadLocal<String> threadSessionKey = new ThreadLocal<String>();
	
	/**
	 * 用于sgint_service,进在cxf接受请求的时候将sysid设入
	 */
	private static ThreadLocal<String> currentSysid = new ThreadLocal<String>();
	
	
	public static String getCurrentSysid() {
		return currentSysid.get();
	}

	public static void setCurrentSysid(String sysid) {
		ContextThread.currentSysid.set(sysid);
	}

	public static CommonParams getCurrentParams() {
		return currentParams.get();
	}

	public static void setCurrentParams(CommonParams currentParams) {
		ContextThread.currentParams.set(currentParams);
	}

	public static HttpServletRequest getCurrentRequest() {
		return currentRequest.get();
	}

	public static void setCurrentRequest(HttpServletRequest currentRequest) {
		ContextThread.currentRequest.set(currentRequest);
	}

	public static HttpServletResponse getCurrentResponse() {
		return currentResponse.get();
	}

	public static void setCurrentResponse(HttpServletResponse currentResponse) {
		ContextThread.currentResponse.set(currentResponse);
	}

	public static String getThreadSessionKey() {
		return threadSessionKey.get();
	}

	public static void setThreadSessionKey(String sessionKey) {
		threadSessionKey.set(sessionKey);
	}
}


四、cxf配置了拦截器的好处总结


  1. 权限验证,有些请求可能涉及到权限这一块
  2. 公共参数传递,避免在每个方法中都要在参数总加入一些公共参数,公共参数可以在拦截器中通过头部信息来传递
  3. 日志打印,打印相关请求信息(测试阶段)


你可能感兴趣的:(CXF,拦截器)