一个简单的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(Expression Language)表达式在Java Web开发中扮演着重要的角色,尤其是在JSP(Java Server Pages)技术中。本文将详细解释EL表达式的使用方法及其应用场景,帮助开发者更好地理解和掌握这一...
### EL表达式详解 #### 一、EL表达式的概述与基本使用 EL(Expression Language),即表达式语言,是JavaServer Pages (JSP) 2.0标准的一部分,用于简化JSP页面中对数据访问的操作。它允许开发者通过简单的语法在...
此外,在每个JSP文件中也可以通过page directive指令来控制是否忽略EL表达式的解析,通过isELIgnored属性来实现。该属性可以设置为"true"或"false",来决定是否忽略EL表达式。例如,通过以下指令可以关闭对EL表达式...
本资源主要讲解了如何在JSTL中定义和使用自定义的EL表达式,这对于提高JSP页面的可读性和可维护性至关重要。 首先,理解JSTL的基础概念。JSTL由几个核心标签库组成,如fmt、fn、sql、xml等,它们提供了处理日期和...
**EL表达式简介** EL(Expression Language,表达式语言...通过简单使用EL表达式标签,我们可以轻松地在JSP页面中展示和处理数据,实现页面与后台的高效交互。理解和熟练运用EL表达式,对于提升Web开发技能至关重要。
例如,使用EL表达式和`<c:if>`标签可以实现简单的条件判断: ```jsp ${user != null}"> 用户已登录:${user.name} ``` 综上所述,JSTL和EL是JSP开发中非常重要的工具,它们提供了丰富的功能,使开发者能够更加...
EL表达式的主要目标是提高JSP页面的可读性和可维护性,减少脚本代码的数量。 ### EL表达式的基本语法 EL表达式通常以`$`符号开头,后跟大括号`{}`,如`${expression}`。表达式可以是简单的属性引用,也可以包含...
EL表达式常常与JSTL(JavaServer Pages Standard Tag Library)一起使用,以实现更强大的功能。 ##### 1. JSTL简介 JSTL是一组标准标签库,用于简化JSP页面的开发工作,其中包括了条件判断、循环控制等功能。 ####...
EL表达式的语法结构非常简单,主要形式为`{expression}`。这里`expression`代表具体的表达式,它可以是变量名、方法调用等。 ##### 2. 运算符 EL提供了两种运算符用于访问对象属性: - **`.`**:点运算符,用于...
### EL表达式语言详解 #### 9.1 概述 在JSP页面开发中,为了提高代码的可读性和可维护性,开发者们逐渐转向使用标签库来替代传统的Java片段语言来实现页面的显示逻辑。然而,自定义标签虽然灵活,但也容易导致重复...
JSTL也包含了EL表达式的实现,使得在JSP页面上可以直接使用EL语法进行数据操作。 2. **el-api.jar** 和 **el-impl.jar**:这两个jar包分别包含了EL表达式的API接口和其实现。`el-api.jar`定义了EL表达式的接口和类...
此外,EL表达式还可以与JSP动作标签(如`<jsp:useBean>`、`<jsp:setProperty>`等)配合,实现更复杂的业务逻辑。 EL表达式与JavaBeans的结合使用是其核心优势之一。JavaBeans是一种遵循特定规范的Java类,通常用于...
在IT行业中,构建基于Web的应用程序是常见的任务,而Servlet、MySQL、HTML、CSS、JSP和EL表达式是实现这一目标的关键技术。本项目利用IntelliJ IDEA这个强大的集成开发环境(IDE)来整合这些技术,实现了数据库的CRUD...
EL表达式EL表达式 JSTL JSP标准标签库 在EL表达式中只能进行逻辑运算 并不能进行逻辑控制 也就是说 使用了EL表达式 还是无法真正实现JSP页面完全无脚本 这时我们可以借助JSTL来
### EL表达式学习资料 #### 一、EL简介 EL(Expression Language)是Java Server Pages (JSP) 技术中的一种简化的脚本语言,主要用于简化页面开发中对对象和属性的访问过程。EL 表达式允许开发者在 JSP 页面中直接...
首先,`el-api.jar`包含了EL表达式的API定义,定义了EL表达式的语法和行为。这个库提供了一种标准,使得开发者可以使用统一的方式来处理表达式,而无需关心具体的实现细节。例如,你可以使用`${}`来引用JavaBeans的...
在JSP页面中,EL表达式通常以`${}`包裹,可以用来访问页面作用域、请求作用域、会话作用域或应用作用域的属性,以及执行简单的算术运算、条件判断和方法调用。例如: ```jsp <p>Welcome, ${user.name}! ${user....
在本实践项目“练习1:使用EL表达式实现一项问卷调查”中,我们将深入探讨Java Web开发中的一个重要组件——EL(Expression Language),它是JavaServer Pages(JSP)标准的一部分,用于简化网页和JavaBean之间的...
EL表达式极大地简化了JSP页面的开发过程,通过简单的语法和丰富的隐含对象,使得开发者可以更加专注于业务逻辑的实现,而不是页面的布局和样式。了解并熟练掌握EL表达式的使用方法对于提升Web开发效率具有重要意义。
对于需要使用到Fel的特定功能,比如自定义上下文环境,需要按照Fel引擎提供的API进行编程实现。 总体而言,Fel表达式引擎以其轻量级、高效和易用性特点,在Java社区中占据一席之地。尤其对于需要处理复杂逻辑和性能...