如何利用反射实现EL表达式
来源:互联网 发布:贾扬清caffe百度百科 编辑:程序博客网 时间:2024/05/29 03:11
http://www.sxt.cn/u/482/blog/2498
反射机制
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
JSP的规范中,有个表达式语言(Expression Language, 简称EL),可以算是一个微型的语言,其中对request, page, session, application中预存的JavaBean对象的引用方式很是简单。最近正好需要写一个支持简单EL的taglib,所以就研究了下Java反射机制,目前基本上实现了多级bean的属性的访问,经测试,还是可以用的。如:
public
static
void
main(String[] args){
UserBean bean =
new
UserBean();
bean.setName(
"John Abruzzi"
);
bean.setNick(
"Abruzzi"
);
bean.setAge(
24
);
AddressBean addr =
new
AddressBean();
addr.setZip(
"0086"
);
addr.setStreet(
"Bell Street #12"
);
bean.setAddress(addr);
System.out.println(BeanParser.doParse(bean,
"bean.address.street"
));
System.out.println(BeanParser.doParse(bean,
"bean.address.zip"
));
System.out.println(BeanParser.doParse(bean,
"bean.name"
));
System.out.println(BeanParser.doParse(bean,
"bean.nick"
));
System.out.println(BeanParser.doParse(bean,
"bean.age"
));
}
反射,即由一个抽象的对象(如Object),取出这个具体对象的属性或者方法(就EL中关于Bean的引用来说,这个定义已经够了)。在EL中,对一个Bean的某字段进行引用,只需 ${bean.field},当然,这个bean是已经被set到容器中的,这就是Java反射机制。
我们从容器中取出以bean为名字的Object,通过Java反射机制知道它的真实类型,然后通过field以javabean规范拼出方法名,进行调用,如果这个表达式是多级的,如${bean.field.field},其中第一个field本身就是一个bean对象,同样需要递归的进行解析。
现有一个UserBean, 其中的一个字段Address本身又是一个AddressBean。
package
elparser;
public
class
AddressBean {
private
String street;
private
String zip;
public
String getZip() {
return
zip;
}
public
void
setZip(String zip) {
this
.zip = zip;
}
public
String getStreet() {
return
street;
}
public
void
setStreet(String street) {
this
.street = street;
}
}
然后是UserBean
1
.
package
elparser;
2
.
3
.
public
class
UserBean {
4
.
private
String name;
5
.
private
String nick;
6
.
private
AddressBean address;
7
.
private
int
age;
8
.
9
.
public
int
getAge(){
10
.
return
this
.age;
11
. }
12
.
13
.
public
void
setAge(
int
age){
14
.
this
.age = age;
15
. }
16
.
17
.
public
String getName() {
18
.
return
name;
19
. }
20
.
public
void
setName(String name) {
21
.
this
.name = name;
22
. }
23
.
public
String getNick() {
24
.
return
nick;
25
. }
26
.
public
void
setNick(String nick) {
27
.
this
.nick = nick;
28
. }
29
.
public
AddressBean getAddress() {
30
.
return
address;
31
. }
32
.
public
void
setAddress(AddressBean address) {
33
.
this
.address = address;
34
. }
35
.}
Bean都是很简单的,考虑到对基本类型的支持,所以在UserBean中加入一个int型的字段age
好了,看看怎么通过一个串和一个对象来取出其中的字段来:
1
.
package
elparser;
2
.
3
.
import
java.lang.reflect.Method;
4
.
5
.
public
class
BeanParser {
6
.
7
.
private
static
String getMethodName(String property, String prefix){
8
. String prop = Character.toUpperCase(property.charAt(
0
))+property.substring(
1
);
9
.
10
. String methodName = prefix + prop;
11
.
12
.
return
methodName;
13
. }
14
.
15
.
private
static
Object parse(Object bean, String expr){
16
. Class beanClass = bean.getClass();
17
.
18
. Method method =
null
;
19
. Object result =
null
;
20
.
21
.
try
{
22
.
//这两步是关键,get方法不需要传入参数,所以只是new出两个空数组传入
23
. method = beanClass.getMethod(getMethodName(expr,
"get"
),
new
Class[]{});
24
. result = method.invoke(bean,
new
Object[]{});
25
. }
catch
(Exception e){
26
. System.out.println(e.getMessage());
27
. }
28
.
29
.
return
result;
30
. }
31
.
32
.
public
static
Object doParse(Object bean, String expr){
33
. String keys[] = expr.split(
"\\."
);
34
.
35
. Object obj =
null
;
36
.
37
.
for
(
int
i =
1
; i < keys.length;i++){
38
. obj = parse(bean, keys[i]);
39
. bean = obj;
40
. }
//递归parse
41
.
42
.
return
obj;
43
. }
44
.
45
.
public
static
void
main(String[] args){
46
. UserBean bean =
new
UserBean();
47
. bean.setName(
"John Abruzzi"
);
48
. bean.setNick(
"Abruzzi"
);
49
. bean.setAge(
24
);
50
.
51
. AddressBean addr =
new
AddressBean();
52
. addr.setZip(
"0086"
);
53
. addr.setStreet(
"Bell Street #12"
);
54
. bean.setAddress(addr);
55
.
56
. System.out.println(BeanParser.doParse(bean,
"bean.address.street"
));
57
. System.out.println(BeanParser.doParse(bean,
"bean.address.zip"
));
58
. System.out.println(BeanParser.doParse(bean,
"bean.name"
));
59
. System.out.println(BeanParser.doParse(bean,
"bean.nick"
));
60
. System.out.println(BeanParser.doParse(bean,
"bean.age"
));
61
. }
62
.}
代码比较简短,重要部分有注释,应该很容易理解。当然这篇文章主要是关于Java的反射机制,如果需要对EL完全支持,可以使用JavaCC做一个简单的分析器(Apache的commons中包含一个el的项目,就是用javacc写的分析器)。
反射,即由一个抽象的对象(如Object),取出这个具体对象的属性或者方法(就EL中关于Bean的引用来说,这个定义已经够了)。在EL中,对一个Bean的某字段进行引用,只需 ${bean.field},当然,这个bean是已经被set到容器中的,这就是Java反射机制。
我们从容器中取出以bean为名字的Object,通过Java反射机制知道它的真实类型,然后通过field以javabean规范拼出方法名,进行调用,如果这个表达式是多级的,如${bean.field.field},其中第一个field本身就是一个bean对象,同样需要递归的进行解析。
==========
http://www.thinksaas.cn/group/topic/102025/
- 如何利用反射实现EL表达式
- 如何实现利用EL表达式去获取用户头像
- 反射机制实现EL表达式的解析过程
- EL表达式漏洞利用
- jsp页面中利用EL表达式实现时间格式转换
- jsp页面中利用EL表达式实现时间格式转换
- el表达式如何计算
- 如何使用EL表达式?
- el表达式实现原理
- EL表达式如何嵌套使用
- javaScript如何使用EL表达式
- 如何在jsp页面中利用el表达式的<p>${error }</p>取值?
- 利用el表达式回填form下拉框
- 利用el表达式回填form下拉框
- 利用EL表达式替换回车符
- 利用反射实现BaseDao
- 力所能及之Java反射机制(模拟EL表达式)
- JAVA反射机制-EL表达式获取对象属性的原理
- 如何设置TextField前的图片
- linux--简介
- 《鸟哥的Linux私房菜-基础学习篇(第三版)》(四)
- MySQL ERROR 1005: Can't create table (errno: 150)解决办法
- 中国互联网公司最新最全阵亡名单
- 如何利用反射实现EL表达式
- 怎么配置FTP站点
- redis --- noSQL数据库
- 程序员十层楼
- cocos2d-x 3.X用progressTimer制作血槽
- 一个关于中国省市区的字典,数组嵌套使用
- Android中的Activity和Service是否属于同一个进程
- Android之横竖屏切换内容丢失问题解决方法
- 俏皮的sed