CXF之六(对请求参数和返回给客户数据处理)
??一、对客户端上送的参数统一处理??
????? 最近有人提出来这样的需求,通过WebService调用的接口时,请求的输出的某些参数值先进行加密(如密码等),然后再上送给服务器。所以造成了在接口中必须先对密文进行解密,然后再操作。我就想着通过CXF的拦截器进行统一处理,因为拦截器的功能非常强大。如果不熟悉CXF拦截器功能的童鞋可以先去熟悉一下。通过测试发现这种方法是可行的。具体代码如下:
第一步:创建拦截器
?
import java.io.ByteArrayInputStream;import java.io.InputStream;import java.util.HashMap;import java.util.Iterator;import java.util.Map;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.apache.log4j.Logger;import org.springframework.stereotype.Service;/** * 对客户端上送的数据进行处理,可以完成以下功能 * (1)、对加密的字段统一加密; * (2)、对特殊的字段进行特殊处理 * * @author XX * @version [版本号, 2012-11-07 下午02:34:07 ] * @see [相关类/方法] * @since [产品/模块版本] */@Service("gatewayInInterceptor")public class GatewayInInterceptor extends AbstractPhaseInterceptor<Message> {private Logger logger = Logger.getLogger(GatewayInInterceptor.class);public GatewayInInterceptor(String phase) {super(phase);}public GatewayInInterceptor() {super(Phase.RECEIVE);}/** <功能详细描述> * 创 建 人: XX * 创建时间: 2012-11-07 下午02:34:07 * @param arg0 * @throws Fault * @see [类、类#方法、类#成员] */@SuppressWarnings("static-access")public void handleMessage(Message message) throws Fault {/* Iterator<Entry<String, Object>> it = message.entrySet().iterator();while (it.hasNext()) {Entry<String, Object> e = it.next();System.out.println(e.getKey() + "," + e.getValue());}*/String reqParams=null; if(message.get(message.HTTP_REQUEST_METHOD).equals("GET")){//采用GET方式请求 reqParams=(String) message.get(message.QUERY_STRING); message.remove(message.QUERY_STRING); reqParams=this.getParams(this.getParamsMap(reqParams)); message.put(message.QUERY_STRING,reqParams); }else if(message.get(message.HTTP_REQUEST_METHOD).equals("POST")){//采用POST方式请求 try { InputStream is = message.getContent(InputStream.class); reqParams=this.getParams(this.getParamsMap(is.toString()));if (is != null)message.setContent(InputStream.class, new ByteArrayInputStream(reqParams.getBytes()));} catch (Exception e) {logger.error("GatewayInInterceptor异常",e);} } logger.info("请求的参数:"+reqParams);}private Map<String,String> getParamsMap(String strParams){if(strParams==null||strParams.trim().length()<=0){return null;}Map<String,String> map =new HashMap<String,String>();String[] params=strParams.split("&");for(int i=0;i<params.length;i++){String[] arr=params[i].split("=");map.put(arr[0], arr[1]);}return map;}private String getParams(Map<String,String> map){if(map==null||map.size()==0){return null;}StringBuffer sb=new StringBuffer();Iterator<String> it =map.keySet().iterator();while(it.hasNext()){String key=it.next();String value =map.get(key);/*这里可以对客户端上送过来的输入参数进行特殊处理。如密文解密;对数据进行验证等等。。。if(key.equals("content")){value.replace("%3D", "=");value = DesEncrypt.convertPwd(value, "DES");}*/if(sb.length()<=0){sb.append(key+"="+value);}else{sb.append("&"+key+"="+value);}}return sb.toString();}}?
第二步:修改配置文件
?
<jaxrs:server id="smsGateway" address="/smsGateway"><jaxrs:inInterceptors> <ref bean="inMessageInterceptor"/> <ref bean="gatewayInInterceptor"/></jaxrs:inInterceptors><jaxrs:outInterceptors> <ref bean="outMessageInterceptor"/> </jaxrs:outInterceptors><jaxrs:serviceBeans><ref bean="smsGatewayImpl" /></jaxrs:serviceBeans><jaxrs:extensionMappings><entry key="json" value="application/json" /><entry key="xml" value="application/xml" /></jaxrs:extensionMappings><jaxrs:languageMappings><entry key="en" value="en-gb" /></jaxrs:languageMappings><jaxrs:providers> <bean name="code">import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import org.apache.commons.io.IOUtils;import org.apache.cxf.io.CachedOutputStream;import org.apache.cxf.message.Message;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.apache.log4j.Logger;import org.springframework.stereotype.Service;/** * * 对返回给客户端的结果进行处理,可以进行以下操作 * (1)、对返回的数据进行加密; * (2)、对返回的数据进行特殊处理 * @author 文超 * @version [版本号, 2012-11-7 下午03:14:39 ] * @see [相关类/方法] * @since [产品/模块版本] */@Service("gatewayOutInterceptor")public class GatewayOutInterceptor extends AbstractPhaseInterceptor<Message> { private Logger logger = Logger.getLogger(GatewayOutInterceptor.class);public GatewayOutInterceptor() {super(Phase.PRE_STREAM);// 触发点在流关闭之前}public void handleMessage(Message message) {try {OutputStream os = message.getContent(OutputStream.class);CachedStream cs = new CachedStream();message.setContent(OutputStream.class, cs);message.getInterceptorChain().doIntercept(message);CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);InputStream in = csnew.getInputStream();String result = IOUtils.toString(in,"UTF-8");logger.info("返回给客户端值:"+result);/** 这里可以对result做处理,如可以对result进行加密,把密文返回给客户端 处理完后同理,写回流中*/IOUtils.copy(new ByteArrayInputStream(result.getBytes("UTF-8")), os);cs.close();os.flush();message.setContent(OutputStream.class, os);} catch (Exception e) {logger.error("GatewayOutInterceptor异常",e);}}private class CachedStream extends CachedOutputStream {public CachedStream() {super();}protected void doFlush() throws IOException {currentStream.flush();}protected void doClose() throws IOException {}protected void onWrite() throws IOException {}}}?
第二步:添加配置
?
<jaxrs:server id="smsGateway" address="/smsGateway"><jaxrs:inInterceptors> <ref bean="inMessageInterceptor"/> <ref bean="gatewayInInterceptor"/></jaxrs:inInterceptors><jaxrs:outInterceptors> <ref bean="outMessageInterceptor"/> <ref bean="gatewayOutInterceptor"/></jaxrs:outInterceptors><jaxrs:serviceBeans><ref bean="smsGatewayImpl" /></jaxrs:serviceBeans><jaxrs:extensionMappings><entry key="json" value="application/json" /><entry key="xml" value="application/xml" /></jaxrs:extensionMappings><jaxrs:languageMappings><entry key="en" value="en-gb" /></jaxrs:languageMappings><jaxrs:providers> <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/> <bean class="com.pml.service.outer.InvokeFaultExceptionMapper"/> </jaxrs:providers></jaxrs:server>
?
第三步:OK,测试一下,是否达到你相应的结果
?
?
?