我的 JSF 应用程序背后的数据访问层使用两种不同的日期字段格式(有时是 ddmmyyyy,有时是 yyyymmdd);显示的日期始终为 dd/mm/yyyy。
有没有办法为单个字段使用两个不同的转换器并决定动态使用哪个?就像“如果单击此命令按钮,请使用此转换器,否则如果单击此其他命令按钮,请使用该转换器”。
BalusC 在这里解释了为什么这很困难:https ://stackoverflow.com/a/7123153/3284943
根据他的建议,我创建了这个:
在 JSF 文件中,我使用我的自定义转换器及其定义的属性,在运行时选择转换器和动态属性。这是来自动态 PrimeFaces 数据表的片段:
<h:outputText rendered = "#{column.dateTime}" value="#{table[column.name]}">
<f:converter converterId="runtimeConverterSelector" />
<f:attribute name="converterId" value="#{column.converterName}" />
<f:attribute name="pattern" value="#{column.converterPattern}" />
</h:outputText>
自定义转换器:
@FacesConverter ("runtimeConverterSelector")
public class RuntimeConverterSelector implements Converter {
Converter delegateConverter;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
retrieveAttributes(component);
return delegateConverter.getAsObject(context, component, value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
retrieveAttributes(component);
return delegateConverter.getAsString(context, component, value);
}
private void retrieveAttributes(UIComponent component) {
Object attribute;
attribute = component.getAttributes().get("converterId");
if (attribute != null) {
String converterName = (String)attribute;
switch (converterName) {
case "javax.faces.BigDecimal":
delegateConverter = new BigDecimalConverter();
break;
case "javax.faces.BigInteger":
delegateConverter = new BigIntegerConverter();
break;
case "javax.faces.Boolean":
delegateConverter = new BooleanConverter();
break;
case "javax.faces.Byte":
delegateConverter = new ByteConverter();
break;
case "javax.faces.Character":
delegateConverter = new CharacterConverter();
break;
case "javax.faces.DateTimeConverter":
delegateConverter = new DateTimeConverter();
attribute = component.getAttributes().get("pattern");
if (attribute != null) ((DateTimeConverter)delegateConverter).setPattern((String)attribute);
attribute = component.getAttributes().get("timeZone");
if (attribute != null) ((DateTimeConverter)delegateConverter).setTimeZone(TimeZone.getTimeZone((String)attribute));
attribute = component.getAttributes().get("dateStyle");
if (attribute != null) ((DateTimeConverter)delegateConverter).setDateStyle((String)attribute);
attribute = component.getAttributes().get("timeStyle");
if (attribute != null) ((DateTimeConverter)delegateConverter).setDateStyle((String)attribute);
attribute = component.getAttributes().get("type");
if (attribute != null) ((DateTimeConverter)delegateConverter).setDateStyle((String)attribute);
break;
case "javax.faces.Double":
delegateConverter = new DoubleConverter();
break;
case "javax.faces.Enum":
delegateConverter = new EnumConverter();
break;
case "javax.faces.Float":
delegateConverter = new FloatConverter();
break;
case "javax.faces.Integer":
delegateConverter = new IntegerConverter();
break;
case "javax.faces.Long":
delegateConverter = new LongConverter();
break;
case "javax.faces.Number":
delegateConverter = new NumberConverter();
attribute = component.getAttributes().get("currencyCode");
if (attribute != null) ((NumberConverter)delegateConverter).setCurrencyCode((String)attribute);
attribute = component.getAttributes().get("currencySymbol");
if (attribute != null) ((NumberConverter)delegateConverter).setCurrencySymbol((String)attribute);
attribute = component.getAttributes().get("groupingUsed");
if (attribute != null) ((NumberConverter)delegateConverter).setGroupingUsed(Boolean.parseBoolean((String)attribute));
attribute = component.getAttributes().get("integerOnly");
if (attribute != null) ((NumberConverter)delegateConverter).setIntegerOnly(Boolean.parseBoolean((String)attribute));
attribute = component.getAttributes().get("locale");
if (attribute != null) ((NumberConverter)delegateConverter).setLocale(new Locale((String)attribute));
attribute = component.getAttributes().get("maxFractionDigits");
if (attribute != null) ((NumberConverter)delegateConverter).setMaxFractionDigits(Integer.parseInt((String)attribute));
attribute = component.getAttributes().get("maxIntegerDigits");
if (attribute != null) ((NumberConverter)delegateConverter).setMaxIntegerDigits(Integer.parseInt((String)attribute));
attribute = component.getAttributes().get("minFractionDigits");
if (attribute != null) ((NumberConverter)delegateConverter).setMinFractionDigits(Integer.parseInt((String)attribute));
attribute = component.getAttributes().get("minIntegerDigits");
if (attribute != null) ((NumberConverter)delegateConverter).setMinIntegerDigits(Integer.parseInt((String)attribute));
attribute = component.getAttributes().get("pattern");
if (attribute != null) ((NumberConverter)delegateConverter).setPattern((String)attribute);
attribute = component.getAttributes().get("type");
if (attribute != null) ((NumberConverter)delegateConverter).setType((String)attribute);
break;
case "javax.faces.Short":
delegateConverter = new ShortConverter();
break;
default:
System.err.println("ConverterId provided to runtimeConverterSelector, '" + converterName + "' is invalid. The default converter will be used");
break;
}
} else {
System.err.println("No converterId was provided to runtimeConverterSelector. The default converter will be used.");
}
}
}
AFAIK 这是不可能的。但是您可以在一个转换器中检查这两种格式。当然,转换为字符串将基于一种格式完成。或者,您可以根据当前的Locale
. 基本示例:
@FacesConverter("doubleDateConverter")
public class DateConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value == null || value.equals("")) {
return null;
}
SimpleDateFormat format1 = new SimpleDateFormat("ddMMyyyy");
SimpleDateFormat format2 = new SimpleDateFormat("yyyyMMdd");
Date date = null;
boolean valid = true;
try {
date = format1.parse(value);
} catch (ParseException e) {
valid = false;
}
if(!valid) {
try {
date = format2.parse(value);
} catch (ParseException e) {
valid = false;
}
}
if((!valid) || (date == null)) {
throw new ConverterException(new FacesMessage("Date is in wrong format: " + value));
}
return date;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (!(value instanceof Date) || (value == null)) {
return null;
}
SimpleDateFormat format = new SimpleDateFormat("ddMMyyyy");
return format.format((Date)value);
}
}