简体   繁体   中英

Why do I get an error using this enum as option items in JSTL

The enum is defined as:

public enum Country {
    US("United States"),
    CA("Canada"),
    AUS("Australia");

    private String fullName;

    private Country(String fullName) {
        this.fullName = fullName;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
}

The Model is:

public class Workspace implements Serializable {
    // ...
    @Valid
    @NotNull
    private Address address;
    //...
}

public class Address implements Serializable {
    // ...
    private Country country;
    //...
}

I have a view object as such:

public class WorkspaceVO implements Serializable {
    //..
    private Workspace workspace;
    //...
}

And finally in my jsp I'm trying to do:

<form:select id="country"  path="workspace.address.country">
  <form:options items="${workspace.address.country}" itemLabel="fullName"/>
</form:select>

I have this exact situation duplicated in other spots in my code and its working fine. I don't see any difference, however, I'm getting an error when I visit the jsp...

javax.servlet.jsp.JspException: Type [com.mycompany.web.Country] is not valid for option items

Any ideas why?

It is a simple mistake: form:options items is the value for the list that contains all the options!

So in the controller, add a variable to your modelmap

modelMap.add("aviableCountries", Country.values);

and then use it in the jsp:

<form:select id="country"  path="workspace.address.country">
   <form:options items="${aviableCountries}" itemLabel="fullName"/>
</form:select>

Edit : an other solution is the remove the items attribute completely

<form:select id="country"  path="workspace.address.country">
   <form:options itemLabel="fullName"/>
</form:select>

then you do not need to add the enum values in the controller. This works because of an not well known feature of spring-form:options -Tag. In the tld for the items value, you can read:

... This attribute (items) is required unless the containing select's property for data binding is an Enum, in which case the enum's values are used.

In the code of org.springframework.web.servlet.tags.form.OptionsTag you will find this if-statement:

if (items != null) {
    itemsObject = ...;
} else {
     Class<?> selectTagBoundType = ((SelectTag) findAncestorWithClass(this, SelectTag.class))
            .getBindStatus().getValueType();
      if (selectTagBoundType != null && selectTagBoundType.isEnum()) {
            itemsObject = selectTagBoundType.getEnumConstants();
      }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM