I am new to struts2 and facing one issue.
I have following datastructure.
class Employee extends actionsupport{
Private List<Address> address;
....getters and setters
}
class Address {
private String street_name;
Private City_name;
......and so on
... getters and setters
}
how to iterate over this list in JSP using <s:iterate> tag. I tried many combination but some way it is not working for me.
I believe the best way is to use Struts2 iterator tag which needs to provide collection as a data-source to iterator over.
<s:iterator value="address">
<s:property value="street_name"/>
<s:property value="City_name"/>
//so on
</s:iterator>
When Iterator will iterator over the address it will place the object (Address in your case) on the top of value stack and you can refer to these properties directly as described above
<s:iterator value="%{address}" var="addr">
<s:property value="%{street_name}"/>
<s:property value="#addr.street_name"/>
</s:iterator>
Related
I have an Action class and a Data class like below
Action Class
public class TestAction extends ActionSupport{
private Data aData;
}
Data class
public class Data {
private char v1;
private char v2; etc till 17;
public accessors for all variables above;
}
My jsp is like below
JSP snippet
<s:set var="varName" value="'data.v'"/>
<s:iterator var="idx" begin="1" end="17">
<s:set var="prop" value="#varName+#idx"/>
<s:property value="<WHAT TO DO HERE TO GET THE VALUES STORED IN THE VARIABLES>"
</s:iterator
Whatever I put in the s:property tag's value attribute, (%{#prop}, #arr#prop, [prop]), I get the literal Strings data.v1, data.v2, ... data.v17 in my output and NOT the values stored in the data.v1, data.v2, etc. variables.
Can you please let me know how I can get the values stored in the data object.
Edit based on duplicate question suggestion struts-2-warning-the-default-value-expression-contains-evaluated-to-nullnu
The suggested question is a double evaluation of the value in the variable, whereas what I am looking for is a double evaluation of the variable. After submitting my original question, I came across another question with a comment that the double evaluation I am looking for is not supported. I have mentioned this as a comment in my own question, requesting for confirmation as it was not quite clear in the other question as well.
Struts 2, 2.3.20 mentioned that
Support for accessing static methods from expression will be disabled
soon, please consider re-factoring your application to avoid further
problems!
We have used OGNL static calls in validators:
#ExpressionValidator(
expression = "#foo.bar#isValidAmount(amount)",
key = "validate.amount.is.not.valid"),
Also we used it in tags
<s:set var="test"
value="#foo.bar#sampleMethod(#attr.sampleObject.property1)" />
Well, what is the best way to refactor above two usages ?!
In your code you are using a static method call. The best way is to create a method in the action class that wraps a static methods and use it in OGNL.
public class Wrapper {
public boolean isValidAmount(amount){
return foo.barr.isValidAmount(amount);
}
public Object sampleMethod(Object property1){
return foo.barr.sampleMethod(Object property1);
}
}
As soon as action bean is in the value stack you can use
#ExpressionValidator(
expression = "isValidAmount(amount)",
key = "validate.amount.is.not.valid"),
or in JSP
<s:set var="test"
value="sampleMethod(#attr.sampleObject.property1)" />
i am using hibernate to save large amount of text as BLOB in the DB. Thus I have a class instance as byte[].
public class News {
...
private byte[] content;
// getter and setter
...
}
I am trying to output such variable as String in JSP, e.g. using <s:property> tag. Can anyone give a hint?
Struts2 uses OGNL http://commons.apache.org/ognl/. So in JSP do it like you would do it in Java.
<s:property value="new java.lang.String(news.content)"/>
I have this bean class
Class Address {
private String addressId;
private Set<Location> setOfLocations;
// more attributes
//getters and setters
}
Class Location{
private Long locationId;
private String locationName
private String nearestHospital;
//getters and setters
}
in the jsp I have a textField controls for the Address class members, and also for Location class members one for locationName and nearestHospital.
the Address class members map normally because the model driven interface map them to their respective fields. the problem is how i can map the location textFields to a location object inside Set member of the Address class
Add new item to collection
Using type conversion and a list instead of a set, this will work to add a new item to the list:
<s:textfield name="locations[%{locations.size()}].locationName"/>
If you want to use a set, then I don't know how to achieve what you want without spending some time digging, but you will want to start here.
Display and edit existing collection items
On the other hand, if you were to want to be able to display and edit an existing collection, then this should work if you use a list instead of a collection:
<s:iterator var="listItem" value="yourList" status="listStatus">
<s:set name="paramName">yourList[${ listStatus.index }].someField</s:set>
<s:textfield name="%{#paramName}" value="%{#listItem.someField}"/>
</s:iterator>
Here, your model would have a list called yourList. The items in yourList contain a field called someField. We are able to set the value onto the fields by setting the request parameter name to be in the form yourList[2].someField so that OGNL will evaluate this and set the parameter value onto the someField field of item 2 of yourList.
Using your classes as you show them above but with changing the locations to a list, we would have:
<s:iterator var="location" value="listOfLocations" status="locationStatus">
<s:set name="paramName">listOfLocations[${ locationStatus.index }]</s:set>
<s:hidden name="%{#paramName}.locationId" value="%{#location.locationId}"/>
<s:textfield name="%{#paramName}.locationName" value="%{#location.locationName}"/>
<s:textfield name="%{#paramName}.nearestHospital" value="%{#location.nearestHospital}"/>
</s:iterator>
Or, if you are using JSTL, this will do the same:
<c:forEach var="location" items="${ listOfLocations }" varStatus="locationStatus">
<s:set name="paramName">listOfLocations[${ locationStatus.index }]</s:set>
<s:hidden name="%{#paramName}.locationId" value="%{#location.locationId}"/>
<s:textfield name="%{#paramName}.locationName" value="%{#location.locationName}"/>
<s:textfield name="%{#paramName}.nearestHospital" value="%{#location.nearestHospital}"/>
</c:forEach>
Is it possible to convert different paremeters into one object on your action?
Say from my html form, I pass in variables, "firstname", "lastname". Can I write a type converter that will convert those into a Person object on my action?
I didn't see any examples of this, and I don't see API. I don't see how I can access the value stack in the StrutsTypeConverter to get to the other variables.
Thanks!
Example :
// JavaBeans
public class Person {
#Getter #Setter private String firstname;
#Getter #Setter private String lastname;
}
// Action
#Setter private Person person;
// form
<s:form>
<s:textfield name="person.firstname" />
<s:textfield name="person.lastname" />
</s:form>
Similar example : vaannila : Domain Object as JavaBeans Property
I am agree what lschin said.you can use the build in OGNL and value stack combination to achieve what you want.still if u need some specific type conversion machanism here are the details from the Struts2 docs
Struts2 Type Conversion