2019独角兽企业重金招聘Python工程师标准>>>
一、客户端写法
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配置了拦截器的好处总结
- 权限验证,有些请求可能涉及到权限这一块
- 公共参数传递,避免在每个方法中都要在参数总加入一些公共参数,公共参数可以在拦截器中通过头部信息来传递
- 日志打印,打印相关请求信息(测试阶段)