类的EL表达式

时间:2015-10-22 14:17:13

标签: java jsp el

我不明白如何在EL表达式中表示Class

我有一个EL函数,它接受一个类作为参数(即一个Enum类)来返回可能的枚举值。

我想将其作为EL表达式调用。例如。 ${myTld:enumer(com.example.enums.MyEnum)}

然而:

  • 以上语法将null作为参数
  • 传递
  • 使用MyEnum.class抛出异常,例如无法评估表达式

如何在EL中表达一个类而不可能通过它的字符串表示?

以下作品

<function>
    <description>
        Returns the list of enum values for the given enum class
    </description>
    <name>enumer</name>
    <function-class>com.example.Functions</function-class>
    <function-signature>List enumer(java.lang.String)</function-signature>
</function>

${tld:enumer('com.example.MyEnum')}

我想要什么

    <function-signature>List enumer(java.lang.Class)</function-signature>

2 个答案:

答案 0 :(得分:3)

我想您希望将answerBar.setHeight(55) 个参数传递给您的函数,以避免每次使用Class解析字符串来提高性能...是吗?

如果是这样,我认为有一种方法......如果您事先知道将把函数作为参数传递的类,请使用Class.forName()将它们放入应用程序范围。这可能如下所示:

ServletContextListener

如果您使用的是3.0之前的Servlet API版本,请丢弃上面的@WebListener public class MyEnumInitializer implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { Map<String, Class<?>> map = new HashMap<>(); map.put("MyEnum1", MyEnum1.class); map.put("MyEnum2", MyEnum2.class); // etc. sce.getServletContext().addAttribute("myEnums", map); } public void contextDestroyed(ServletContextEvent sce) {} } 注释,并在@WebListener文件中声明监听器,如下所示:

web.xml

让你的函数占用<listener> <listener-class>mypackage.MyEnumListener</listener-class> </listener> ,你可以按如下方式使用它:

Class

仍有${tld:enumer(myEnums['MyEnum1'])} 到 - String映射,但它涉及使用Class中的Class键定位String对象,比使用反射解析HashMap对象更快。

此外,如果您需要在此Class课程中添加一个您无法预见的初始化应用程序的课程,您仍然可以在有权访问HashMap({{ {1}}不是一成不变的。例如,在接收ServletContext作为参数的任何方法中:

HashMap

干杯,

杰夫

答案 1 :(得分:3)

您无法在普通EL中代表Class。如果是${myTld:enumer(bean.someEnumClass)}返回Class<? extends Enum>,或${myTld:enumer(bean.someEnum['class'])}其中someEnum是实际的Enum,那么你最多可以通过它。 #39; s。将班级名称传递为String确实是最好的选择。

如果您已经使用EL 3.0(可在Servlet 3.1容器上使用,如Tomcat 8,WildFly 8等),则自定义功能的替代方法是使用新的EL直接在JSP中导入它3.0 ImportHandler API:

${pageContext.ELContext.importHandler.importClass('com.example.enums.MyEnum')}

然后${MyEnum}可以使用枚举。

<c:forEach items="${MyEnum.values()}" var="myEnumValue">
    ${myEnumValue}<br/>
</c:forEach>

或者,通过servlet上下文侦听器全局导入${MyEnum},如下所示:

@WebListener
public class Config implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        JspFactory.getDefaultFactory().getJspApplicationContext(event.getServletContext()).addELContextListener(new ELContextListener() {
            @Override
            public void contextCreated(ELContextEvent event) {
                event.getELContext().getImportHandler().importClass(MyEnum.class.getName());
            }
        });
    }

    // ...
}