Spring Customnumbereditor Sanages Numbers, которые не являются числами
-
12-10-2019 - |
Вопрос
Я использую редактор Spring Customnumbereditor для привязки моих значений поплавки, и я экспериментировал, что если в значении не число, иногда он может проанализировать значение, и ошибка не возвращается.
- номер = 10 ...... тогда число составляет 10, и ошибки нет
- номер = 10а ...... тогда число составляет 10, и нет ошибок
- номер = 10A25 ...... тогда число составляет 10, и нет ошибок
- номер = a ...... ошибка, потому что число недопустимо
Таким образом, кажется, что редактор анализирует значение до тех пор, пока оно не сможет, и не опустит остальные. Есть ли способ настроить этот редактор, поэтому проверка строгая (поэтому цифры, такие как 10A или 10A25, приводят к ошибке), или мне приходится создать свою пользовательскую реализацию. Я смотрю что -то вроде настройки снисходительного к 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));
}
Спасибо.
Решение
Поскольку он опирается на класс 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
}
Другие советы
Вы не можете сделать это с номером.
Документация ясна об этом факте:
/**
* 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();
}
}
Я думаю, что самым элегантным подходом будет использование 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);
}
}
...
}