Domanda

Sto usando l'editor primavera CustomNumberEditor per legare i miei valori float e ho sperimentato che se il valore non è un numero a volte può analizzare il valore e viene restituito alcun errore.

  • Numero = 10 ...... allora il numero è 10 e non c'è nessun errore
  • Numero = 10 bis ...... allora il numero è 10 e non c'è nessun errore
  • Numero = 10a25 ...... allora il numero è 10 e non c'è nessun errore
  • Numero = un errore di ...... perché il numero non è valido

Così sembra che l'editor analizza il valore fino a quando si può e omettere il resto. C'è un modo per configurare questo editor in modo che la convalida è rigorosa (così come i numeri 10a o 10a25 risultato in errore) o devo costruire la mia implementazione personalizzata. Sto cercando qualcosa di simile impostazione indulgenti su false in CustomDateEditor / DateFormat modo date non può essere analizzato al massimo un probabile.

Il modo in cui mi registro l'editor è:

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

Grazie.

È stato utile?

Soluzione

Dal momento che si basa sulla classe NumberFormat, che ferma il parsing della stringa di input al primo carattere non valido penso che si dovrà estendere la classe NumberFormat.

prima vista sarebbe

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
}

Altri suggerimenti

Non si può fare questo whith NumberFormat.

La documentazione è chiaro su questo fatto:

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

Quando si acceept questa API sarebbe addirittura essere ancora valida per scrivere un parser che fa quello che si vuole e implementare l'interfaccia NumberFormat. Questo significa che devi implment il proprio editor di proprietà, invece.

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

Credo che l'approccio più elegante sarebbe quella di utilizzare NumberFormat.parse(String,ParsePosition), qualcosa di simile a questo:

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

    ...
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top