JSTL forEach遍历实现Iterable的用户定义类

时间:2018-10-19 16:28:53

标签: java foreach jstl

我的问题类似于此处的问题: JSTL - Using forEach to iterate over a user-defined class 但是,(简单明了的)解决方案对我不起作用,因此我再次询问是否需要任何建议。

我有一个实现Iterable接口的简单类,

public class Lizt implements Iterable<String> {

  private ArrayList<String> inner = new ArrayList<>();

  public Lizt(){
    this.inner.add("A");
    this.inner.add("B");
  }

  @Override
  public Iterator<String> iterator() {
    return inner.iterator();
  }

  public Iterable<String> getInner(){
    return this.inner;
  }
}

(暂时忽略“ getInner()”函数)。 然后,我有一个简单的JSP页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="lst" scope="session" class="model.Lizt"/>
<html>
<body>
<ul>
<c:forEach var="item" items="${lst}">
    <li>${item}</li>
</c:forEach>
</ul></body></html>

因此,我尝试遍历实现Iterable的实例。但是,服务器还向我返回了

javax.servlet.ServletException: org.apache.jasper.JasperException: An exception occurred processing JSP page [/forEachTest.jsp] at line [7]
...
Caused by: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in &lt;forEach&gt;

如果我替换JSP表达式以直接访问内部内部字段,例如

<c:forEach var="item" items="${lst.inner}">

...一切正常。我的Iterable和ArrayList的Iterable有何区别?

感谢您提前提出建议。

2 个答案:

答案 0 :(得分:1)

区别在于ArrayList是一个Collection,而您的类不是。这是JSTL规范说的:

  

支持的收藏集和当前项目   项目必须支持下面列出的数据类型   [...]

     
      
  • 数组[...]
  •   
  • java.util.Collection的实现[...]
  •   
  • java.util.Iterator的实现[...]
  •   
  • java.util.Enumeration的实现[...]
  •   
  • java.util.Map的实现[...]
  •   
  • 字符串
  •   

如您所见,Iterable未列出。

答案 1 :(得分:1)

亚当·根特(Adam Gent)对已接受答案的评论说:

  

要说明的是,JSTL forEach不支持forEach类型的可迭代(非常令人讨厌)。因此,您需要执行$ {projectSet.iterator()}

forEach根本不支持Iterable,这可能是违反直觉的。不过,它确实支持iterator,我认为您应该更容易使用它。

您可以在方法supportedTypeForEachIterator()的{​​{3}}的源代码中找到证据。