簡體   English   中英

如何為空輸入組件dispite設置自定義非null值INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = true

[英]How to have a custom non null value for empty input component dispite INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = true

在我的faces-config.xml我設置了

<context-param>
 <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
 <param-value>true</param-value>
</context-param>

因此,沒有輸入的任意輸入組件將null放入綁定到value="#{myBean.someDate}"屬性的bean屬性中,並在從該bean屬性獲取null時呈現空組件。

雖然這通常是應用程序的通緝行為,但我有一個特定的組件,我想用自定義的non null值替換null

是否有一般的好方法來實現這一目標?

我用Mojarra 2.3.8為Primefaces(6.2)日歷嘗試了這個:

<h:form id="myForm">
        <p:calendar value="#{myBean.someDate}" pattern="MM/dd/yyyy"
            converter="mySpecialDateConverter" locale="en" />
        <p:commandButton value="send" process="@form" update="@form" />
        <hr />
        <h:outputText value="#{myBean.someDate}" />
</h:form>

我嘗試使用轉換器,當從#{myBean.someDate}收到我的自定義值時,渲染組件時返回getAsString()empty String ,或者當提交null或純null時,在getAsObject()吐出我的自定義值:

import java.util.Date;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.DateTimeConverter;
import javax.faces.convert.FacesConverter;

@FacesConverter("mySpecialDateConverter")
public class MyConverter extends DateTimeConverter {

    private static final Date PAST = new Date(0);

    public MyConverter() {
        setPattern("MM/dd/yyyy");
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (PAST.equals(value)) {
            return "";
        }
        return super.getAsString(context, component, value);
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (null == value || "".equals(value.trim())) {
            return PAST;
        }
        return super.getAsObject(context, component, value);
    }

}

當bean屬性等於PAST時,渲染空日歷組件按預期工作。 但是,在沒有輸入的情況下提交CalendarRenderer會將屬性設置為null因為Primefaces CalendarRenderer在空值提交時不會查詢Converter

package org.primefaces.component.calendar;

public class CalendarRenderer extends InputRenderer {
    // ...
    public Object getConvertedValue(FacesContext context, UIComponent component, Object value) throws ConverterException {
        Calendar calendar = (Calendar) component;
        String submittedValue = (String) value;
        SimpleDateFormat format = null;

        if (isValueBlank(submittedValue)) {
            return null;
        }

        //Delegate to user supplied converter if defined
        try {
            Converter converter = calendar.getConverter();
            if (converter != null) {
                return converter.getAsObject(context, calendar, submittedValue);
            }
        }
        // ...
    }
    // ...
}

這部分可以,因為Converter.getAsObject()上的JavaDoc說:

/** 
 * @return <code>null</code> if the value to convert is <code>null</code>, 
 * otherwise the result of the conversion 
 */

這樣,Primefaces沒有理由在空輸入上解析轉換器。 如果我們設置javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = false將是不同的imho。 然后我會考慮上面的行為不正確,因為""不是null

為了完整性,這是我的bean又名myBean

import java.io.Serializable;
import java.util.Date;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class MyBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Date someDate;

    public Date getSomeDate() {
        return someDate;
    }

    public void setSomeDate(Date someDate) {
        this.someDate = someDate;
    }

}

我不想在實際應用程序中對該bean進行更改,Calendars的值綁定到持久化的實體屬性值。 我也不希望持久層完成這項工作。

背景是:

我想在某些數據庫DATE字段中阻止null值。 例如,在期間的情況下,我希望開始默認為某個遠離過去的日期與應用程序上下文無關,在該期間結束時,我希望遠期的日期與應用程序上下文無關,並且兩者都不會打擾用戶哪個日期它們是默認的。 這些默認日期有助於過濾當前Date在該時間段內或之后的實體,而用戶的任何輸入都不會被假定for ever的時間段。

JSF組件不會在null值或它們認為為null的任何內容上調用轉換器 - 對於JSF中的默認組件也是如此。 所以在這方面我認為PrimeFaces表現得像預期的那樣,這是正確的結果。 以下是兩種繞過這種情況的方法,可以立即浮現在腦海中;

使用OmniFaces

JSF轉換器中的null值所述 ,OmniFaces o:param將調用您的轉換器而不管null值 - 您可以使用它將參數傳遞給組件。 在你的具體情況下,你應該能夠做類似的事情;

<h:form id="myForm">
        <p:calendar value="#{myBean.someDate}" pattern="MM/dd/yyyy" locale="en" />
        <p:commandButton value="send" process="@form" update="@form">
            <o:param name="date" value="#{myBean.someDateConversion}"
                     converter="mySpecialDateConverter" /> 
        </p:commandButton>
        <hr />
        <h:outputText value="#{myBean.someDate}" />
</h:form>

使用自定義渲染器

第二個選項是使用自定義渲染器,只需修改組件的行為以始終調用轉換器,如本答案中所述 - JSF自定義轉換器未調用null值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM