2011-01-18 3 views
5

Estoy usando Spring CustomNumberEditor editor para enlazar mis valores de flotación y he experimentado que si en el valor no hay un número, a veces puede analizar el valor y no se devuelve ningún error.Spring CustomNumberEditor analiza números que no son números

  • número = 10 ...... entonces el número es 10 y no hay errores
  • número = 10a ...... entonces el número es 10 y no hay errores número
  • = 10a25 ...... entonces el número es 10 y no hay errores
  • Number = ...... un error porque el número no es válido

lo que parece que el editor analiza el valor hasta que pueda y omita el resto. ¿Hay alguna forma de configurar este editor para que la validación sea estricta (para que los números como 10a o 10a25 resulten en errores) o tengo que construir mi implementación personalizada? Estoy buscando algo así como establecer indulgente en falso en CustomDateEditor/DateFormat para que las fechas no se puedan analizar al más probable.

La forma en que el editor de registro es:

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

Gracias.

Respuesta

4

Dado que se basa en la clase NumberFormat, que detiene el análisis de la cadena de entrada en el primer carácter no válido, creo que tendrá que ampliar la clase NumberFormat.

primera vista sería

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

Gracias. Pero si tengo que hacer mi implementación personalizada, creo que puedo extender la clase CustomNumberEditor y anular el método setAsText comprobando si el valor es un número como lo hace y si está funcionando con super.setAsText – Javi

7

No se puede hacer esto un poco con NumberFormat.

La documentación es clara acerca de este hecho:

/** 
* 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 { 

Cuando acceept esta API aún sería aún válido para escribir un analizador que hace lo que quiere e implementar la interfaz NumberFormat. Esto significa que debes implementar tu propio Editor de propiedades.

/* 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

creo que el enfoque más elegante sería utilizar NumberFormat.parse(String,ParsePosition), algo como esto:

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

    ... 
} 
Cuestiones relacionadas