vulcan

低头做事,抬头看路

   :: 首页 :: 联系 :: 聚合  :: 管理
  41 Posts :: 7 Stories :: 28 Comments :: 0 Trackbacks
去年的一个问题,后来项目时间紧就搁下了,采用了替代方案,但是总觉得不那么完美,今年升级开发,想解决了,然后才有了这个想法。之前也知道SpringSide,但是没有想过取看,今天因为一个问题搜google,居然发现我之前对于java web开发的一些想法居然和SpringSide一样!又多了解了一下,发现这个项目的贡献者都是国内jee开发领域的高手,所以呢,肯定比我的那些实现完美得多。暂时放下自己的代码,好好看看SpringSide源代码,因为想法有些一致,那么看起来肯定会很愉快的,如果全部和我的胃口,那么就转到SpringSide了,如果不完全合我胃口,那么就把我关心的一些代码搞明白后,选择性吸收进项目了。
下面是读代码的一些感受:
(1) DAO的实现挺对我胃口的,比较喜欢。我的范型DAO是从Hibernate网站上取下来改进的。主要增加了一个可以接收List<Criterion>的重载方法还有分页的功能。List类型的Criterion,方便了在上层灵活的利用添加条件,而不用每次都去转成数组,传给原本只接受可变参数的方法;分页和Order的支持操作比我的实现优雅得多。不过却希望可以给范型DAO的主键也增加一个范型参数,因为对于复合主键的参数传入,如果有一个类型安全检查可能要好一些。
(2) 先有鸡还是先有蛋的问题,这个问题可能是我理解得不清楚还是Struts2的机制变了。看到SpringSide2中core.web包中有一个Struts的支持类,支持了基本的CRUD操作,这个问题,我却之前没有想过,导致有好多很简单的,但是又不得不写代码和配置的webwork Action。于是我就想着给webwork也写了这样一个支持类。正好springside3中有对Struts2的一个支持类,参考了一下,struts2和webwork的关系想必大家都知道。应该有可以借鉴的东西。不过借鉴过来之后,发现行不通有问题,后来居然是一个先有蛋还是先有鸡的问题:因为拦截器的配置顺序。在springside3的struts2支持类中,实体的根据id从数据库载入或者新建放在了prepare方法中,而这个prepare是使用了一个要求子类重载的getId方法,毫无疑问,在我们通常的使用中,getId肯定是从表单参数中获取的,所以也就意味着webwork的param拦截器必须在prepare拦截器之前,由于使用了prepare来准备entity,那么model-driven拦截器必须在prepare拦截器之后,不过webwork model driven要能正常工作,实际上,model-driven又必须是在param拦截器之前,在使用ognl进行参数注入之前,必须先通过model-driven拦截器把实体准备好!这就形成了一个先有蛋还是先有鸡的问题了。不知道是不是我理解webwork还不够深入,这个问题如果是采用prepare来做这个工作,那么这个问题是无解的。最终,我还是按照自己的理解做了一个,提供一个getId()默认实现,并且在getId()方法中,不依赖于param拦截器,而是直接从ActionContext中获取提交的表单Id参数,如下的代码:
    /**
     * for the webwork ognl injection of parameter
     * 默认情况下,将把传递过来的参数转换成Integer类型,
     * 如果不是这种情况,则需要在子类中重载该方法
     * 
@param id
     
*/

    @SuppressWarnings(
"unchecked")
    
public void setId(Serializable id) {
        
//如果范型ID的定义不是Array类型,但是却取到了Array类型的值
        
//那么可以断定这是由于页面传递过来的被webwork认成了Array类型了
        
//这个时候,需要把Array类型的参数值取出来
        
//这种情况仅仅在这个范型父类中存在,在具体类中不存在这种情况
        
//而是参数类型可以被webwork自动转换到相应的类型
        
//一般没有ID取值为Array的情况
        if(id instanceof String[]) {
            String[] idArray 
= (String[])id;
            
if (idArray.length > 0{
                
//从List类型的参数中取出具体类型的Id
                id = Integer.valueOf(idArray[0]);
            }

        }

        
//ID should never be ZERO - 
        
//cope with default value of the primitive types
        if(id instanceof Integer && !new Integer(0).equals(id)) {
            
this.id = id;
        }

    }

    
/**
     * getId of the entity, if this.id is null, try get from
     * action context first
     * 
@return
     
*/

    
protected Serializable getId() {
        
if(this.id == null{
            
//try to get parameter from the actioncontext
            ActionContext context = ActionContext.getContext();
            Map params 
= context.getParameters();
            Object id 
= params.get(this.idParamName);
            
if(id != null{
                
//if the parameter is not null,
                
//set Id parameter
                setId((Serializable)id);
            }

        }

        
return this.id;
    }


并且还需要提供一个setIdParamName()方法,这样就可以在webwork配置中注入idParamName了。
当然还可以这样做:
把springside3中struts支持类中prepare做的工作分散到几个crud操作方法中。首先在:input方法中,根据id是否有值,新建或者从数据库中load一个entity,这是在插入或者更新一个entity之前的操作;而getModel方法中直接放了一个创建一个entity instance的方法,因为model-driven主要是拿来做表单参数接收的,所以是否从数据库中load一个entity其实是无所谓的,反正会被表单参数全部覆盖。不过要是可以在getModel()方法之前知道是对哪个entity进行的操作,然后load该对象,就可以在表单中只传递部分属性值了。按照model-driven必须在param拦截器之前的原则,除非把要编辑的entityId放在session而不是页面参数中,然后在getModel方法中预先判断是否是该Action的编辑操作,而load该entity。
posted on 2008-03-18 10:40 vulcan 阅读(363) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: