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中的属性定义setter

s被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);