在我的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
时呈现一个空组件。
虽然这通常是应用程序所需的行为,但是我有一个特定的组件,希望将null
替换为自定义的non 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>
我使用转换器进行了尝试,当从empty String
接收到我的自定义值时,渲染组件时在getAsString()
中返回了#{myBean.someDate}
,或者在{{1 }}提交getAsObject()
或纯空白时:
null
当bean属性等于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);
}
}
时,呈现一个空的日历组件可以正常工作。但是在没有输入的情况下提交压延机会将属性设置为PAST
,因为Primefaces null
根本不会参考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);
}
}
// ...
}
// ...
}
上的JavaDoc所述:
Converter.getAsObject()
Primefaces没有理由在空输入时解析转换器。如果我们设置/**
* @return <code>null</code> if the value to convert is <code>null</code>,
* otherwise the result of the conversion
*/
,恕我直言。然后,我认为上述行为不正确,因为javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = false
不是""
。
为了完整起见,这就是我的豆null
:
myBean
我不想更改该bean,因为在实际应用程序中,Calendars的值绑定到持久化的实体属性值。我也不希望持久层完成这项工作。
背景情况:
我想防止某些数据库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;
}
}
字段中的null
值。例如,在句点的情况下,我希望开始默认设置为与应用程序上下文无关的某个较远的过去日期,对于该时段的结束,我希望在将来的某个日期与应用程序上下文无关的一个日期,并且两者都不影响用户使用哪个日期它们是默认设置。这些默认日期有助于过滤当前DATE
所在时段或超出该时段的实体,而用户的输入实际上都不是时段Date
。
答案 0 :(得分:2)
JSF组件不会以空值或它们认为为空的任何值调用转换器-JSF中的默认组件也是如此。因此,在这方面,我认为PrimeFaces的行为符合预期,这是正确的结果。这是两种立即想到的规避此问题的方法;
如JSF converter with null value中所述,OmniFaces o:param
将调用转换器,而不管其是否为空值-您可以使用它将参数传递给组件。在您的特定情况下,您应该可以执行类似的操作;
<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 Custom Converter not called on null value中所述。