Utils-action

它提供了两个重要的类:FrontAction和JSONActionSupport 。它们的用法如下:

FrontAction

前端Action类,所有的客户端请求通过此类转发到实际处理的Action类, 其思想和FrontServlet一样。在struts中如下配置:

struts.xml

......

        <package name="net.sourceforge.kivu4j.utils.action.frontAction" extends="struts-default">        
                <action name="services" class="net.sourceforge.kivu4j.utils.action.FrontAction" method="services">
                        <result name="success" type="chain">
                                <param name="actionName">${actionName}</param>
                                <param name="namespace">${namespace}</param>
                        </result>                       
                </action>       
        </package>

......

说明:客户端提交,必须指定namespace和actionName属性,用于确定具体处理的Action类及方法。

这样的设计,灵感来自解决Extjs库中Ext.data.Store的问题。通常情况下,这样使用Ext.data.Store的:

var ds = new Ext.data.JsonStore({
        url : '../initAction/welcome.do',
        fields : ["name", "value"]
        }
});

ds.load();   

问题

  • url在store创建时就已经指定,无法修改的,也就是功能无法改变。
  • Store只有一个load方法访问数据

包装Ext.data.Store

应该创建子类BaseStore,继承Ext.data.Store。BaseStore类的url是固定的, 它访问的是FrontAction类的services方法,代码:

BaseStore.js

BaseStore = function(config){
        var cfg = {
                url:'services.action'
        };
        
        config = Ext.apply(config || {}, cfg);
        
        // 设置namespace
        this.setBaseParam('namespace', config.namespace);
        
        // 调用父构造函数
        BaseStore.superclass.constructor.call(this, config);
};
Ext.extend(BaseStore, Ext.data.JsonStore);

现在,可以创建一个特定对象的数据访问Store。比如PersonStore,它是人员的访问。代码:

PersonStore.js

PersonStore = function(config){
        var cfg ={
                fields:[{
                        name: 'ID'
                },{
                        name: 'firstName'
                },{
                        name: 'lastName'
                }]      
        };
        
        config = Ext.applyIf(config || {}, cfg);
        config = Ext.apply(config, {
                namespace:'/person',
        });

        PersonStore.superclass.constructor.call(this, config);
};
Ext.extend(PersonStore, BaseStore,{
        loadById:function(id,options){
                this.setBaseParam('actionName', 'loadById');
                this.setBaseParam('id', id);
                this.load(options);
        },
        
        loadByName:function(name,options){
                this.setBaseParam('actionName', 'loadByName');
                this.setBaseParam('name', name);
                this.load(options);
        },      
});

可以这样使用:

  var ds = new PersonStore();
  
  ds.loadById(1);
  ......
  ds.loadByName('张三');
  ......
  ds.save({firstName:'三',lastName:'张'});

JSONActionSupport

典型的Action类是这样的:

public class YourAction extends JSONActionSupport {
        @Resource
        private YourManager yourManager;
        
        public String doAction1(){
                try{
                        Long id = this.getRequestAsLong();              //{199}                         //转换json格式数据
                        String rslt = this.yourManager.doSomething(id);                 //处理数据
                                        
                        this.setResponseData(new ResponseList<String>(rslt));   //返回客户端数据
                }catch(Exception e){
                        this.handleException(e);
                }
                return SUCCESS;
        }       
}

其他的json请求数据

 //字符串
 String s = this.getRequestAsStr();// {'abc'}
 
 //数值
 Long l = this.getRequestAsLong();// {100}
 
 //map
 RequestMap rm = this.getRequestAsMap(); //  {'name':'张三', 'age':30}
 String name = rm.getStr("name");
 Long age = rm.getLong("age");
 
 //对象
 Example e = this.getRequest(Example.class);// {name:'张三', age:30}
 
 public class Example{
  private String name;
  private Long age;
  
  // sets and gets
  ......
 } 

其他的返回数据

  // 对象
  Example rslt = ......;
  this.setResponseData(new ResponseList<Example>(rslt));
 
  // 集合
  List<Example> rslt = ......;
  this.setResponseData(new ResponseList<Example>(rslt));
  
  // 字符串
  this.setResponseData(new ResponseList<String>(s));
 
  // 空结果
  this.setResponseData(new ResponseEmpty());