2013-05-06 102 views
0

我的JSF應用程序後面的數據訪問層對日期字段使用兩種不同的格式(有時是ddmmyyyy,有時是yyyymmdd);顯示的日期始終是dd/mm/yyyy。動態JSF轉換器

有沒有辦法在一個字段中使用兩個不同的轉換器並決定動態使用哪一個?就像「如果這個命令按鈕被點擊,使用這個轉換器,否則,如果這個其他命令按鈕被點擊,使用該轉換器」。

+0

你問題需要進一步澄清。如果日期**總是以* 1 *格式顯示,那麼只有*一個轉換器*。轉換器將從該字符串中產生Date對象。接下來,在您的託管bean中,您將擁有日期集,然後*在操作方法中,您將決定以何種格式將數據傳遞給DAO,具體取決於所調用的操作方法。如果我對你的設置的理解與你的不一致,你可以相應地更新答案。 – skuntsel 2013-05-06 19:52:56

回答

0

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); 
    } 

} 
+0

我編輯我的問題更清晰:顯示的日期都具有相同的格式(日/月/年)。使用這種方法,我可以使用getAsString方法和兩個正則表達式來選擇如何顯示我的日期,但getAsObject方法不會「知道」我的數據層預期使用哪種格式。 – Virginie 2013-05-06 11:52:45

+0

請在將其作爲答案發布之前對其進行測試。考慮到SDF的[lenientness](http://stackoverflow.com/questions/13057464/validating-a-date-using-dateformat)以及例如'12121212'在兩種格式中都有效。正如OP明確要求的那樣,最好讓它真正依賴於行動。 – BalusC 2013-05-06 12:16:22

3

BalusC解釋了爲什麼這是很難在這裏:https://stackoverflow.com/a/7123153/3284943

根據他的建議,我創造了這個:

在JSF文件

,我用我的自定義轉換器及其定義的屬性,在運行時選擇轉換器和動態屬性。這是一個動態的PrimeFaces DataTable中的一個片段:

<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."); 
     } 
    } 
}