日期:2014-05-16 浏览次数:20461 次
?
B/S应用需要解决的一个重要问题是:如何在B/S之间传递数据。同样是采用HTTP协议,当时传递的内容形式已经从最初的平面型的form参数提交,发展为结构型的WebRPC调用。其中DWR、Web Service和JsonRPC是最常见的实现。
WebRPC的基本思路如下:在B端和S端分别实现对象及方法的序列化和反序列化,一个典型的调用过程如下:
看起来很完美,但并没有解决全部问题,应用中经常遇到的场景是:只需要对数据库表中的部分而不是全部字段进行操作。即:我们需要对象部分属性的序列化和反序列化。实现这个目标有两种思路:一是hack现有的WebRPC,使其支持部分属性序列化。另一种思路则是:引入一个中间形态以承载部分属性对象。本文采用的是第二种思路。
对该形态的用java描述如下
?
?
/** * object部分属性的map形式 * @author chen4w * */ public class BObj { //从数据库获得的原始状态 public static final char ACTION_ORIG = 'O'; //新增对象 public static final char ACTION_ADD = 'A'; //已设置为删除状态 public static final char ACTION_REMOVE='R'; //经过了修改 public static final char ACTION_UPDATE='U'; //用于新增的默认对象 public static final char ACTION_DEFAULT='D'; //多表按顺序的类名 private String[] cns; /** * 属性数组 */ private HashMap<String,Object> items; /** * 动作标识 */ private char action; public char getAction(){ return action; } public void setAction(char action){ this.action=action; } public String[] getCns(){ return cns; } public void setCns(String[] cname){ this.cns=cname; } public HashMap<String,Object> getItems(){ return items; } public void setItems(HashMap<String,Object> fmap){ this.items=fmap; } }?
可以看出,描述中包含了如下几类信息:
cns——对象类名(O/R mapping映射的POJO),采用数组是考虑到多表联合查询
action——对象自描述的状态,新增/删除/更新/初始。
Items——对象的部分属性集合
以此类作为中间形态,我们不难写出完整对象与之转换的方法。然后利用WebRPC,编写出一个以该类作为参数的通用的数据库CRUD方法。
以jsonRPC为B/S双向序列化协议,编写服务方法如下:
?
static public Object handle(char method,HashMap<String, Object> rm,String sn, HttpServletRequest request) throws Exception { // TODO Auto-generated method stub if(sn==null || sn.trim().equals("")) sn = DEFAULTHANDLER; //session检查 为空且非登录请求 /*if(method!=METHOD_LOGIN){ throw new ServletException(Info.ERR_INVALID_SESSION); }*/ //如果存在before回调 String cn = ""; String[] cns= (String[])rm.get("cns"); if(cns!=null){ cn = cns[0]; } //根据HHUtil中对sn+method的事务要求,采用编程决定是否启动事务管理 Integer transanctionMode = hhutil.getTransactionMode(sn,method); PlatformTransactionManager transactionManager=null; TransactionStatus transactionStatus=null; if(transanctionMode!=null){ transactionManager=(PlatformTransactionManager)Cfg.getBean("transactionManager"); TransactionDefinition transactionDefinition= new DefaultTransactionDefinition(transanctionMode); transactionStatus=transactionManager.getTransaction(transactionDefinition); } try{ IHandleHook hcb = hhutil.getHandleHook(sn, method, cn); if(hcb!=null) hcb.beforeHandle(method,rm,request); Object result= getHandleImpl(sn).handle(method,rm,request); //如果存在after回调 if(hcb!=null) hcb.afterHandle(method,