javax.servlet.ServletException:javax.servlet.jsp.JspTagException:不知道如何迭代提供的“项目";在 <forEach> [英] javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>

查看:19
本文介绍了javax.servlet.ServletException:javax.servlet.jsp.JspTagException:不知道如何迭代提供的“项目";在 <forEach>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个保存结果的 Bean.我需要使用 JSTL 对其进行迭代并呈现结果.这是豆子:

I have a Bean that holds the results. I need to use JSTL to iterate over it and present the results. Here is the bean:

public class DetResults
{
    private List<String> headings;
    private List<Class<?>> types;
    private List<Object[]> data;

    public DetResults() {}

    public List<String> getHeadings() { return this.headings; }
    public String getHeading(int which) { return this.headings.get(which); }

    public List<Class<?>> getTypes() { return this.types; }
    public Class<?> getType(int which) { return this.types.get(which); }

    public List<Object[]> getData( ) { return this.data; }
    public Object[] getDataAtRow( int row ) { return this.data.get(row); }


    public void setHeadings( List<String> val ) { this.headings = val; }
    public void setHeadings( String[] val ) { this.headings = Arrays.asList(val); }
    public void addHeading( String val ) 
    { 
        if( this.headings == null ) this.headings = new ArrayList<String>();
        this.headings.add(val); 
    }

    public void setTypes( List<Class<?>> val ) { this.types = val; }
    public void setTypes( Class<?> val[] ) { this.types = Arrays.asList(val); }
    public void addType( Class<?> val ) 
    {
        if( this.types == null ) this.types = new ArrayList<Class<?>>();
        this.types.add(val); 
    }


    public void setData( List<Object[]> val ) { this.data = val; }

    // allow NPE to get thrown
    public void setDataAtRow( Object[] val, int row ) { this.data.set(row, val); }

    public void appendDataRow( Object[] val ) 
    {
        if( data == null ) data = new ArrayList<Object[]>(); 
        this.data.add(val); 
    }

    public int getColumnCount() { return this.headings!=null?this.headings.size():0; }

}

这是将 bean 设置为 JSP 的处理程序:

Here is the handler that will set the bean to the JSP:

DetResults results = detDAO.fetchDetResults(paramBean);
request.setAttribute("results", results);
action.setJspURI(".../.jsp");

我尝试如下显示:

<c:forEach var="results" items="${results}">
    ${results.heading}
</c:forEach>

但它抛出了以下异常:

引起:javax.servlet.ServletException:javax.servlet.jsp.JspTagException:不知道如何迭代提供的项目";在 <forEach>

Caused by: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>

如果我像这样在处理程序页面上记录结果:

If I log the results on my handler page like this:

System.out.println( "

there are " + results.getColumnCount() + " columns in the result set" );
for( int i=0; i<results.getColumnCount(); i++ )
{
    System.out.println( results.getHeading(i) + " --> " + results.getType(i) );
}

日志似乎在服务器上显示正常.

The logging seems to show fine on the server.

推荐答案

Caused by: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: 不知道如何迭代

没有引用它可以迭代的有效对象时,就会发生这种情况.对象应该是一个 Object[](一个普通数组),一个 集合MapIterator, 枚举String(另见 源代码). 不能迭代任何其他内容.您的 DetResults 类不是上述任一类型的实例,因此它会失败.

That will happen when the <c:forEach items> does not refer a valid object over which it can iterate. The object should be an Object[] (a plain array), a Collection, Map, Iterator, Enumeration or String (see also source code). Anything else can't be iterated by <c:forEach>. Your DetResults class is not an instance of either of the aforementioned types, so it will fail.

您的 DetResults 类看起来不正确.它看起来基本上就像一个神豆,具有多个个体实体的所有属性的集合.这个不对.一个 bean 类最多应该代表一个实体.重写您的 DetResults 类,以便您基本上得到一个完整的 javabeans 集合:

Your DetResults class doesn't look right. It look basically like one God bean with a collection of all properties of multiple individual entities. This is not right. A bean class should represent at most one entity. Rewrite your DetResults class so that you basically end up with with a fullworthy collection of javabeans:

List<DetResult> results = detDAO.fetchDetResults(paramBean);

以便您可以按如下方式访问它:

so that you can access it as follows:

<c:forEach items="${results}" var="result">
    ${result.heading}
    <c:forEach items="${result.data}" var="dataItem">
        ${dataItem}
    </c:forEach>
</c:forEach>

如果你真的坚持保持你的 DetResults bean 原样,你可以按如下方式访问它:

If you really insist to keep your DetResults bean as it is, you could access it as follows:

<c:forEach begin="0" end="${results.columnCount}" varStatus="loop">
    ${results.headings[loop.index]}
    <c:forEach items="${results.data[loop.index]}" var="dataItem">
        ${dataItem}
    </c:forEach>
 </c:forEach>

另见:

  • 使用 JavaBean 的地方?
  • 使用 MVC 和 DAO 模式在 JSP 页面中以 HTML 格式显示 JDBC ResultSet莉>

    与具体问题无关 属性不对.您不应为其赋予与范围内现有对象相同的名称.只会冲突.但是,如果您无法解释错误消息,则需要提出一个新问题.

    Unrelated to the concrete problem, the <c:forEach var> attribute is not right. You should not give it the same name as an existing object in the scope. It would only clash. But that's subject for a new question if you can't interpret the error message.

    这篇关于javax.servlet.ServletException:javax.servlet.jsp.JspTagException:不知道如何迭代提供的“项目";在 &lt;forEach&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆