Spring CustomNumberEditor анализирует числа, которые не являются числами - PullRequest
5 голосов
/ 18 января 2011

Я использую редактор Spring CustomNumberEditor для привязки моих значений с плавающей запятой, и я экспериментировал с тем, что если значение не является числом, иногда оно может анализировать значение, и ошибка не возвращается.число = 10 ...... тогда число равно 10 и ошибок нет

число = 10а ...... тогда число равно 10 и ошибок нет число =10a25 ...... тогда число равно 10 и ошибок нет number = a ...... ошибка, потому что номер недействителен

Так что кажетсячто редактор анализирует значение до тех пор, пока не сможет, а остальное пропустит.Есть ли способ настроить этот редактор таким образом, чтобы проверка была строгой (чтобы числа, такие как 10a или 10a25, приводили к ошибке), или мне нужно создать свою собственную реализацию.Я смотрю что-то вроде установки lenient в false в CustomDateEditor / DateFormat, чтобы даты не могли быть проанализированы для наиболее вероятного.

Способ регистрации редактора:

@InitBinder
public void initBinder(WebDataBinder binder){
    NumberFormat numberFormat = NumberFormat.getInstance();
    numberFormat.setGroupingUsed(false);
    binder.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, numberFormat, true));
}

Спасибо.

Ответы [ 3 ]

7 голосов
/ 18 января 2011

Вы не можете сделать это с помощью NumberFormat.

В документации ясно сказано об этом факте:

/**
 * Parses text from the beginning of the given string to produce a number.
 * The method may not use the entire text of the given string.
 * <p>
 * See the {@link #parse(String, ParsePosition)} method for more information
 * on number parsing.
 *
 * @param source A <code>String</code> whose beginning should be parsed.
 * @return A <code>Number</code> parsed from the string.
 * @exception ParseException if the beginning of the specified string
 *            cannot be parsed.
 */
public Number parse(String source) throws ParseException {

Когда вы принимаете этот API, было бы даже недопустимо написать парсер, которыйделает то, что вы хотите, и реализует интерфейс NumberFormat.Это означает, что вместо этого вы должны изменить свой собственный редактор свойств.

/* untested */
public class StrictNumberPropertyEditor extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
       super.setValue(Float.parseFloat(text));
    }

    @Override
    public String getAsText() {
        return ((Number)this.getValue()).toString();
    }    
}
4 голосов
/ 18 января 2011

Поскольку он опирается на класс NumberFormat, который останавливает синтаксический анализ входной строки по первому недопустимому символу, я думаю, что вам придется расширить класс NumberFormat.

Первое покраснение будет

public class StrictFloatNumberFormat extends NumberFormat {

  private void validate(in) throws ParseException{
     try {
       new Float(in);
     }
     catch (NumberFormatException nfe) {
       throw new ParseException(nfe.getMessage(), 0);     
  }


  public Number parse(String in) throws ParseException {
    validate(in);
    super.parse(in);
  }
  ..... //any other methods
}
3 голосов
/ 18 января 2011

Я думаю, что наиболее элегантный подход - использовать NumberFormat.parse(String,ParsePosition), что-то вроде этого:

public class MyNumberEditor extends PropertyEditorSupport {
    private NumberFormat f;
    public MyNumberEditor(NumberFormat f) {
        this.f = f;
    }

    public void setAsText(String s) throws IllegalArgumentException {
        String t = s.trim();
        try {
            ParsePosition pp = new ParsePosition(0);
            Number n = f.parse(t, pp);
            if (pp.getIndex() != t.length()) throw new IllegalArgumentException();
            setValue((Float) n.floatValue());
        } catch (ParseException ex) {
            throw new IllegalArgumentException(ex);
        }
    }

    ...
}
...