开发者

How can I work with Iterables in my JSP pages?

I'm using an API that makes heavy use of Iterables (java.lang.Iterable), but I can't use them directly on开发者_如何学编程 my JSP pages because JSTL tags and EL can not process them. Right now, I'm transforming each iterable to a list prior to rendering them.

What would be the cleanest and simplest approach to make it work without previous transformations? Do newest JSTL-Jasper-EL-taglibs-etc. versions support it? Where can I found that information? I don't find anything about it googling...

I know I can use Iterable.iterator(), but I can't call that method inside the JSP, only in my controller class, and this is very limiting.


To access the iterators of your Iterables in EL expressions in your JSTL tags, you could use Java code (in your model, controller or service layer) that wraps your Iterable objects in instances of a class Iter that looks like this (with a simple getter method that follows the Java beans method name convention):

public class Iter<T> {

    private final Iterable<T> iterable;

    public Iter(Iterable<T> iterable) {
        this.iterable = iterable;
    }

    public Iterator<T> getIterator() {
        return iterable.iterator();
    }
}


You can implement your own JSP tags in Java, so you could write a tag that accepted an Iterable and then use that in the same way as you'd use the JSTL forEach tag.

This documentation has an example on how to create a custom tag that iterates through an arbitrary custom object - your implementation would likely be simpler. The key is in returning EVAL_BODY_AGAIN to allow you to process the body of the tag multiple times.

http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags6.html#68297

I haven't tried running this, but it might be something to start with:

public class IterableForEachTag extends BodyTagSupport {
    private static final long serialVersionUID = 1L;
    private Iterable<?> iterable = null;
    private Iterator<?> iterator = null;
    private String var = null;

    public int doStartTag() throws JspException {
        if (iterator == null) {
            iterator = iterable.iterator();
        }
        if (iterator.hasNext()) {
            Object element = iterator.next();
            pageContext.setAttribute(var, element);
            return (EVAL_BODY_AGAIN);
        } else
            return (SKIP_BODY);
    }

    public int doAfterBody() throws JspException {
        if (bodyContent != null) {
            try {
                JspWriter out = getPreviousOut();
                out.print(bodyContent.getString());
                bodyContent.clearBody();
            } catch (IOException e) {
                throw new JspException(e);
            }
        }
        if (iterator.hasNext()) {
            Object element = iterator.next();
            pageContext.setAttribute(var, element);
            return (EVAL_BODY_AGAIN);
        } else {
            return (SKIP_BODY);
        }
    }

    public void setIterable(Iterable i) {
        iterable = i;
        iterator = null;
    }

    public void setVar(String v) {
        var = v;
    }
}


You can create a Map with your Iterables as a key, and their Iterators as values. Then you should be able to access the Iterators using your Iterables in your JSP using JSTL/EL.

Further reading:

  • Calculate total sum of all numbers in c:forEach loop, a very interesting and thought provoking post -- having several apt solutions.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜