`
iamlotus
  • 浏览: 106668 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

struts2中接收非基本类型的对象时必须有setter

 
阅读更多

今天重构以前代码过程中发现一个struts2设置参数的问题,前后足足追了半天,顺便看了OGNL的源码,在这里记录下原因和解决方案:

 

在struts2的action中接收参数时,通常我是不喜欢写getter,只写setter。这样可以更加清楚的表示这是一个输入参数,比如

 

public class XXAction{
     private int size;
     public viod setSize(int size){
         this.size=size;     
      }

}

 

 

当只接收普通类型时没有问题,可对于如下复杂类型

 

public class PageBean{
         int pageSize;
         int pageNo;
         String orderBy;

         // getter &setter
         // ...

}

 

 

   如果不写getter

 

public class XXAction{
       private PageBean page;
       public void setPage(PageBean page){
              this.page=page;
       }
}

  

    前端传过来的参数 page.pageSize=10&page.pageNo=1&page.orderBy=name

    在execute()方法中会发现page对象只有 pageSize被赋值了(10),pageNo和orderBy都为null。而且无论怎么调整传入参数的顺序结果都是一样的。

 

    这个问题让我很费解,网上找了半天也没找到答案,老老实实的去跟OGNL的源码,最后发现原因是这样的:

 

    1) OGNL 首先收集所有需要赋值的属性( page.pageSize, page.pageNo, page.orderBy)

    2) 如果是复杂对象(如这里的PageBean),OGNL并不是首先构造好这个PageBean,赋上所有的值(pageSize,pageNo,orderBy),然后再把整个对象赋给action.page;而是通过一个循环依次往action.page这个对象上追加值。循环中每次执行时并不知道action.page对象是否已经执行过初始化,所以每次都要用以下方法测试action.page是否存在,若不存在则会初始化它 (action.page=new PageBean()), 然后完成本次赋值

 

          

if (OgnlRuntime.hasSetProperty(ognlContext, o, name)) {
                    OgnlRuntime.setProperty(ognlContext, o, name, value);

                    return;
                }

 

           由于我没有在Action中对page属性写setter,所以.hasSetPropertyf方法每次都会返回false,然后OGNL就会傻傻的重新初始化并赋值, 对于以上三个属性,它一共会初始化page对象三遍,而只保留下最后赋值的属性pageSize。

           至于为什么每次都是pageSize排在最后呢? 这是因为OGNL在步骤1)中收集对象时用的是 TreeMap, 而前段穿过来的这三个key(page.pageSize, page.pageNo, page.orderBy) 按照String.compareTo()的实现总是page.pageSize排在最后一个。

 

 

        知道了原因,解决方法当然很简单,只要加上 page属性的setter就行了。不过这里还是要对Struts的设计吐个槽,如果是我来设计,输入参数肯定不会要求实现者提供getter,而是用一个Map保存对象的中间状态,最后统一调用setter赋给action。 现在这种拿action当临时对象用的方法看起来简化了一些实现,但作为框架来说,强制要求使用者提供getter完全是过分的要求。

 

        

 

 

     

0
2
分享到:
评论
6 楼 Shen.Yiyang 2012-10-30  
当然需要你写getter了,dupe。。。如果复杂类型有多层,比如PageBean里面有SortOption,SortOption里面有orderclomuns,ordertye(asc,desc) 你不get到最外面那个,怎么给里面的多个层次设置
5 楼 if(i!=我){} 2012-10-30  
汗,这……还被弄到首页……
4 楼 kjj 2012-10-30  
标题说的是getter,结论归纳到setter,可见struts2的作者不是那么不屑
作为你一喷子,你也得知道,javaeye上的人大都有智商,而不是你这样的,
智商是硬伤!!
3 楼 freezingsky 2012-10-30  
文章表述,有很多前后不一致的地方。
2 楼 kissau 2012-10-30  
onlylau 写道
struts2中接收非基本类型的对象时必须有setter

如果不写getter

由于我没有在Action中对page属性写setter

知道了原因,解决方法当然很简单,只要加上 page属性的setter就行了。

但作为框架来说,强制要求使用者提供getter完全是过分的要求。


请问LZ你这个到底是setter方法,还是getter方法。。。有些地方表述错误噢!会误导人

确实,
从描述来看这个好像和getter方法没什么关系。
但是setter方法肯定是需要的,不管是基本类型还是非基本类型对象。
所以你这文章让人。。。,就不说了。
1 楼 onlylau 2012-10-30  
struts2中接收非基本类型的对象时必须有setter

如果不写getter

由于我没有在Action中对page属性写setter

知道了原因,解决方法当然很简单,只要加上 page属性的setter就行了。

但作为框架来说,强制要求使用者提供getter完全是过分的要求。


请问LZ你这个到底是setter方法,还是getter方法。。。有些地方表述错误噢!会误导人

相关推荐

    struts1和struts2的区别

    Struts 2无须继承任何类型或实现任何接口,表单数据包含在Action中,通过Getter和Setter获取。 虽然,在理论上Struts2的Action无须实现任何接口或者是继承任何的类,但是,在实际编程过程中,为了更加方便的实现...

    struts1&struts2

    2.Struts2和Struts1.x的差别, 最明显的就是Struts2是一个pull-MVC架构。 这是什么意思呢?从开发者角度看, ... Struts 2无须继承任何类型或实现任何接口,表单数据包含在Action中,通过Getter和Setter获取。

    struts2.3.32版本升级附升级步骤

    Apache官方已针对该漏洞发布安全公告,ApacheStruts 2.3.5 – 2.3.31版本及2.5 – 2.5.10版本存在远程代码执行漏洞(CNNVD-201703-152 ,CVE-2017-5638)。该漏洞是由于上传功能的异常处理函数没有正确处理用户输入...

    struts项目学习笔记

    允许POJO(Plain Old Java Objects,简单javabean对象,没有继承,没有实现,getter,setter方法)对象 作为Action,没有耦合 Action的execute 默认方法不再与Servlet API耦合,更易测试 支持更多视图技术(JSP(转译java...

    用Struts2新建一个应用的方法步骤

    在File Name中输入struts.xml(必须为此名),单击Finish。Struts.xml的代码为: <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ...

    eclipse中setter、getter注释

    eclipse中的setter与getter注释,实体的编写,在代码编写工程中能清晰了解此意

    GIDOT TYPESETTER 3.0.8

    ·关闭时保存编辑现场,包括当前排版助手中的文本以及光标位置 ·小工具箱里增加“去掉汉字间的空格”、“生成随机字符串”两项功能 功能改进: ·快捷工具条增加排版设置按钮 ·更换了玻璃质感的图标 ·其它显示上...

    java简便方法引入getter/setter/tostring等方法

    java 的eclipse或idea等 定义变量时 直接引入lombok.jar包 在类外部 引入@AllArgsConstructor @NoArgsConstructor @Data 简便方法引入getter/setter/tostring等方法

    浅谈JS对象添加getter与setter的5种方法

    1.通过对象初始化器在创建对象的时候指明(也可以称为通过字面值创建对象时声明) (function () { var o = { a : 7, get b(){return this.a +1;},//通过 get,set的 b,c方法间接性修改 a 属性 set c(x){this.a =...

    排版助手gidot typesetter 3.1.1

    排版助手gidot typesetter 是一款比较受欢迎的智能文章排版软件,这款排版软件不大,且不需要安装即可轻松实现编辑排版。 排版助手gidot typesetter主要功能:段落智能修正、去掉某些防拷贝的干扰符、修正段落首尾...

    eclipse 自动为getter和setter 添加中文注释

    eclipse 自动为getter和setter添加中文注释 详细参见 http://blog.csdn.net/kongguoan/article/details/38293137

    Laravel开发-setter

    Laravel开发-setter 将数据库设置与Laravel集成的简单方法。

    Typesetter CMS v5.1.zip

    Typesetter CMS简介 TypesetterCMS是一个功能全面的网站内容管理系统,其嵌入式的管理接口可以让用户在一个简单的浏览器窗口中看到网站的改变。 Typesetter CMS特色功能: 真正的所见即所得编辑器 (CKEditor) ...

    Gidot TypeSetter(排版助手)

    Gidot TypeSetter是一款广受编辑追捧的智能排版整理文章的软件,该软件短小精悍,无需安装即可使用。适合新闻采集员、编辑、文摘网及有文章排版需求者。 软件主要功能:段落智能修正、去掉某些防拷贝的干扰符、修正...

    java普通类编译成json但只是当前类的有getter、setter方法的版本

    java普通类编译成json但只是当前类的有getter、setter方法的版本

    Gidot_Typesetter_3.0.6.rar

    软件名称:排版助手 GIDOT TYPESETTER 当前版本:3.0.6 作者:GIDOT 邮箱:GIDOT@VIP.QQ.COM 网站:WWW.GIDOT.CN/TYPESETTER 新增功能: ·批量排版功能 ·多文本文件合并成单一文本文件 功能改进: ·将排版工具...

    Vue 理解之白话 getter/setter详解

    主要介绍了Vue getter setter,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    u-attributes:创建没有setter的“不可变”对象,只有getters

    这个gem允许您定义“不可变的”对象,使用它时,您的对象将仅具有getter而没有setter。 因此,如果更改[ ] [ ]对象的属性,则将有一个新的对象实例。 也就是说,您可以变换对象而不是对其进行修改。文献资料版本...

    Gidot TypeSetter文章自动排版工具

    Gidot TypeSetter文章自动排版工具

Global site tag (gtag.js) - Google Analytics