. I s...">

Problem iterating over java.util.Map using "JSF" or JSTL TAGS

I am using Richfaces JSF and I want to iterate over Map<Object,Object>

. I see many examples on the Sun forums and other sites, but it doesn't work in my case. Here is my XHTML code:

<c:forEach items="#{order.customOptions}" var="option">
    <h:outputText value="this text does not print" />
    <h:outputText value="#{option.value.name}" />
    <h:outputText value="#{option.value.key}" />
</c:forEach>

      

The order object has a type Order

. "CustomOptios" is of type Map<CustomOption,CustomOptionValue>

. When I create a Javascript alert to print '# {order.customeOptions}, its content is correct, but it's not even included c:forEach loop

.

Update 1: . I tried the list but it doesn't work. I used the list and got the answer on other pages. I also use a4j:poll

, does some other ajax component have a problem with them?

<c:forEach items="#{order.food.cusomableOptions}" var="option">
    <h:outputText value="this text does not print" />
    <h:outputText value="#{option.title}" />
</c:forEach>

      

Update 2: . Conclusion <h:outputText value="#{order.customOptions}" />

:

{model.CustomOption@be8464=model.CustomOptionValue@14e8ac9, 
 model.CustomOption@1ea0c8b=model.CustomOptionValue@78f4, 
 model.CustomOption@24389c=model.CustomOptionValue@3f0bc0, 
 model.CustomOption@a765c=model.CustomOptionValue@3b34ca, 
 model.CustomOption@95868c=model.CustomOptionValue@199de59}

      

Update 3: when I use it outside rich:column

, it works, but when I use it in tags rich:dataTable

and rich:column

, it doesn't work:

<rich:column>
    <f:facet name="header">
        <h:outputText value="xf" />
    </f:facet>
    <c:forEach items="#{order.customOptions}" var="option">
        <p><h:outputText value="option : #{option.key.title}" /></p>
    </c:forEach>
</rich:column>

      

+2


source to share


7 replies


JSTL and JSF don't work seamlessly together in sync, as you would intuitively expect from source ordering. Roughly speaking, JSTL processes the entire page from top to bottom, and then feeds the generated output (thus without any JSTL tags, but with its generated output) to JSF, which in turn processes the entire page from top to bottom.

JSF UIData

components like h:dataTable

and rich:dataTable

have not generated any rows yet when JSTL runs, which makes you see nothing from c:forEach

inside the column.



To fix this, you should rather use JSF supplied iterable components like RichTaces ' a4j:repeat

or Facelets' ui:repeat

, or Tomahawk t:dataList

. They all do less or more than JSTL c:forEach

.

For the rest of JSTL tags, only the functions taglib is useful in JSF, all other tags are supernatural in the JSF environment, as it either provides the same functionality out of the box (core JSTL, and taglib format), or just doesn't fit in the MVC ideology (JSTL sql and xml taglibs).

+1


source


This blog might be helpful as there are some problems when using JSTL tags in JSF.



+4


source


If I need to iterate over a Map, I use a helper class (like Entry) as shown below:

public class Entry {
    private String value;
    private String key;

    public Entry(String value, String key) {
        super();
        this.value = value;
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

      

and a method that converts the map to a list:

private List<Entry> mapToList(Map<String,String> map) {
    List<Entry> list = new ArrayList<Entry>();
    for(String key: map.keySet()) {
        list.add(new Entry(key, map.get(key)));
    }
    return list;        
}

      

XHTML:

<ui:repeat var="entry" value="#{bean.list}" varStatus="i">
    <div>#{entry.key} : #{entry.value}</div>
</ui:repeat>

      

Maybe this will help you ... or maybe not;)

+3


source


If the cycle has not yet been entered, it means that the card is simply empty.

You can diagnose this by putting something like

<h:outputText value="map size: #{order.customOptions.size()}" />

      

before the loop tags, but you have to really set up an IDE like eclipse or Netbeans and run your code inside it so you can use a real debugger - you can make things much easier and faster.

+1


source


Perhaps you shouldn't be mixing JSTL: core tags and JSF: h tags.

Sincerely.

0


source


Just convert the MAP to ArrayList and use h: dataTable and your problem should be resolved.

0


source


You must use the equivalent JSF tag. Have you tried <a4j:repeat/>

?

0


source







All Articles