Hello,
I have a Struts 6.4 page with a select, and I have a problem populating the
list attribute.
<s:select id="searchView_showSecured" data-mdb-select-init=""
name="searchView.showSecured" theme="simple" list="yesNoAllList"
listKey="id" listValue="label" />
What I'm trying to do is relatively simple: I have the following action code:
public class MachineParameterOverviewBootstrapAction extends
OverviewActionSupport implements Expirable {
...
}
And this is the super action. Notably, this getter does NOT have an underlying
field property.
public class OverviewActionSupport extends BaseActionSupport {
...
public List<SelectOptionView> getYesNoAllList() {
return
BootstrapSupport.getInstance().getYesNoAllList();
}
}
In the Tomcat log, I get this error:
Caused by: tag 'select', field 'list', name 'searchView.showSecured': The
requested list key 'yesNoAllList' could not be resolved as a
collection/array/map/enumeration/iterator type. Example: people or
people.{name} - [unknown location]
at
org.apache.struts2.components.Component.fieldError(Component.java:284)
at org.apache.struts2.components.Component.findValue(Component.java:363)
at
org.apache.struts2.components.ListUIBean.evaluateExtraParams(ListUIBean.java:78)
at
org.apache.struts2.components.Select.evaluateExtraParams(Select.java:101)
at org.apache.struts2.components.UIBean.evaluateParams(UIBean.java:884)
at org.apache.struts2.components.UIBean.end(UIBean.java:550)
at
org.apache.struts2.views.jsp.ComponentTagSupport.doEndTag(ComponentTagSupport.java:40)
at
org.apache.jsp.jsp.machineparameter.machineParameterOverviewBootstrap_jsp._jspx_meth_s_005fselect_005f1(machineParameterOverviewBootstrap_jsp.java:11949)
at
org.apache.jsp.jsp.machineparameter.machineParameterOverviewBootstrap_jsp._jspService(machineParameterOverviewBootstrap_jsp.java:1209)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466)
... 118 more
I assumed that Struts 6.4 would use getters and setters to interact with
properties on the page, because AFAIK that's what it did in Struts 2.3 and 2.5,
and hence I could just use a getter without having a field property with the
corresponding name on the action. Is that assumption incorrect?
For completeness, this is BootstrapSupport.java:
public final class BootstrapSupport extends ActionSupport {
/**
*
*/
private static final long serialVersionUID =
3159663106530217293L;
private BootstrapSupport() {
loadYesNoAllOptionsMap();
}
private static final BootstrapSupport INSTANCE = new
BootstrapSupport();
/**
* The text provider, initialized with an instance of the
CustomTextProvider.
*/
private final transient TextProvider textProvider = new
CustomMessageResourcesFactory().createInstance(getClass(),
this);
private List<SelectOptionView> yesNoAllList;
private List<SelectOptionView> yesNoList;
public static BootstrapSupport getInstance() {
return INSTANCE;
}
/**
* This is used to help generate the yesnoall options dojo string
*/
private static final int YNA_NO =
CommonUtils.DO_NOT_SHOW_ENTRIES;
private static final int YNA_YES = CommonUtils.SHOW_ENTRIES;
private static final int YNA_ALL = CommonUtils.SHOW_ALL_ENTRIES;
// Operating System description
private static final String[][] YESNOALLDESCRIPTIONS = {
{ YNA_YES + "",
MasterCodeDescriptionKeys.MC_YESNOALL_YES },
{ YNA_NO + "",
MasterCodeDescriptionKeys.MC_YESNOALL_NO },
{ YNA_ALL + "",
MasterCodeDescriptionKeys.MC_YESNOALL_ALL } };
// Operating System description
private static final String[][] YESNODESCRIPTIONS = { { YNA_YES
+ "", MasterCodeDescriptionKeys.MC_YESNOALL_YES },
{ YNA_NO + "",
MasterCodeDescriptionKeys.MC_YESNOALL_NO } };
/**
* This method is automatically called by Struts, it injects the
value of the
* StrutsConstants.STRUTS_CUSTOM_I18N_RESOURCES. The values is
set as the static
* field of the CustomLocalizedTextUtil class, which is needed
when loading
* messages from the resource bundles.
*
* @param strutsCustomI18nResources The property value
*/
@Inject(StrutsConstants.STRUTS_CUSTOM_I18N_RESOURCES)
public void setStrutsCustomI18nResources(String
strutsCustomI18nResources) {
if
(CustomLocalizedTextUtil.getStrutsCustomI18nResources() == null) {
CustomLocalizedTextUtil.setStrutsCustomI18nResources(strutsCustomI18nResources);
CustomLocalizedTextUtil.clearDefaultResourceBundles();
}
}
/**
* @see com.opensymphony.xwork2.ActionSupport#getText(String)
*/
public String getText(String aTextName) {
return textProvider.getText(aTextName);
}
/**
* This generates the Bootstrap String for the YesNoAll Options.
*/
private void createAutocompleteViewListForYesNoAllOptionsMap() {
yesNoAllList = new
ArrayList<SelectOptionView>();
for (String[] yesNoAllOption :
YESNOALLDESCRIPTIONS) {
SelectOptionView
selectOptionView = new SelectOptionView();
selectOptionView.setLabel(getText(yesNoAllOption[1]));
selectOptionView.setId(yesNoAllOption[0]);
yesNoAllList.add(selectOptionView);
}
}
/**
* This generates the Bootstrap String for the YesNoAll Options.
*/
private void createAutocompleteViewListForYesNoOptionsMap() {
yesNoList = new ArrayList<SelectOptionView>();
for (String[] yesNoOption : YESNODESCRIPTIONS) {
SelectOptionView
selectOptionView = new SelectOptionView();
selectOptionView.setLabel(getText(yesNoOption[1]));
selectOptionView.setId(yesNoOption[0]);
yesNoList.add(selectOptionView);
}
}
/**
* Load the Yes/No/All optionset map
*/
public void loadYesNoAllOptionsMap() {
createAutocompleteViewListForYesNoAllOptionsMap();
createAutocompleteViewListForYesNoOptionsMap();
}
public List<SelectOptionView> getYesNoAllList() {
return yesNoAllList;
}
public List<SelectOptionView> getYesNoList() {
return yesNoList;
}
}
Kind regards,
Nate Kerkhofs