How to access ValueStack objects within Struts iterator? - java

I have following code:
<s:iterator value="reviews">
<img src="<s:property value="#request.restaurant.portalImage.url" />" />
<s:property value="user.firstName" />
<s:property value="user.lastName" />
<s:property value="rating" />
<s:property value="review" />
</s:iterator>
reviews is a list of review objects which contain details of a review, such as rating and name of user.
My problem is that I'm not able to access any of the objects present on the ValueStack within the loop.
Outside the loop <s:property value="#request.restaurant.portalImage.url" /> works correctly. But within the loop it prints null.
AFAIK an iterator pushes it's collection on the ValueStack so that all OGNL expressions resolve against it. But I've used # which means I'm explicitly specifying the root object for resolution.
Why is it still not working?

I just spent my whole afternoon fighting against a similar issue.
In my case, the issue was that my iterator variable (In your case reviews) had a field with the same name as the outer variable.
No matter how hard I tried to break out of the local stack of the iterator, it would not access the outer variable.
If your reviews iterator has a field called restaurant its going to override the outer restaurant variable, no matter how hard you try :(
The solution I found was to simply rename the outer variable. (eg: theRestaurant)
Once I renamed it, it was no longer clashing with the inner variable, and I was able to access it from within the iterator.

I am not sure what object is contained in the collection you are using in the Iterator.As per the iterator when you iterate the collection using the S2 iterator tag it will push the object on the top of value stack, which means, say you have collection of user object on which you are iterating like
<s:iterator value="userCollection">
</s:iterator>
so when this will iterate, S2 iterator will push the user object on top of value stack and if we want to refer to the name property of user object, all we need to refer to the name property
<s:property name="userName"/>
since OGNL will try to resolve userName in the value stack and we already have user object as top level object in value stack.I suggest to go through the Iterator tag documentation and how it push values
S2 Iterator tag

You should change it like below:
<s:iterator value="reviews" var="varrequest">
<img src="<s:property value="#varrequest.restaurant.portalImage.url" />" />
<s:property value="#varrequest.user.firstName" />
<s:property value="#varrequest.user.lastName" />
<s:property value="#varrequest.rating" />
<s:property value="#varrequest.review" />
</s:iterator>
Using a iterator reference variable to fetch the unique index object.

I think it resolves your issue
s:iterator value="reviews" status="position">
<img src="<s:property value="#request.restaurant.portalImage.url"/>"/>
<s:property value="#position.user.firstName"/>
<s:property value="#position.user.lastName"/>
<s:property value="#position.rating"/>
<s:property value="#position.review"/>
</s:iterator>
your requirement is little confusing

Related

How to retrieve dynamically generated name tag for s:set for Struts2?

How can I retrieve a dynamically generated name tag for <s:set> on Struts 2?
E.g.:
In my action class I have an object (currency) that have this fields: 'id' and 'symbol'.
So in my view page I can use this:
<s:iterator value="currency">
<s:set name="var_%{id}" value="symbol"/>
<s:set name="total_%{id}" value="%{0.0}"/>
</s:iterator>
So I can use this to create these PageContext variables like "var_BRL", "var_USD", "var_MXN" and "total_BRL", "total_USD", "total_MXN" etc. If I write the following code:
<s:property value="#var_USD"/> = <s:property value="#total_USD"/>
I'm able to retrive a result like:
USD = 0.0
I'm using these #total_XXX variables to sum some values under some conditions presented by another iterator, in a way that I'll have at the end of this other iteraction, a result of the total spent in every currency (BRL, USD, MXN etc).
But when I try to retrieve these values dynamically, nothing is rendered. Following is the code I'm using to retrieve the values from these variables, at the end of my page. I don't understand OGNL very well, so I've tryed different arrangements like the ones below and had no success with any of them:
<s:iterator value="currency">
<s:property value="#var_%{id}"/> = <s:property value="#total_%{id}"/>
<s:property value="#%{var_%{id}}"/> = <s:property value="#%{total_%{id}}"/>
<s:property value="%{#var_%{id}}"/> = <s:property value="%{#total_%{id}}"/>
</s:iterator>
Is there a solution to retrieve these values in the PageContext? Or can I only solve this inside my Action? I've searched so many posts but I couldn't find anything.
Thank you!
LZ
discussing with a friend, I found the proper OGNL expression to call for the dynamically created variables names at the end of my code:
<s:iterator value="currency">
<s:property value="#attr['var_'+id]"/> = <s:property value="#attr['total_'+id]"/><br>
</s:iterator>

Struts2 nested iteration through Lists using dynamic variables

I'm iterating through a List<SomeObject>, but I want only to print out certain attributes of SomeObject depending on the attributes specified in another List. So far, I have got it. What I'm not sure, how to use the item in the List as the attribute of SomeObject that I want to print out.
<s:iterator value="theList" var="listItem" status="theListCount">
<s:iterator value="listOfAttributes" var="attr" status="attrListCount">
Attribute=<s:property value="#attr"/> Value=<s:property value='#listItem.[%{#attr}]'/>
</s:iterator>
</s:iterator>
No need to force OGNL in the part of the expression
<s:iterator value="theList" var="listItem" status="theListCount">
<s:iterator value="listOfAttributes" var="atr" status="attrListCount">
Attribute=<s:property value="#atr"/> Value=<s:property value="#listItem[#atr]"/>
</s:iterator>
</s:iterator>
First of all #attr is a reserved keyword, so don't use it as a variable value. And use [] notation to reference property of the object.
<s:iterator value="theList" var="listItem" status="theListCount">
<s:iterator value="listOfAttributes" var="atrbt" status="attrListCount">
Attribute=<s:property value="#atrbt"/> Value=<s:property value="#listItem[#atrbt]"/>
</s:iterator>
</s:iterator>

how to access a struts2 property value in jsp?

<s:iterator value="MyList" status="idx">
<% int index = %><s:property value = '%{#idx.index}'/><% ; %>
</s:iterator>
The above code does not work.
how can the integer value of the 'idx' be stored in the variable 'index'?
Instead of using java variables creating a struts variable works fine.
<s:set name="newVariable" value="%{#idx.index}" />
whenever you need to access the newly created struts variable. You can use this
<s:property value="#newVariable" />
you can access the list value in jsp using
<s:property value="dataname"/>
dataname is your pojo generated database columns

Struts2 - OGNL parameterized name

I have a generic jsp which is in charge of printing some values, the values depends on a parameter.
For example, I have an object car with and attribute color and a object house with the same attribute, I want to use the same jsp receiveng the name of the object as a parameter.
<jsp:include page="/jsp/prv/generic/PaintColor.jsp" >
<jsp:param name="element" value="car" />
</jsp:include>
So, I want to print the value of car color. I try to do it like this:
<s:set var="propertyName">${param.element}.color<s:set/>
<s:property value="%{#attr.propertyName}" />
It doesnt work, but if I do
<s:textfield name="%{#attr.propertyName}"/>
it works perfect.
How can I use the parametrized name in avalue?
I finally solve it accesing the value from a java scriptlet

Struts 2.0 - dynamically append the s:property value

I have some objects of same type in action class..
E.g.:
LivingThings fish = new LivingThings("FISH");
LivingThings dog = new LivingThings("DOG");
LivingThings lion = new LivingThings("LION");
The contents of each objects will be different.
Also in the same action class I have a list with values as the name of the objects
i.e.
ArrayList<String> animalsList = new ArrayList<String>();
animalsList.add("fish");
animalsList.add("dog");
animalsList.add("lion");
=====
Now in the jsp page, I need dynamically get the object contents using the animalsList contents. i.e.
<s:iterator value="animalsList" id="eachAnimal">
<s:property value="#eachAnimal.lifespan" />
</s:iterator>
Here all I am trying to do is, instead of directly giving the code like
<s:property value="fish.lifespan" />
<s:property value="dog.lifespan" />
<s:property value="lion.lifespan" />
Somehow, I need append the object name from the animalsList list. Is it possible in struts 2.0. I am little bit confused with OGNL concept.
I tried these scenarios:
<s:iterator value="animalsList" id="eachAnimal">
<s:property value="#eachAnimal.lifespan" />
<s:property value="%{eachAnimal}.lifespan" />
<s:property value="%{#eachAnimal}.lifespan" />
</s:iterator>
Can someone give me suggestions?
Maybe it is not the best way to handle such case, but what you asking for could be done something like so:
<s:iterator value="animalsList" id="eachAnimal">
<s:property value="#attr[#eachAnimal].lifespan" />
</s:iterator>

Categories