webservice-自定义注解处理参数加解密问题
2017-08-05 19:48
190 查看
webservice-自定义注解处理参数加解密问题
前一段项目中用到了webservice,正好自己之前也了解过一点apache的cxf框架,所以就采用了cxf来实现webservice服务端,本身实现并没技术难点,但是项目为了保证安全性,采用了传输加密的过程,所以大部分请求参数需要加密,返回参数也需要加密,大致流程是:请求参数对称加密+对称秘钥非对称加密,
返回参数堆成加密+对称秘钥非对称加密
参数加密本身并不复杂,但是有些服务并不需要加密,有些则需要,加密工具类并不通用
string,datahandler等不能重用,虽然本质都是对字节数据加密,但是要写许多方法,还要方法参数,检查需要加解密处理的参数,然后寻找对应的类型处理方法调用.
逻辑很清晰,但是过程实现很恶心,最终这样实现了一版,但是并不合我的意.
如果能在拦截器中获取到参数列表,然后寻找对应的解码器解码,这样就比较简单了.但是难点是,如果标记参数,并指定被标记参数的解码器尼?
我想到了注解,注解就可以标记,参数,然后通过反射获取到注解,解析出内容.
本来想标记到参数上,但是一个个标记太麻烦,而且获取也不太方便,索性就放在方法上,用数组来接收.
问题解决.
代码实现
自定义注解:import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author webservice请求参数自定义注解 * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequestHanleAnnotation { Class[] handler() default {}; int[] index() default {}; }
参数解码器接口
import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author taoyuan *参数处理器 * @param <T> */ public abstract class ParamHandler<T> { //解码器实例缓存 public static final Map<Class,ParamHandler> hanlers=new ConcurrentHashMap<>(); //处理方法 abstract T handle(T t); }
解码器实现,这里并没有真正解码,只是在参数后面加了123
public class StringHandler extends ParamHandler<String> { @Override public String handle(String t) { return t+"123"; } }
服务方法注解使用
//表示第一个参数需要StringHandler处理 @RequestHanleAnnotation(index=0,handler=StringHandler.class) public String test(String test, String test2) throws Exception { System.out.println(test); System.out.println(test2); return "cesshi"; }
拦截器实现
import java.io.File; import java.lang.reflect.Method; import java.util.Map; import org.apache.commons.io.FileUtils; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.MessageContentsList; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.apache.log4j.Logger; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; /** * @author 都市桃源 */ public class EcrInInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ private Logger log = Logger.getLogger(ContractLogicImpl.class); public EcrInInterceptor(){ // 在调用方法之前调用拦截器 super(Phase.PRE_INVOKE); } @Override public void handleMessage(SoapMessage msg) throws Fault { /*获取请求ip,拦截器中可以做下统一日志处理 HttpServletRequest httprequest = (HttpServletRequest)msg.get(AbstractHTTPDestination.HTTP_REQUEST); * */ //获取正在执行的方法 Method method = MsgUtil.getSoapMethod(msg); //解析注解,并处理参数 MessageContentsList contentsList = MessageContentsList.getContentsList(msg); MsgUtil.handle(method,contentsList); } @Override public void handleFault(SoapMessage message) { super.handleFault(message); }
注解解析工具类实现
import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.MessageContentsList; import org.apache.cxf.service.Service; import org.apache.cxf.service.invoker.MethodDispatcher; import org.apache.cxf.service.model.BindingOperationInfo; /** * @author ll * 获取方法名称 * */ public class MsgUtil { /**根据消息获取调用方法 * @param msg * @return */ public static Method getSoapMethod(SoapMessage msg){ Exchange exchange = msg.getExchange(); BindingOperationInfo bop = exchange.get(BindingOperationInfo.class); MethodDispatcher md = (MethodDispatcher) exchange.get(Service.class) .get(MethodDispatcher.class.getName()); Method method = md.getMethod(bop); return method; } public static void handle(Method method, MessageContentsList contentsList) { if(method==null)return; RequestHanleAnnotation reqAnno= method.getAnnotation(RequestHanleAnnotation.class); int[] indexs = reqAnno.index(); if(indexs==null||indexs.length==0)return; Class[] handlers = reqAnno.handler(); try { //处理器实例 ParamHandler handler=null; for(int i=0,len=indexs.length;i<len;i++){ //获取需要处理的参数 Object obj = contentsList.get(indexs[i]); //从缓存中获取处理器实例 handler=ParamHandler.hanlers.get(handlers[i]); if(handler==null){ //创建处理器实例 handler=(ParamHandler) handlers[i].newInstance(); //缓存处理器实例 ParamHandler.hanlers.put(handlers[i], handler); } contentsList.set(indexs[i], handler.handle(obj)); } }catch (Exception e) { e.printStackTrace(); } } }
返回参数同样也可以注解实现,这里就不在赘述了,实现也比较简单.
**需要注意的是,拦截器拦截顺序不一样
拦截器统一继承
AbstractPhaseInterceptor类,
请求拦截 :super(Phase.PRE_INVOKE);
返回拦截: super(Phase.PRE_STREAM);**
相关文章推荐
- 商城项目处理“横向越权”问题。(自定义注解aop的方式)
- AJAX JSON中日期类型DateTime格式化的序列化自定义对象以及自定义类型参数的问题处理
- spring mvc 自定义注解ResponseEncryptBody、RequestDecryptBody统一处理加密、解密数据,供移动端使用的rest服务
- spring@Transactional注解解决事务处理问题
- Retrofit 常用参数使用方式和Url处理注解汇总(一)
- 自定义注解的使用(将request参数中的数据解释成对象)
- javaWeb自定义可排序过滤器注解,解决Servlet3.0下@WebFilter注解无法排序问题
- 使用Spring Boot的AOP处理自定义注解
- soapUI测试webservice(参数为xml格式的处理方式)
- 面向对象的设计方式处理Android编程中的GridView问题,以及自定义ListAdapter的使用
- kettle 映射的使用——对自定义参数处理
- jsp处理c for循环中取到每一条信息+get方式提交form表单参数拼接问题
- 自定义注解与spring事务的问题
- C#调用WebService的问题处理
- HFun.快速开发平台(四)=》自定义列表实例(请求参数的处理)
- WebService返回数据前台获取并处理JSON的相关问题
- 利用HttpHandler处理自定义控件中需要引用大量js文件问题
- 【jmeter】利用BeanShell Preprocessor 处理请求参数的中文转码问题
- 关于在java环境下调用 .net的 webservice无法获取参数的问题
- 面向对象的设计方式处理Android编程中的GridView问题,以及自定义ListAdapter的使用