我不明白如何用EL表达式表示Class。
我有一个EL函数,它以类作为参数(即Enum类)来返回可能的枚举值。
我想以EL表达式的形式调用它。例如${myTld:enumer(com.example.enums.MyEnum)}
然而:
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>发布于 2015-10-22 15:00:47
您不能在普通EL中表示Class。如果它是像so ${myTld:enumer(bean.someEnumClass)}返回的Class<? extends Enum>那样的bean属性,或者是someEnum是实际Enum的${myTld:enumer(bean.someEnum['class'])},则最多可以传递它,但仅此而已。以String的形式传递类名是最好的选择。
如果您已经使用了EL 3.0 (可以在Servlet3.1容器(如Tomcat 8、WildFly 8等)上使用),那么您的自定义函数的另一种选择是立即在JSP3.0中导入它,如下所示,使用新的El3.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());
}
});
}
// ...
}发布于 2015-10-22 15:00:12
我想您希望将Class参数传递给您的函数以提高性能,避免每次使用Class.forName()解析字符串.是真的?
如果是这样的话,我想有个办法.如果预先知道将函数作为参数传递给您的类,请使用ServletContextListener将它们放入您的应用程序范围。这可能如下所示:
@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) {}
}如果在3.0之前使用Servlet版本,请放弃上面的@WebListener注释并在web.xml文件中声明侦听器,如下所示:
<listener>
<listener-class>mypackage.MyEnumListener</listener-class>
</listener>如果您的函数接受Class,您可以如下所示使用它:
${tld:enumer(myEnums['MyEnum1'])}仍然存在String到Class的映射,但是它需要使用HashMap中的String键来定位Class对象,这比使用反射解析Class对象要快。
此外,如果您需要在这个HashMap中添加一个在初始化应用程序时无法预见的类,那么您仍然可以在可以访问ServletContext的任何地方(HashMap不是不可变的)来实现它。例如,在接收作为参数的HttpServletRequest的任何方法中:
public void aMethod(HttpServletRequest req, [other params]) {
// ...
Map<String, Class<?>> myEnums = (Map<String, Class<?>>) req.getSession().getServletContext().getAttribute("myEnums");
if (!myEnums.containsKey("aNewEnum")) {
myEnums.put("aNewEnum", NewEnum.class);
}
// ...
}干杯,
杰夫
https://stackoverflow.com/questions/33283260
复制相似问题