Domanda

Sto usando Spring MVC 3 e JSR 303. Ho un oggetto supporto modulo che ha i fagioli di diversi tipi in esso. A seconda del valore di un parametro richiesta, dovrò scegliere un chicco di convalidare e risparmiare. Non posso usare @Valid per la convalida in quanto il chicco di convalidare non si sa fino a quando il tempo di esecuzione.

sono stato in grado di iniettare una javax.validation.Validator al controllore, ma non sono sicuro di come convalidare un fagiolo con esso e memorizzare gli errori in un BindingResult/Error in modo "Primavera".

ho bisogno di farlo nel metodo del gestore, piuttosto che un metodo initBinder, a causa della richiesta di mappatura.

[modifica]

Il problema che sto avendo con validate(Object, Errors) è che non riconosce i fagioli nidificate. Chicco alla validate si accede attraverso foo.getBar (). GetBean (), dove il foo è l'oggetto di forma supporto. Quando faccio validate(foo.getBar().getBean(), errors), ricevo il seguente messaggio di errore.

JSR-303 validated property 'property-name' does not have a corresponding accessor for Spring data binding

Qualcuno ha fatto qualcosa di simile prima d'ora? Grazie.

È stato utile?

Soluzione

Solo una supposizione, ma avete provato

 errors.pushNestedPath("bar.bean"); // Path to the nested bean
 validate(foo.getBar().getBean(), errors)
 errors.popNestedPath();

Ecco come BindingResult è di solito utilizzato per la convalida dei fagioli nidificate.

Altri suggerimenti

Yup, la classe di magia che stai cercando è org.springframework.validation.beanvalidation.SpringValidatorAdapter

Questa classe ottiene un javax.validation.Validator iniettato in esso e contiene il codice per, come suggerisce il nome, 'adattare' la parte posteriore di uscita nell'oggetto Errors familiare. E 'ciò che viene utilizzato internamente per eseguire l'elaborazione quando si mette @Valid su un parametro del metodo.

È possibile ottenere direttamente con l'aggiunta di un LocalValidatorFactoryBean esplicito nel vostro servlet dispatcher. Basta Iniettare un'istanza di tale come un'istanza dell'interfaccia standard di primavera Validator e utilizzarlo come si farebbe con qualsiasi 'pre JSR 303-' fornitore di convalida primavera.

Il modo in cui l'ho visto fare è quello di utilizzare uno standard JSR-303 validatore (qualsiasi cosa tu stia già iniettando in) per ottenere le violazioni (cioè Set<ConstraintViolaion<T>>)

Quindi utilizzare codice simile a quello dentro LocalValidatorFactoryBean per la conversione tra quelle violazioni ed errori Primavera:

public static <T> void convert(Errors errors, Collection<ConstraintViolation<T>> violations) {
        for (ConstraintViolation<?> violation : violations) {
            String field = violation.getPropertyPath().toString();
            FieldError fieldError = errors.getFieldError(field);
            if (fieldError == null || !fieldError.isBindingFailure()) {
                errors.rejectValue(field, violation.getConstraintDescriptor().getAnnotation().annotationType()
                        .getSimpleName(), getArgumentsForConstraint(errors.getObjectName(), field, violation
                        .getConstraintDescriptor()), violation.getMessage());
            }
        }
    }

    private static Object[] getArgumentsForConstraint(String objectName, String field,
            ConstraintDescriptor<?> descriptor) {
        List<Object> arguments = new LinkedList<Object>();
        String[] codes = new String[] { objectName + Errors.NESTED_PATH_SEPARATOR + field, field };
        arguments.add(new DefaultMessageSourceResolvable(codes, field));
        arguments.addAll(descriptor.getAttributes().values());
        return arguments.toArray(new Object[arguments.size()]);
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top