2011-01-18 1 views
5

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

  • числа = 10 ...... того число равно 10, и нет никаких ошибок
  • числа = 10a ...... того число составляет 10, и нет никаких ошибок
  • числа = 10À25 ...... того число 10, и нет никаких ошибок
  • числа = а ...... ошибки, потому что номер не является действительным

Таким образом, кажется, что редактор анализирует значение пока он не сможет и не опустит остальных. Есть ли способ настроить этот редактор, чтобы проверка была строгой (поэтому числа, такие как 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)); 
} 

Спасибо.

ответ

4

Поскольку он полагается на класс 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 
} 
+0

Спасибо. Но если я выполнил свою собственную реализацию, я думаю, что я могу расширить класс CustomNumberEditor и переопределить метод setAsText, проверяя, является ли это число так же, как и вы, и если оно происходит с помощью super.setAsText – Javi

7

Вы не можете сделать это Whith 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 { 

При acceept этого 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(); 
    }  
} 
3

Я думаю, что самый элегантный подход будет использовать 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); 
     } 
    } 

    ... 
}