Class JSP中的JSP EL私有静态类
我有以下建议:Class JSP中的JSP EL私有静态类,class,jsp,static,el,private,Class,Jsp,Static,El,Private,我有以下建议: <%@ page import="java.util.Arrays" %> <%@ page import="java.util.List" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html><body> <%! private static class Test { private String val2;
<%@ page import="java.util.Arrays" %>
<%@ page import="java.util.List" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html><body>
<%!
private static class Test {
private String val2;
private String val1;
public Test(String v1, String v2) {
val1 = v1;
val2 = v2;
}
public String getVal1() {
return val1;
}
public String getVal2() {
return val2;
}
};
private static List<Test> ITEMS = Arrays.asList(new Test("1","1"),new Test("2","2"));
%>
<%
pageContext.setAttribute("ITEMS",ITEMS);
%>
<c:forEach var="item" items="${ITEMS}">
${item.val1},${item.val2}
</c:forEach>
</body></html>
因此EL迭代集合,但由于某种原因,forEach中的${item}变成了字符串
然而,当您简单地将私有静态类
更改为公共静态类
时,一切正常
我认为这不是问题,因为我们有解决办法。但我不明白为什么在这种情况下它需要公开。JSP被翻译成servlet,所以在翻译后的java代码中它仍然可以看到这一点。EL不仅仅是获取对象属性的反射材料(在我们的例子中,属性是public
,所以EL应该可以在不使用反射修饰符的情况下获取它)
如果有人知道-请回复。我将非常感激!
提前谢谢。我没有所有的答案,但我可以帮你一点忙。 Tomcat使用BeanELResolver在使用JavaBeans组件体系结构的对象上定义属性解析行为。由于您没有遵守JavaBean约定,因此没有定义行为。如果您使用
private static class Test implements java.io.Serializable {
这将导致
javax.el.PropertyNotFoundException: Property 'var1' not found on type org.apache.jsp.test_jsp$Test
看看JSP使用ELResolver链解析EL变量。以下是EL分解器链层次结构:
- 复合溶出器
- 隐式对象解析器
- 复合溶出器
- 插入式旋转变压器
- MapELResolver
- ResourceBundleeResolver
- 列表解决程序
- 阵列分解器
- BeanELResolver
- ScopedAttributeResolver
项将使用BeanELResolver解析。BeanELResolver要求对象遵循某些规则,将其称为Bean
。一个这样的属性是,每个属性都应该有setter和getter
您看到的异常是因为您没有为bean中的属性定义setters被JSP引擎翻译成。EL表达式在运行时由
当JSP声明Test
为private
时,通过对表达式语言引擎的内省,其方法(默认情况下)不可见
以下是WebSphere Application Server翻译的forEach
中的一个片段:
do {
out.write(_jsp_string4);
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl
.proprietaryEvaluate("${item.val1}", java.lang.String.class,
(PageContext)pageContext, _jspx_fnmap, false));
out.write(_jsp_string5);
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl
.proprietaryEvaluate("${item.val2}", java.lang.String.class,
(PageContext)pageContext, _jspx_fnmap, false));
out.write(_jsp_string1);
int evalDoAfterBody = _jspx_th_c_forEach_0.doAfterBody();
if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
break;
} while (true);
EL设计用于JavaBeans;bean强制使用一个没有参数构造函数的公共类。更新:但是,在私有静态类
${item.class.name}
返回org.apache.jsp.test\u jsp$test
的情况下,EL不会将${item}转换为字符串……它只是不能接受${item.val1}出于某些原因…不太理解它…简单地说:类和getter需要对BeanELResolver可见。因此是公共的,而不是私人的。
do {
out.write(_jsp_string4);
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl
.proprietaryEvaluate("${item.val1}", java.lang.String.class,
(PageContext)pageContext, _jspx_fnmap, false));
out.write(_jsp_string5);
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl
.proprietaryEvaluate("${item.val2}", java.lang.String.class,
(PageContext)pageContext, _jspx_fnmap, false));
out.write(_jsp_string1);
int evalDoAfterBody = _jspx_th_c_forEach_0.doAfterBody();
if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
break;
} while (true);