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

Reply via email to