日期:2014-05-16 浏览次数:20583 次
?
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,