Pregunta

Estoy usando el editor de Primavera CustomNumberEditor para unir mis valores flotantes y he experimentado que si en el valor no es un número a veces puede analizar el valor y se devuelve ningún error.

  • 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
  • número = un error ...... porque el número no es válido

Así que parece que el editor analiza el valor hasta que se pueda y omitir el resto. ¿Hay alguna manera de configurar este editor por lo que la validación es estricta (así como los números 10a o 10a25 resultado por error) o tengo que construir mi implementación personalizada. Busco algo así como el establecimiento de indulgente en false en CustomDateEditor / DateFormat lo que las fechas no pueden ser analizados a lo más un 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.

¿Fue útil?

Solución

Desde que se basa en la clase NumberFormat, que para analizar la cadena de entrada en el primer carácter no válido creo que tendrá que extender la clase NumberFormat.

En primer rubor 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
}

Otros consejos

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 sería incluso aunque no válido para escribir un analizador que hace lo que quiere e implementar la interfaz NumberFormat. Esto significa que tenga que implment su propio editor de propiedades en su lugar.

/* 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();
    }    
}

Creo que el enfoque más elegante sería el uso de 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);
        }
    }

    ...
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top