今天重构以前代码过程中发现一个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完全是过分的要求。
分享到:
相关推荐
在Struts2中,接收参数是常见的操作,这涉及到用户通过HTTP请求传递的数据如何被框架捕获和处理。这篇博客文章可能深入探讨了Struts2如何在Action类中获取和管理这些参数。 首先,Struts2的核心是DispatcherServlet...
本篇文章将深入探讨Struts2中Action接收参数的多种方式,以及相关源码解析。 首先,最常见的接收参数方式是通过方法签名直接接收。例如,如果在JSP页面上有这样一个表单: ```jsp 提交" /> ``` 对应的Action...
在Struts2中,你可以创建领域对象,通过setter和getter方法来接收和设置请求参数,这些对象可以在多个Action之间共享,提高了代码的复用性。 4. **Struts2_2.1.6版本的中文问题** 在某些版本的Struts2中,可能出现...
### Struts2中的参数传递 #### 一、概述 在Web开发中,Struts2框架因其灵活、高效的特点被广泛采用。Struts2的核心之一就是它对于参数传递的支持能力,这一点主要依赖于OGNL(Object-Graph Navigation Language)...
在Struts2中,JSON插件允许我们在Action中返回JSON格式的数据,以便于JavaScript进行异步处理。要使用JSON插件,你需要下载并添加相应的JAR文件到项目的类路径中,例如`jsonplugin-0.33.jar`和其他Struts2的核心库。...
在这个案例中,我们将深入探讨Struts2中的ConverterType,以及如何实现一个自定义的类型转换器来处理坐标(x,y)的数据。 首先,了解Struts2的类型转换机制。默认情况下,Struts2会根据Action类中属性的数据类型...
- **自动填充**:Struts2 自动从 request 中获取数据并填充到 Action 对象中。 - **原理**:通过拦截器实现,拦截器会查找与 Action 类中的 setter 方法相匹配的请求参数,并调用这些方法填充数据。 **3.3 数据传递...
在Struts2中,类型转换和国际化是两个重要的特性,用于处理数据类型之间的转换以及多语言环境下的内容显示。 **类型转换**是Struts2处理请求参数与Action类属性之间数据类型不匹配的过程。当用户通过表单提交请求时...
这篇博客文章可能详细探讨了如何在Struts2中使用ModelDriven接口来接收和处理请求参数。 ModelDriven接口允许开发者将一个对象绑定到Action上下文中,这个对象可以被用来存储和传递业务逻辑层的数据。当Action类...
在Struts2中,我们可以通过Spring或Apache DBCP等第三方库来管理数据源。配置文件如Web.xml或应用的特定配置文件中应包含数据库连接参数,如URL、用户名、密码等。 进行CRUD操作时,我们需要设计对应的实体类,这些...
### Struts 2中实现CRUD操作详解 #### 一、引言 CRUD操作是软件开发中最常见的数据处理方式之一,它代表了对数据进行的四种基本操作:创建(Create)、读取(Read)、更新(Update)与删除(Delete)。在企业级应用开发中,...
在Struts 2中,类型转换器(Type Converter)扮演着至关重要的角色,它负责将HTTP请求中的字符串数据转换为应用程序所需的对象类型。当我们需要对默认类型转换器的功能进行扩展或者处理自定义类型时,就需要自定义...
值得注意的是,这种方式中模型对象需要被实例化,但不需要提供 setter 方法,因为 Struts2 会直接修改模型对象的属性。 ### 总结 Struts2 提供了多种灵活的方式来处理参数接收。直接设置变量适用于简单场景;使用...
Struts框架是Java Web开发中常用的一个开源MVC框架,由Apache软件基金会维护。在Struts1.2版本中,实现多文件上传是一项常见的需求,它允许用户在一次提交中上传多个文件,这对于数据交互、资源分享等场景非常实用。...
在整合Struts2和Hibernate进行开发时,首先需要理解这两个框架的基本工作原理。Struts2通过FilterDispatcher作为中央控制器,接收HTTP请求,然后根据配置文件(struts.xml)中的Action配置,调用相应的Action类执行...
本篇文章将深入探讨Struts2中“对象.属性”注入的原理与实践。 #### 二、Struts1与Struts2的区别 ##### Struts1中的FormBean 在Struts1框架中,每当提交表单时,表单中的属性值首先会被赋给FormBean对象。开发者...
### Struts2框架学习笔记整理 #### 一、Struts2框架概述 ...通过对Struts2的学习,开发者不仅可以掌握其基本用法,还能深入理解其内部原理和技术细节,从而更好地利用这一强大工具解决实际项目中的问题。