Rich:Calendar backed by String throws Exception

2019-08-23 04:02发布

I have the following RichFaces (3.3.3) :

    <rich:calendar id="richCal1"                                    
        value="#{user.CreateDate}"
        popup="true" mode="client"
        inputSize="20"
        datePattern="dd/M/yyyy HH:mm"
        enableManualInput="true"
        buttonIcon="/images/calendar.gif">
        <f:convertDateTime type="date" pattern="dd/MM/yyyy HH:mm" />
        <a4j:support bypassUpdates="true" event="oninputblur"  ajaxSingle="true" />
        <a4j:support bypassUpdates="true" event="onchanged" ajaxSingle="true" />
    </rich:calendar>

The backbean Variable Type is String as the the column where the Calendar appears is calculated dynamically based on user profile and can be one of many type of controls (Label,Input,SelectItem,Rich Calendar)....

The calendar works the first time the page loads and the correct value for RichCal1 is retrived and shown (in this case 05/03/2012 12:00:00).

Problem occurs when the page needs to update (excuse the technically incorrect expression, i'll try and explain):

There is control on the page, where user can click and customize their current profile (additional rows or remove rows...etc). Once updated to reflect the change page needs to update which is where i see the following exception:

    ERROR: org.ajax4jsf.webapp.BaseXMLFilter - Exception in the filter chain
    javax.servlet.ServletException: myForm:0:richCal1: 'Mon Mar 05 
    12:00:00 EST 2012' could not be understood as a date.

I don't understand how the Date went from appearing as 05/03/2012 12:00:00 to 'Mon Mar 05 12:00:00 EST 2012 which is causing the issue.

Can someone please enlighten me.

Update:

Further debugging i discovered that when user updates/create a profile in another window, upon completion the process Refreshes the parent window. I set breakpoints on the setter/Getter of the Rich:Calendar value and i can see that first Getter is called and it has the correctly formatted date value, then the Setter is called which is set to Mon Mar 05 12:00:00 EST 2012 after which the exception is thrown! Anyone knows why this is happening?

标签: jsf richfaces
1条回答
走好不送
2楼-- · 2019-08-23 04:44

I resolved the above issue by writing a Converter as below:

    public class CalDateStrConveter implements Converter {
        private String pattern = ApplicationConstant.DD_MM_YYYYHHMM;
                    //eg 02/02/2012 12:00  (note Rich:calendar has no support for seconds)

        public Object getAsObject(FacesContext context, UIComponent component, String value)
                throws ConverterException {

            String result = "";
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            if(value!= null && value.length() > 0) {
                try {
                    Date date = sdf.parse(value);
                    result = sdf.format(date);
                } catch (Exception e) {
                    Date date = new Date();
                    logger.error(e.getMessage());
                    FacesMessage facesMessage = new FacesMessage("Invalid Date", value + " is an invalid date. Example " + sdf.format(date));
                    FacesContext.getCurrentInstance().addMessage("DATE PARSE ERROR", facesMessage);
                }
            }

            return result;
        }

        public String getAsString(FacesContext context, UIComponent component, Object value)
                throws ConverterException {

            String result = "";
            String valueStr = (String) value;
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            if (valueStr!= null && valueStr.length() > 0) {
                try {
                    Date date = sdf.parse(valueStr);
                    result = sdf.format(date);
                } catch (Exception e) {
                    logger.error(e.getMessage());
                    Date date = new Date();
                    FacesMessage facesMessage = new FacesMessage("Invalid Date", value + " is an invalid date. Example " + sdf.format(date));
                    FacesContext.getCurrentInstance().addMessage("DATE PARSE ERROR", facesMessage);
                }
            }
            return result;
        }

    }

Register it in faces-config.xml:

     <converter>
        <converter-id>CalDateStrConveter </converter-id>
        <converter-class>com.util.userProd.CalDateStrConveter</converter-class>
     </converter>

and modified the rich:calendar to:

    <rich:calendar id="richCal1"                                    
            value="#{user.CreateDate}"
            popup="true" mode="client"
            inputSize="20"
            datePattern="dd/M/yyyy HH:mm"
            enableManualInput="true"
            buttonIcon="/images/calendar.gif">
            <f:converter converterId="CalDateStrConveter "/>
            <a4j:support bypassUpdates="true" event="oninputblur"  ajaxSingle="true" />
            <a4j:support bypassUpdates="true" event="onchanged" ajaxSingle="true" />
    </rich:calendar>

Hope that helps someone in similar position. Cheers

查看更多
登录 后发表回答