一个简单的el表达式实现
实现还在完善种,现在只能处理引用类型的的属性字段和函数,不支持容器类数组!不支持子类型
线来个测试用例
package com.isnowfox.oel; import java.util.Date; import com.isnowfox.core.junit.BaseTest; import com.isnowfox.util.RandomUtils; /** * el 测试用例 * @author zuoge85 * */ public class OelTest extends BaseTest{ public void testBasObject() throws UnknownKeyException{ OelEngine oel = OelEngine.getInstance(); TestObject obj = new TestObject(); Date date = new Date(); int number = RandomUtils.randInt(); String string = "测试用例"; obj.dateField =date; obj.setDateProperty(date); obj.intField =number; obj.setIntProperty(number); obj.stringField = string; obj.setStringProperty(string); obj.dateMethod(date); assertEquals(date, oel.el(obj, "dateProperty")); assertEquals(date.getTime(), oel.el(obj, "dateProperty.time")); assertEquals(date, oel.el(obj, "dateField")); assertEquals(date.getTime(), oel.el(obj, "dateField.time")); assertEquals(date, oel.el(obj, "dateMethod()")); assertEquals(date.getTime(), oel.el(obj, "dateMethod().time")); assertEquals(number, oel.el(obj, "intField")); assertEquals(number, oel.el(obj, "intProperty")); assertEquals(string, oel.el(obj, "stringField")); assertEquals(string, oel.el(obj, "stringProperty")); } }
package com.isnowfox.oel; import java.util.Date; public class TestObject { public int intField; public String stringField; public Date dateField; private int intProperty; private String StringProperty; private Date dateProperty; private Date dateMethod; public int getIntProperty() { return intProperty; } public void setIntProperty(int intProperty) { this.intProperty = intProperty; } public String getStringProperty() { return StringProperty; } public void setStringProperty(String stringProperty) { StringProperty = stringProperty; } public Date getDateProperty() { return dateProperty; } public void setDateProperty(Date dateProperty) { this.dateProperty = dateProperty; } public Date dateMethod(){ return dateMethod; } public void dateMethod(Date dateMethod){ this.dateMethod = dateMethod; } @Override public String toString() { return "TestObject [intField=" + intField + ", StringField=" + stringField + ", dataField=" + dateField + ", intProperty=" + intProperty + ", StringProperty=" + StringProperty + ", dataProperty=" + dateProperty + "]"; } }
下面是实现
package com.isnowfox.oel; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.CtNewMethod; import javassist.NotFoundException; import com.isnowfox.oel.KeyInfo.Type; /** * oel引擎 * @author zuoge85 * */ public class OelEngine { private static final boolean DEBUG = true; private static final String PACKAGE_NAME = OelEngine.class.getPackage().getName(); private static Map<Class<?>, Class<?>> primitivesWrapMap = new HashMap<Class<?>, Class<?>>(16); static{ primitivesWrapMap.put(boolean.class, Boolean.class); primitivesWrapMap.put(byte.class, Byte.class); primitivesWrapMap.put(char.class, Character.class); primitivesWrapMap.put(double.class, Double.class); primitivesWrapMap.put(float.class, Float.class); primitivesWrapMap.put(int.class, Integer.class); primitivesWrapMap.put(long.class, Long.class); primitivesWrapMap.put(short.class, Short.class); primitivesWrapMap.put( void.class, Void.class); } public static final OelEngine getInstance(){ return Inner.instance; } private Map<String,OelProxy> cacheMap = new HashMap<>(); private AtomicInteger itemSeed = new AtomicInteger(); public Object el(Object obj,String el) throws UnknownKeyException{ if(obj == null){ throw new NullPointerException("null"); } try { Class<?> cls = obj.getClass(); String cacheKey = cls.getName() + el; OelProxy p =cacheMap.get(cacheKey); if(p==null){ ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass(PACKAGE_NAME + ".MyOelProxy" + itemSeed.incrementAndGet()); cc.addInterface(pool.get(PACKAGE_NAME +".OelProxy")); CtMethod method = CtNewMethod.make("public Object el(Object obj);", cc); method.setBody(makeMethod(cls, obj, el)); cc.addMethod(method); if(DEBUG){ cc.debugWriteFile("debug"); } p = (OelProxy) cc.toClass().newInstance(); cacheMap.put(cacheKey, p); } return p.el(obj); } catch (NotFoundException|CannotCompileException|InstantiationException|IllegalAccessException e) { throw new RuntimeException(e); } } private String makeMethod(Class<?> cls, Object obj, String el) throws UnknownKeyException{ int varSeed = 0; StringBuilder sb = new StringBuilder("{\n"); String[] keys = el.split("\\."); sb.append(cls.getCanonicalName() + " var_" + (++varSeed) + " = (" +cls.getCanonicalName() + ")$1;\n" ); for(String key:keys){ KeyInfo info =analyse(cls,key); int nextVar = varSeed++ ; switch (info.getType()) { case FIELD: sb.append(info.getCls().getCanonicalName() +" var_" + varSeed + " = var_"+ nextVar +"." + key + ";\n"); break; case PROPERTY: sb.append(info.getCls().getCanonicalName() +" var_" + varSeed + " = var_"+ nextVar +"." + info.getMethodName() + "();\n"); break; case METHOD: sb.append(info.getCls().getCanonicalName() +" var_" + varSeed + " = var_"+ nextVar +"." + key + ";\n"); break; default: break; } cls = info.getCls(); } if(cls.isPrimitive()){ cls = wrap(cls); sb.append("return "+cls.getCanonicalName()+".valueOf(var_" + varSeed + ");}"); }else{ sb.append("return var_" + varSeed + ";}"); } return sb.toString(); } private KeyInfo analyse(Class<?> cls,String key) throws UnknownKeyException{ try { if(key.endsWith("()")){ try { Method method = cls.getMethod(key.substring(0, key.length()-2)); return new KeyInfo(Type.METHOD, method.getReturnType()); } catch (Exception e2) { } } PropertyDescriptor prop = new PropertyDescriptor(key, cls); return new KeyInfo(Type.PROPERTY, prop.getPropertyType(), prop.getReadMethod().getName()); } catch (IntrospectionException e) { //属性没找到那么可能是field Field field; try { field = cls.getField(key); return new KeyInfo(Type.FIELD, field.getType()); } catch (Exception e1) { } } throw new UnknownKeyException("未知的 key:"+key +",cls:"+ cls); } private Class<?> wrap(Class<?> cls){ return primitivesWrapMap.get(cls); } public Object part(Object Obj,String name){ return null; } private static class Inner{ private static final OelEngine instance = new OelEngine(); } }
相关推荐
关于EL表达式语言的简单总结,里面结合有EL表达式的各种使用方法,以及EL表达式配合JSTL的使用
EL表达式EL表达式 JSTL JSP标准标签库 在EL表达式中只能进行逻辑运算 并不能进行逻辑控制 也就是说 使用了EL表达式 还是无法真正实现JSP页面完全无脚本 这时我们可以借助JSTL来
EL表达式 (详解) EL表达式 1、EL简介 1)语法结构 ${expression} 2)[]与.运算符 EL 提供.和[]两种运算符来存取数据。 当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用 ...
jsp+servlet+el 分页 实现的简单 分页
jstl+EL ,一些简单的代码实现,主要介绍了EL的语法,以及JSTL的几个常用标签,需要的可以下载查看。
本小小系统采用JSP实现了JSTL标记标签结合EL表达式一起使用. 适合JSP初学者适用 适合教学讨论使用 -- 评论返还积分
JavaEE+JDBC+Servlet+EL表达式的员工信息管理系统源码+数据库+项目说明(高分课设).zip # :heart: JavaEE+JDBC+Servlet+EL表达式的员工信息管理系统 ## 介绍 简易的员工管理系统,包括信息的增删改查,新增员工...
用EL表达式和JSTL标签实现的缺点就是无法实现异步效果,整个页面是重新刷新了一遍的。 二、如果是普通的html页面,当然是无法使用EL表达式和JSTL标签的,这时只能通过异步Ajax的方式去实现。当然了,JSP页面两种...
用来支持ognl表达式的,类似于EL表达式,功能比EL表达式强大的多。 freemarker-2.3.15.jar freemarker是比jsp更简单好用,功能更加强大的表现层技术,用来替代jsp的。 在Struts2中提倡使用 freemarker模板,但实际...
由于时间有限,直接将个人实现的JSP上传至...对于JSP里的html:select及其html:option几乎只用直接拷贝,没什么需要修改的(除了修改页面的EL表达式);如果有不懂的,可以直接联系我;电子邮件:zyyceo@gmail.com; QQ:114948587
4.进行验证码收发操作,系统进入后展示商品列表,利用c标签将db入库的数据进行动态渲染,el表达式进行数据取值展示,添加购物车利用ajax请求 5.进行添加购物车、移除购物车的技术实现,根据所添加的购
能学到什么:①练习JSP,EL表达式,SERVLET关键点技术项目;②分层开发的管理系统,都是如何设计和实现的,简单的展现,通俗易懂。 阅读建议:此资源以开发简化版jsp学习其原理和内核,不仅是代码编写实现也更注重...
jQuery+CSS3文字跑马灯特效是一款将跑马灯背景制作为3D立方体效果,文字在上面移动时,就像是文字投影到墙壁上,在转角出会改变运动方向。 效果图如下: ... <!...meta name="viewport" content="width=device-width,...
MVC+DAO设计模式实现的的留言管理 可以实现简单的留言添加修改查看和删除 包含了登录验证,EL表达式+javabean
Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型...
Jsp+Servlet+Cookie实现记住密码,自动登录,防止表单提交,记录登录次数的新手例子。简单明了,大量注释,El表达式等。
使用集合类、EL表达式以及标准标签库,实现在客户端对所查询的结果集分页的效果,简单实用!
对于j2EE的简单web开发,其中有各种j2EE web开发过程中会使用到的技巧,如el表达式,jstl自定义标签,过滤器的使用等 通过这些来实现登录 注册 修改 删除 分页 等功能
最近写一个给用户组添加角色的功能,要求一边是未添加的角色,一边是已添加的角色,还有搜索功能, 点击添加后,ajax保存操作. 考虑功能为待查询功能分页 , 下方分页条, 一共有 2*2 ,4个ajax… JS代码如下: ...
压缩包内包含《Java Web程序设计任务教程》教材第13-15章的教材资源,即传智书城项目,包括数据库文件。 说明文件: 【代码相关】 ...网上书城开发记录、注册功能邮箱调试、(基本语法)EL表达式与JSTL