3

I have the following sources:

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.custom.i18n.resources" value="ApplicationResources" />

    <package name="vislabWebShop" extends="struts-default">

        <action name="UserForward">
            <result>/pages/Login.jsp</result>
        </action>

        <action name="UserLogin" class="vislabWebShop.controller.LoginAction">
            <result name="success">/pages/Welcome.jsp</result>
            <result name="input">/pages/Login.jsp</result>
        </action>

        <action name="UserRegister" class="vislabWebShop.controller.RegisterAction">
            <result name="success">/pages/RegisterSuccess.jsp</result>
            <result name="input">/pages/Register.jsp</result>
        </action>

        <action name="UserRegisterNew">
            <result>/pages/Register.jsp</result>
        </action>

        <action name="UserRegisterSuccess">
            <result>/pages/Login.jsp</result>
        </action>

        <action name="ProductSearchForward">
            <result>/pages/SearchProduct.jsp</result>
        </action>

        <action name="ProductSearch" class="vislabWebShop.controller.ProductSearchAction">
            <result name="success">/pages/Login.jsp</result>
        </action>
    </package>
</struts>

ProductSearchAction.java:

package vislabWebShop.controller;

import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class ProductSearchAction extends ActionSupport
{
  private List<String> categories;
  private String chosenCategory;

  public ProductSearchAction()
  {
    categories = new ArrayList<String>();
    categories.add("Eins");
    categories.add("Zwei");
    categories.add("Drei");
  }

  @Override
  public String execute() throws Exception
  {
    return SUCCESS;
  }

  public List<String> getCategories()
  {
    return categories;
  }

  public void setCategories(List<String> categories)
  {
    this.categories = categories;
  }

  public String getChosenCategory()
  {
    return chosenCategory;
  }

  public void setChosenCategory(String chosenCategory)
  {
    this.chosenCategory = chosenCategory;
  }
}

SearchProduct.jsp:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@ taglib prefix="s" uri="/struts-tags"%>

    <html>
    <head>
    <title><s:text name="welcome.title" /></title>
    </head>

    <body bgcolor="white">

        <font color="red"> <s:actionmessage />
        </font>

    <p>
        <b><s:text name="product.search.title" /></b>
    </p>

    <s:form action="ProductSearch" focusElement="description">
        <s:textfield name="description" key="prompt.description" size="20" />
        <s:textfield name="minprice" key="prompt.price.min" size="20" />
        <s:textfield name="maxprice" key="prompt.price.max" size="20" />
        <s:select key="product.search.category" headerKey="-1" 
        headerValue="Bitte wählen Sie eine Kategorie"
            list="categories" />
        <s:submit value="Produkt suchen" align="right" />
    </s:form>

    <font color="red"> <s:actionerror label="label" />
    </font>


</body>
</html>

Now I have the problem, that I always get the following error if I come from Action ProductSearchForward to the JSP site SearchProduct.jsp:

org.apache.jasper.JasperException: tag 'select', field 'list', name 'product.search.category': The requested list key 'categories' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]

I just want the DropDownList to be populated from the given ArrayList<String> (List<String>), but it is not working. If I set the list content directly it works fine.

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
marc3l
  • 2,525
  • 7
  • 34
  • 62

1 Answers1

3
<s:select list = "categories" 
           key = "product.search.category" />

You are listing a List<String> and trying to access, through OGNL . (dot notation), fields that do not exist.

In OGNL

product.search.category 

is the equivalent of Java

getProduct().getSearch().getCategory()

Since you are listing Strings, just omit key attribute, because both your key and value will be the String itself.

It seems that you are confusing key with name too: key is the key of the <option> element, while name is the Action's attribute that will receive the chosen value through its Setter.

<s:select list = "categories" 
          name = "chosenCategory" />

EDIT: for a succesful living, implement Preparable Interface and load there your "static" data:

public class ProductSearchAction extends ActionSupport implements Preparable {
    private List<String> categories;
    private String chosenCategory;

    @override
    public void prepare() throws Exception {      
        categories = new ArrayList<String>();
        categories.add("Eins");
        categories.add("Zwei");
        categories.add("Drei");
    }

    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }

    /* GETTERS AND SETTERS */
}

And you must specify fully qualified class names for each tag in struts.xml...

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Okay I did it like you mentioned. But just the following error: tag 'select', field 'list', name 'chosenCategory': The requested list key 'categories' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location] Where to setup the List? – marc3l Dec 11 '13 at 15:24
  • If, with setup, you mean population, I suggest to implement `Preparable` Interface and loading "static" data in `prepare()` method. Avoid using Action's constructor... otherwise, populate it in `execute()` method, but it won't be available to page in case of INPUT result. Also remove the setter for the List. – Andrea Ligios Dec 11 '13 at 15:27
  • BTW the error message is misleading: just do as I said with the key and name attributes, and it will work. – Andrea Ligios Dec 11 '13 at 15:29
  • Yes. I did. But where to set the List??? In the constructor of ProductSearchAction class or how to implement the Preparable? Do I have to call the method and where? – marc3l Dec 11 '13 at 15:32
  • I get the error again and again and again...Is something wrong with my struts.xml? The Action calss ProductSearchAction is just called from the reference in the "ProductSearchForward" action in struts.xml, nowhere else. – marc3l Dec 11 '13 at 15:42
  • /pages/SearchProduct.jsp /pages/Login.jsp This is the action call tree. – marc3l Dec 11 '13 at 15:45
  • is not valid. where is the class attribute ? – Andrea Ligios Dec 11 '13 at 15:46
  • in ProductSearch action...I have a a href link to this ProductSearchForward.action and in there I result to the /pages/SearchProduct.jsp where the list is. – marc3l Dec 11 '13 at 15:47
  • 1
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42970/discussion-between-andrea-ligios-and-marcel-holl) – Andrea Ligios Dec 11 '13 at 15:48