Let's say my controller look like this :
public class myController {
private MyCustomItem acte;
...
// getter and setter
}
and the MyCustomItem class have a Set of another class, like this
public class MyCustomItem {
private Set<AnotherClass> signataires;
...
// getter and setter
}
Finally, the AnotherClass item have some String attributes.
What I want to do is, from the view linked to my controller, set those String attributes when I submit a form, so I wrote my view.jsp like this :
<!-- some html before -->
<s:form namespace="/my/namespace" action="MyController_execute">
<s:iterator value="acte.signataires" status="signaStatus">
<s:hidden name="id" value="%{id}" />
<s:property value="collectivite.nom"/>
<s:textfield name="acte.signataires(%{#signaStatus.index}).commentaire" cssStyle="width:250px;"/>
</s:iterator>
<s:submit/>
</s:form>
Afte I submitted the form, in my controller if I try to get some values from my Set<> acte.signataires, they are null :
for (AnotherClass signataire : acte.getSignataires()) {
System.out.println(signataire.getCommentaire()); // this print NULL
}
any help on this ? Is my jsp mapping bad ? I also tried a very simple syntax like <s:textfield name="commentaire" cssStyle="width:250px;"/> but it won't work either
Do you need the property signataires to be a Set ?
I suggest to you to use an ArrayList so that you can access each element by the index (signataires[0], signataires[1], etc...).
Using an ArrayList then you could do in this way:
<s:form namespace="/my/namespace" action="MyController_execute">
<s:iterator value="acte.signataires" status="signaStatus">
<s:hidden name="id" value="%{id}" />
<s:property value="collectivite.nom"/>
<INPUT type="text" name="acte.signataires[<s:property value="%{#signaStatus.index}"/>].commentaire" cssStyle="width:250px;"/>
</s:iterator>
<s:submit/>
</s:form>
Related
I am using struts 2 and I have set up my code like this:
Action class:
public class OrderDetailAction extends BaseActionSupport {
private Collection<ShippingAddress> shippingAddressList;
<the getters and setters here>
private Collection<ShippingAddress> billingAddressList;
<the getters and setters here>
public String displayCreate() {
LOGGER.info("DISPLAY CREATE CALLED");
populateForiegnFields();
LOGGER.info("populate foreign fields done calling");
return SUCCESS;
}
private void populateForiegnFields(){
LOGGER.info("ENTERED POPULATE FOREIGN FIELDS");
ShippingAddressService shippingAddressService = ServiceFactory.getInstance().getShippingAddressService();
shippingAddressList = shippingAddressService.getShippingAddresss();
if(shippingAddressList == null) {
LOGGER.info("shipping address list IS NULL");
} else {
LOGGER.info("shipping address list IS NOT NULL. CONTENTS:");
}
getSession().put("shippingAddressList", shippingAddressList);
billingAddressList = shippingAddressService.getShippingAddresss();
if(billingAddressList == null) {
LOGGER.info("billingAddressList IS NULL");
} else {
LOGGER.info("billingAddressList IS NOT NULL. CONTENTS:");
}
getSession().put("billingAddressList", billingAddressList);
}
And the snippet of my Create Order Detail JSP is:
<s:form>
<div class="form-group">some other fields</div>
<div class="form-group">
<s:select label="SHIPPINGADDRESSID" list="shippingAddressList" listKey="ID" listValue="ID" name="shippingAddress" ></s:select>
</div>
<div class="form-group">
<s:select label="BILLINGADDRESSID" list="billingAddressList" listKey="ID" listValue="ID" name="billingAddress" ></s:select>
</div>
<input class="btn btn-success" type="submit" name="action:createOrderDetail" value="submit" id="displayCreateOrderDetail_createOrderDetail"/>
<input class="btn btn-default" type="submit" name="action:getOrderDetails" value="cancel" id="displayOrderDetail_getOrderDetails" />
</s:form>
The error I am getting is this:
tag 'select', field 'list', name 'shippingAddress': The requested list
key 'shippingAddressList' could not be resolved as a
collection/array/map/enumeration/iterator type
But what confuses me, especially after I looked up this error on other posts
people suggested that the shippingAddressList may never have been instantiated but when I checked the log files that I wrote above, it was not null and at one point, I also logged the values from shippingAddressList.
Are there other reasons I could be getting this error?
Thank you in advance.
First Remove Collection and instead use List.
private List<ShippingAddress> shippingAddressList;
<the getters and setters here>
private List<ShippingAddress> billingAddressList;
<the getters and setters here>
I am not sure why you are putting these two list on session. They will already be on value stack.
I believe your ShippingAddress class have ID property.
Oh boy so here is the error I was making. To make sure people don't run into this headache:
my getters and setters for my shippingAddressList and my billingAddressList were as follows:
get**s**hippingAddressList(); set**s**hippingAddressList()
and
get**b**illingAddressList(); set**b**illingAddressList()
The issue here was that the casing was not proper. Because it was not proper camel case, struts was never able to call the getters and setters.
I have an issue using an attribute of an arraylist in my jsp.
The arraylist in my ActionForm :
private ArrayList<Account> accounts = new ArrayList<Account>();
The class declaration of the Account object in the Arraylist :
public class Account implements Serializable, Cloneable {
private String bic;
public String getBic() {
return bic;
}
public void setBic(final String newBic) {
bic = newBic;
}
}
The call in my jsp :
<bean:write name="BankAccountsActionForm"
property="accounts.get(0).bic" />
The console error :
javax.servlet.jsp.JspException: No getter method for property accounts.get(0).bic of bean BankAccountsActionForm
Do you have a solution or another way to do this?
I have a terrible alternative using a property accountbic1 directly in the form. But it induces lots of work behind to re affect all the temporary attributes to the real ArrayList.
If you have a collection of items in Struts 1.x, then use the <logic:iterate> tag.
Add the struts-logic.tld taglig on top of your JSP as follows:
<%# taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
Then, using <logic:present> and <logic:iterate> you can iterate your ArrayList as follows:
<logic:present name="accounts">
<logic:iterate id="account" name="accounts">
<bean:write name="account.bic" />
</logic:iterate>
</logic:present>
If you want to iterate a collection and access a particular index, use the indexId on <logic:iterate> like so:
<logic:present name="accounts">
<logic:iterate id="account" name="accounts" indexId="index">
<logic:equal name="index" value="0">
<bean:write name="account.bic" />
</logic:equal>
</logic:iterate>
</logic:present>
The same can be done using JSTL:
<logic:present name="accounts">
<logic:iterate id="account" name="accounts" indexId="index">
<c:if test="${index == 0}">
<bean:write name="account.bic" />
</c:if>
</logic:iterate>
</logic:present>
Make sure that Account class has a getter/setter method for attribute bic.
This is simply the error of getter and setter method. recode your getter and setter according to POJO standard as shown below:
Remove final from setter method and change your setter and getter method name as per POJO standard as shown below :
public String getBic() {
return bic;
}
public void setBic(String bic) {
this.bic = bic;
}
try some thing like:
<bean:write name="BankAccountsActionForm" property="accounts.get(1).bic" />
As it is a ArrayList not Array.
Make sure you have getter setter for accounts in in action class ** BankAccountsActionForm **
public List getAccounts ();
public void setAccounts(List acc);
Change your setter and getter method name as per POJO standard as shown below :
public String getBic() {
return bic;
}
public void setBic(final String newBic)
{ bic = newBic; }
It will work fine
remove final from setter method and try again and write it as follows
public void setBic(String bic )
{ this.bic = bic ; }
I am new to Struts2. I have a JSP page which shows a list of Rooms (where Room is a user-defined class). I need to send this entire list to the action class as a hidden field. The JSP code is as follows:
<form method="GET" action="reporting.action" >
<s:hidden name="roomsReport" value="%{allRooms}"/>
<s:textfield name="roomsR" value="%{allRooms}"/>
<s:submit name="action" style="width:220px;" value="Generate Report for Rooms" />
</form>
The textfield (used for testing) shows the address for the list (implying that its not null in the jsp page)
I am still unable to access it in my ReportingAction class using the following code:
System.out.println("xxx"+this.roomsReport.size());
System.out.println(this.roomsReport);
Both above print statements give 0 and [] respectively. I have the getters and setters for roomsReport as follows:
private List<Room> roomsReport;
public List<Room> getRoomsReport() {
return roomsReport;
}
public void setRoomsReport(List<Room> roomsReport) {
this.roomsReport = roomsReport;
}
Can anyone help ?
Finally I could pass the list to the jsp using session
The list is set in a session variable in jsp as follows:
<s:set name="roomsReport" value="%{allRooms}" scope="session" />
In the action class I can access it using the following code:
List<Room> roomsReport = (List<Room>)ActionContext.getContext().getSession().get("roomsReport");
I am a newbie to Spring and I want to create "option group select" But I am unable to do this.
I want an output as following but in HTML type saying
<select name="..." value"...">
<optgroup label="Category 1">
<option ... />
<option ... />
</optgroup>
<optgroup label="Category 2">
<option ... />
<option ... />
</optgroup>
</select>
General
movies
hobbies
Games
football
basketball
Images
officePics
familyPics
PresntationPics
RingTones
pop
classical
jazz
jsp code
Edited : Correct one
<form:select multiple="single" path="servicemodule" id="servicemodule">
<form:option value="None" label="--Select--" />
<c:forEach var="service" items="${servicemodule}">
<optgroup label="${service.key}">
<form:options items="${service.value}"/>
</optgroup>
</c:forEach>
</form:select>
Controller code :
There are 4 main categories and under each of these there can be many subCategories. These can be retrieved from getServiceModuleList method. But I am not getting idea where to implement the loop to store different subcategories under their respective main category.
#Autowired
private ServiceModule servicemodule;
Edited: Correct #ModelAttribute
#ModelAttribute("servicemodule")
public Map<String,List<String>> populateService() {
String[][] mainCategory = new String[7][2];
mainCategory[0][0]= "General"; mainCategory[0][1]= "general1234";
mainCategory[1][0]= "Games"; mainCategory[1][1]= "games1234";
mainCategory[2][0]= "Images"; mainCategory[2][1]= "images1234";
mainCategory[3][0]= "Ringtones"; mainCategory[3][1]= "ringtone1234";
Map<String,List<String>> serviceModule=
new LinkedHashMap<String,List<String>>();
List<String> subCategory=new ArrayList<String>();
List<ServicesPojo> services=
servicemodule.getServiceModuleList("1",mainCategory[0][1],"0");
for(ServicesPojo serviceName: services)
{
subCategory.add(serviceName.getServiceName().trim());
}
serviceModule.put(scats[0][0],subService);
return serviceModule;
}
Edited: Got the Answer for Loop
for(int i=0;i<mainCategory.length;i=i+2){
List<String> subCategory=new ArrayList<String>();
List<ServicesPojo> services=
servicemodule.getServiceModuleList("1",mainCategory[0][i],"0");
for(ServicesPojo serviceName: services)
{
subCategory.add(serviceName.getServiceName().trim());
}
serviceModule.put(mainCategory[i][0],subCategory);
}
Model
This has the main error whether I should keep only String or List Confused!!
Edited: Now Corrected one
private List<String> servicemodule;
public List<String> getServicemodule() {
return servicemodule;
}
public void setServicemodule(List<String> servicemodule) {
this.servicemodule = servicemodule;
}
Error Description
org.springframework.beans.NotReadablePropertyException:
Invalid property 'serviceModule' of bean class
[springx.practise.model.SiteModel]: Bean property 'serviceModule'
is not readable or has an invalid getter method:
Does the return type of the getter match the parameter type of the setter?
Solved!!
Watch you case: servicemodule != serviceModule.
The <c:foreEach> loop isn't correct either: it uses itemGroup both for var and varStatus, and itemGroup is never used inside the loop. Instead, serviceModule is used, but is not defined anywhere.
And I have a hard time understanding your code, one of the reasons being that you use the same name for very different things and don't pluralize attributes of type List.
private ServiceModule servicemodule;
...
Map<String,List<String>> serviceModule
...
private List<String> servicemodule;
...
<form:select multiple="single" path="serviceModule" id="serviceModule">
...
<c:forEach var="itemGroup" items="${servicesModule}" varStatus="itemGroup">
No wonder you lost yourself.
I feel this should be exceedingly obvious, but so far I've failed to find an answer.
I want to have a list of strings (or an array of strings, I really don't care) get populated by form data in Struts2.
I've seen several examples of how to do indexed properties with beans, but wrapping a single string inside an object seems fairly silly.
So I have something like
public class Controller extends ActionSupport {
private List<String> strings = new ArrayList<String>();
public Controller() {
strings.add("1");
strings.add("2");
strings.add("3");
strings.add("4");
strings.add("5");
}
public String execute() throws Exception {
return ActionSupport.SUCCESS;
}
public List<String> getStrings() {
return strings;
}
public void setStrings(List<String> s) {
strings = s;
}
}
...
<s:iterator value="strings" status="stringStatus">
<s:textfield name="strings[%{#stringStatus.index}]" style="width: 5em" />
</s:iterator>
The form fields get populated with their initial values (e.g. 1, 2, etc), but the results are not properly posted back. setStrings is never called, but the values get set to empty strings.
Anybody have any idea what's going on? Thanks in advance!
I believe as you have it, your jsp code would render something like:
<input type="text" name="strings[0]" style="width: 5em" value="1"/>
<input type="text" name="strings[1]" style="width: 5em" value="2"/>
<input type="text" name="strings[2]" style="width: 5em" value="3"/>
...
Notice that the name of the field references are "strings[x]" where as you need the name to be just "strings". I would suggest something like:
<s:iterator value="strings" status="stringStatus">
<s:textfield name="strings" value="%{[0].toString()}" style="width: 5em" />
</s:iterator>
Not sure if the value attribute above may is correct, but I think something like this will get you the desired result.