Не удается сохранить число с помощью f: convertNumber в карту

#jsf #jsf-2

#jsf #jsf-2

Вопрос:

У меня странная ситуация, когда f: convertNumber не работает при попытке сохранить его на нетипизированной карте.

Я ожидаю, что число будет сохранено как java.lang.Двойной объект на карте.


Вот выдержка из xhtml :

 <h:inputText value="#{tInputBean.generalMap['myNumber']}" id="testNumber">
    <f:convertNumber />
</h:inputText>
<p:message for="testNumber" />
  

И вот компонент :

 @Named("tInputBean")
@Scope("view")
public class TInputBean {
    private Log log = LogFactory.getLog(TInputBean.class);
    private Map generalMap = new HashMap();

    // .. and the setter getter
    ....
}
  

И вот мой журнал :

 DEBUG PhaseTracker - BEFORE PHASE RESTORE_VIEW 1
DEBUG PhaseTracker - AFTER PHASE RESTORE_VIEW 1
DEBUG PhaseTracker - BEFORE PHASE APPLY_REQUEST_VALUES 2
DEBUG DebugUtil - ============== start debugMap parameter map : ==============
DEBUG DebugUtil - testNumber='123123123'
DEBUG DebugUtil - javax.faces.partial.execute='SaveHeader testNumberPanel RPBPanel'
DEBUG DebugUtil - SaveHeader='SaveHeader'
DEBUG DebugUtil - javax.faces.partial.render='messages RPBPanel DebugVersionHeader testNumberPanel'
DEBUG DebugUtil - javax.faces.source='SaveHeader'
DEBUG DebugUtil - j_idt42='j_idt42'
DEBUG DebugUtil - javax.faces.ViewState='7088371747667351331:-3641627426454744246'
DEBUG DebugUtil - transNum='TRX003'
DEBUG DebugUtil - javax.faces.partial.ajax='true'
DEBUG DebugUtil - ============== end debugMap parameter map : ==============
DEBUG PhaseTracker - AFTER PHASE APPLY_REQUEST_VALUES 2
DEBUG PhaseTracker - BEFORE PHASE PROCESS_VALIDATIONS 3
DEBUG PhaseTracker - AFTER PHASE PROCESS_VALIDATIONS 3
DEBUG PhaseTracker - BEFORE PHASE RENDER_RESPONSE 6
DEBUG PhaseTracker - AFTER PHASE RENDER_RESPONSE 6
  

И после рендеринга <p:message for="testNumber" /> заменяется на : {0}: Conversion error occurred.


То, что я замечаю, это :

  1. При возникновении ошибки преобразования исключения не происходит. Мой обработчик исключений, который фиксирует и регистрирует все исключения, ничего не обрабатывает. Трассировка исключений отсутствует.
  2. Я не могу указать такой тип, как java.lang.Дважды в <f:convertNumber> теге.

Должен ли я создать свой собственный конвертер, чтобы это работало? Я уже представляю себе такие вещи, как :

 <h:inputText value="#{tInputBean.generalMap['myNumber']}" id="testNumber">
    <f:converter type="MyDoubleConverter" />
</h:inputText>
<p:message for="testNumber" />
  

Пожалуйста, поделитесь своим мнением по этому поводу.
Спасибо!


Обновить


Я создал простой конвертер, который соответствует моим потребностям, и до сих пор он работал нормально. Вот код, пожалуйста, поделитесь своим мнением по этому поводу :

 @FacesConverter(value="Double")
public class DoubleConverter implements Converter {
    private Log log = LogFactory.getLog(DoubleConverter.class);

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        //log.debug("locale : "   context.getViewRoot().getLocale());
        DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(context.getViewRoot().getLocale());
        //log.debug("VALUE == "   value);
        String result = value == null || value.toString().trim().length() == 0 ? null : format.format(value);
        //log.debug("RESULT == "   value);
        return resu<
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        //log.debug("locale : "   context.getViewRoot().getLocale());
        //log.debug("STRING VALUE == "   value);
        DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(context.getViewRoot().getLocale());
        try {
            Object result = ((value == null) || (value.trim().length() == 0)) ? null : format.parse(value).doubleValue();
            //log.debug("RESULT == "   result);
            return resu<
        } catch (Exception e) {
            log.error(e,e);
            throw new ConverterException(e);
        }
    }
}
  

И вот как мой jsf использует это :

 <h:inputText value="#{tInputBean.generalMap['myNumber']}" 
   id="testNumber" converter="Double"/>
<p:message for="testNumber" />
  

Комментарии:

1. @Cristian Boariu: Вау! Это работает, спасибо! Но теперь у меня есть другая проблема: при визуализации внутри inputText он будет иметь это 1.23123123E8 . Этого не произойдет с f: convertNumber, поскольку оно будет форматироваться в зависимости от локали (если я не ошибаюсь). Есть предложения по этому поводу?

Ответ №1:

Вы должны попробовать это:

 <f:converter converterId="javax.faces.Double"/>
  

Если вы хотите отформатировать, вы можете использовать конвертер для чисел:

 <f:convertNumber type="number" maxIntegerDigits="3"/>
  

Подробности о форматировании чисел вы можете найти здесь и здесь.

Комментарии:

1. Привет, спасибо за идею. Но я заметил, что тег f: converter не поддерживает атрибут pattern . Я попробовал вашу идею, но она по-прежнему показывает 12.23123123E8 . Перед этим я попробовал вложить f: attribute name=»pattern» value = «…..» внутри тега f: converter , надеясь, что это сработает, но также потерпел неудачу.

2. @Альберт Кам — Вы правы, атрибут pattern существует только для f:convertNumber . Можете ли вы попробовать с моим обновленным ответом?

3. Здравствуйте, я также обновил свой тест, используя только f: convert, или только f: convertNumber, или даже обе комбинации, вложенные внутри этого входного текста. Работал только f: convert, но без форматирования. Остальные завершились ошибкой преобразования. В настоящее время я также тестирую свой собственный конвертер.

Ответ №2:

Наконец, я создал свой собственный простой конвертер для этой цели, и код был опубликован внизу исходного сообщения.

Спасибо!