在使用Struts2、WebWork框架开发Web应用时,JSP页中的表单项,常常会使用这样的参数名:
<input type="text" name="person.username" />
<input type="password" name="person.password" />
甚至,可以有更多层次的,如:
<input type="text" name="person.username.firstname" />
<input type="text" name="person.username.lastname" />
上面第一例,在后端Java代码中,自然有一个Person类与之对应。其中,这个Person类包含2个属性:username, password,还有必要的Setter和Getter方法。
上面第二例,同样有一个Person类与之相对应,而Person类中包括了一个Username类型的属性"username";而在Username类里,有firstname和lastname两个属性。同样,相应的Setter和Getter方法是必不可少的。
那么,那些框架是怎么自动将型如"person.username.firstname"的字符串,组装成相应的对象(如Person对象)的呢?
请看以下代码:
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.provider.bean;
import com.opensymphony.provider.BeanProvider;
import com.opensymphony.provider.ProviderConfigurationException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.StringTokenizer;
/**
* BeanProvider implementation for accessing properties.
*
* Can handle a.b.c.d -> getA().getB().getC().getD().
* Access properties in this order: bean.getA(), bean.isA(), bean.a(), bean.a.
*
* Can also deal with setter methods.
*
* @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
* @version $Revision: 1.1.1.1 $
*/
public class DefaultBeanProvider implements BeanProvider {
//~ Static fields/initializers /////////////////////////////////////////////
private static String GET = "get";
private static String SET = "set";
private static String IS = "is";
//~ Methods ////////////////////////////////////////////////////////////////
public boolean setProperty(Object object, String property, Object value) {
if ((property == null) || (object == null)) {
return false;
}
// Split out property on dots ( "person.name.first" -> "person","name","first" -> getPerson().getName().getFirst() )
StringTokenizer st = new StringTokenizer(property, ".");
if (st.countTokens() == 0) {
return false;
}
// Holder for Object at current depth along chain.
Object current = object;
try {
// Loop through properties in chain.
for (int i = 0; st.hasMoreTokens(); i++) {
String currentPropertyName = st.nextToken();
if (i < st.countTokens()) {
// This is a getter
current = invokeProperty(current, currentPropertyName);
} else {
// Final property in chain, hence setter
try {
// Call setter
Class cls = current.getClass();
PropertyDescriptor pd = new PropertyDescriptor(currentPropertyName, current.getClass());
pd.getWriteMethod().invoke(current, new Object[] {value});
return true;
} catch (Exception e) {
return false;
}
}
}
// Return holder Object
return true;
} catch (NullPointerException e) {
// It is very likely that one of the properties returned null. If so, catch the exception and return null.
return false;
}
}
public Object getProperty(Object object, String property) {
if ((property == null) || (object == null)) {
return null;
}
// Split out property on dots ( "person.name.first" -> "person","name","first" -> getPerson().getName().getFirst() )
StringTokenizer st = new StringTokenizer(property, ".");
if (st.countTokens() == 0) {
return null;
}
// Holder for Object at current depth along chain.
Object result = object;
try {
// Loop through properties in chain.
while (st.hasMoreTokens()) {
String currentPropertyName = st.nextToken();
// Assign to holder the next property in the chain.
result = invokeProperty(result, currentPropertyName);
}
// Return holder Object
return result;
} catch (NullPointerException e) {
// It is very likely that one of the properties returned null. If so, catch the exception and return null.
return null;
}
}
public void destroy() {
}
public void init() throws ProviderConfigurationException {
}
/**
* Convert property name into getProperty name ( "something" -> "getSomething" )
*/
private String createMethodName(String prefix, String propertyName) {
return prefix + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);
}
/**
* Invoke the method/field getter on the Object.
* It tries (in order) obj.getProperty(), obj.isProperty(), obj.property(), obj.property.
*/
private Object invokeProperty(Object obj, String property) {
if ((property == null) || (property.length() == 0)) {
return null; // just in case something silly happens.
}
Class cls = obj.getClass();
Object[] oParams = {};
Class[] cParams = {};
try {
// First try object.getProperty()
Method method = cls.getMethod(createMethodName(GET, property), cParams);
return method.invoke(obj, oParams);
} catch (Exception e1) {
try {
// First try object.isProperty()
Method method = cls.getMethod(createMethodName(IS, property), cParams);
return method.invoke(obj, oParams);
} catch (Exception e2) {
try {
// Now try object.property()
Method method = cls.getMethod(property, cParams);
return method.invoke(obj, oParams);
} catch (Exception e3) {
try {
// Now try object.property()
Field field = cls.getField(property);
return field.get(obj);
} catch (Exception e4) {
// oh well
return null;
}
}
}
}
}
}
oscore-2.2.5中的类,代码不难,且有注释,我就不多解析了。如有疑问,请提出来,我尽力解决。
分享到:
相关推荐
2,使用+运算符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串再连接,如:${3 + "5"},结果是:35 使用内建的int函数可对数值取整,如: ${ (x/2)?int } ${ 1.1?int } ${ 1.999?int } ${ -1.1?int } ...
2. **数据类型**:PHP支持整型、浮点型、字符串、布尔型、数组、对象、NULL以及资源等多种数据类型。 3. **流程控制**:包括条件语句(if...else)、循环结构(for、while、do...while、foreach)、开关结构...
3. 数据类型:PHP支持多种数据类型,包括整型、浮点型、字符串、布尔型、数组、对象、NULL等。 4. 条件语句:如`if...else`,`switch...case`用于根据条件执行不同的代码块。 5. 循环结构:`for`、`while`、`do......
2. 输出:`echo` 和 `print` 用于输出字符串,`echo` 比 `print` 稍快,两者都可以同时输出多个值。 3. 注释:单行注释使用 `//` 或 `#`,多行注释使用 `/* ... */`。 【控制结构】 1. 条件语句:`if...else if......
3. **数据类型**:PHP支持多种数据类型,包括字符串、整型、浮点型、数组、对象等。例如: ```php $age = 30; // 整型 $height = 1.78; // 浮点型 $name = "Jane Smith"; // 字符串 $isActive = true; // 布尔...
3. 字符串(string) 4. 布尔型(bool) 5. 数组(array) 6. 对象(object) 7. NULL 8. 资源(resource) **流程控制** - 条件语句:`if...else`、`switch...case` - 循环语句:`for`、`while`、`do...while`、`...
根据标签修剪,清理和修改结构字符串字段。 更新2016年1月12日-现在也适用于嵌入式结构 变成这个... type Person struct { FirstName string `conform:"name"` LastName string `conform:"ucfirst,trim"` ...
常见的数据类型有字符串、整型、浮点型、布尔型、数组和对象。 ```php $greeting = "你好"; // 字符串 $age = 25; // 整型 $height = 1.78; // 浮点型 $isStudent = true; // 布尔型 ``` ### 控制结构 PHP提供了...
- **字符串**(string) - **数组**(array) - **对象**(object) 这些数据类型覆盖了常见的编程需求,为编写灵活多变的应用程序提供了支持。 ##### 3.3 条件语句 条件语句允许根据不同的条件执行不同的代码块...
PHP支持多种数据类型,包括字符串、整型、浮点型、布尔型、数组和对象等。数组在PHP中尤为重要,因为它们可以用来存储和操作大量数据。例如: ```php $myArray = array("apple", "banana", "cherry"); echo $...
这段代码定义了一个字符串变量并将其打印出来。 【PHP与HTML的结合】 在PHP中,我们可以直接在HTML代码中嵌入PHP语句,实现动态网页生成。例如: ```html <!DOCTYPE html> echo "当前时间是:" . date("Y-m-d ...