Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

java - JSF 2 - f:selectItems with a Date keyed Map

The below selectItems is fed from a Session Scoped Map. When the user clicks the Submit button, it is supposed to set a date field in the Request Scoped backing bean and display it on the page.

    <h:selectOneMenu value="#{dropDown.selectedDate}">
        <f:selectItems value="#{mapValues.dateMap.entrySet()}" var="entry" itemLabel="#{entry.value}" itemValue="#{entry.key}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" />
You selected Date #{dropDown.selectedDate}

However, the following conversion error is received:

Conversion Error setting value 'Wed Dec 26 15:09:32 EST 2012' for 'null Converter'. 

I'm not sure why this error is received. I attempted setting a javax.faces.DateTime converter on the selectOneMenu tag, but then received an even more cryptic validation error.

Found a post that suggests checking if the equal() method is available, and that the item select is in the dropdown, both of which should be true in this case.

One workaround I can think of is to change my map to be String keyed where dates are saved off as strings. But it seems like an overkill.

Any suggestions on how to get this set up to work?

Backing bean:

@Named
@RequestScoped
public class DropDown {

    private Date selectedDate;

    public Date getSelectedDate() {
        return selectedDate;
    }

    public void setSelectedDate(Date selectedDate) {
        this.selectedDate = selectedDate;
    }

}

Map bean:

@Named
@SessionScoped
public class MapValues implements Serializable {

    private Map<Date, String> dateMap;

    @PostConstruct
    public void init() {        
        dateMap = new LinkedHashMap<Date, String>();
        dateMap.put(new Date(), "DATEVALUE1");      
    }

    public Map<Date, String> getDateMap() {
        return dateMap;
    }

    public void setDateMap(Map<Date, String> dateMap) {
        this.dateMap = dateMap;
    }
}

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Using the date time converter should have been the right solution. Your "more cryptic validation error" turns out to be just this:

It was "form:location: Validation Error: Value is not valid

This will occur when the Object#equals() test of the selected item has not returned true for any of the available items. So, the selected Date did not match any of the available Date instances.

And indeed, the converter="javax.faces.DateTime" (aka <f:convertDateTime />) ignores by default the time part. It prints by default the "short" date style like "Dec 27, 2012" Rightclick page in browser, choose View Source to see it yourself.

<option value="Dec 27, 2012">DATEVALUE1</option>

When JSF converts the string submitted value in that format back to a concrete Date instance, it becomes basically 2012-12-27 00:00:00.000 while the dates provided in your map have apparently the time part still set, causing the equals() to always fail unless the map of available dates is by coincidence generated at exactly 00:00:00.000 midnight.

There are 2 solutions for this problem:

  1. Remove the time part of the dates in your mapping. You can use java.util.Calendar for this (or better, Joda Time).

  2. Use <f:convertDateTime pattern="yyyyMMddHHmmssSSS"/> instead to convert the entire date/time up to with the last milli second.

    <h:selectOneMenu value="#{dropDown.selectedDate}">
        <f:selectItems value="#{mapValues.dateMap.entrySet()}" var="entry" itemLabel="#{entry.value}" itemValue="#{entry.key}" />
        <f:convertDateTime pattern="yyyyMMddHHmmssSSS" />
    </h:selectOneMenu>
    

    This way the option value becomes

    <option value="20121227114627792">DATEVALUE1</option>
    

    Be careful with timezone issues when you've configured JSF to use platform specific timezone instead of GMT as <f:convertDateTime> timezone. You'd like to explicitly add timeZone="UTC" attribute to the converter then.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...