Comment obtenir le texte d'erreur dans controller à partir de BindingResult

j'ai un contrôleur qui renvoie JSON. Il prend une forme qui se valide par annotations de printemps. Je peux obtenir la liste de FieldError à partir de BindingResult, mais ils ne contiennent pas le texte qu'un JSP affichera dans la balise. Comment puis-je obtenir le texte d'erreur à renvoyer dans JSON?

@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
JSONResponse submit(@Valid AnswerForm answerForm, BindingResult result, Model model, HttpServletRequest request, HttpServletResponse response) {

    if (result.hasErrors()) {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        JSONResponse r = new JSONResponse();
        r.setStatus(JSONResponseStatus.ERROR);
        //HOW DO I GET ERROR MESSAGES OUT OF BindingResult??? 
    } else {
        JSONResponse r = new JSONResponse();
        r.setStatus(JSONResponseStatus.OK);
        return r;
    }

}

JSONREsponse classe est un simple POJO

public class JSONResponse implements Serializable {
    private JSONResponseStatus status;
    private String error;
    private Map<String,String> errors;
    private Map<String,Object> data;

...getters and setters...
}

Appel BindingResult.getAllErrors () retourne un tableau d'objets FieldError, mais il n'a pas les erreurs réelles.

21
demandé sur Mike 2010-05-02 01:28:35

5 réponses

Avertissement: je n'ai pas encore utiliser Spring-MVC 3.0

mais je pense que la même approche utilisée par le printemps 2.5 peut combler vos besoins

for (Object object : bindingResult.getAllErrors()) {
    if(object instanceof FieldError) {
        FieldError fieldError = (FieldError) object;

        System.out.println(fieldError.getCode());
    }

    if(object instanceof ObjectError) {
        ObjectError objectError = (ObjectError) object;

        System.out.println(objectError.getCode());
    }
}

j'espère que cela peut être utile pour vous

UPDATE

si vous voulez obtenir le message fourni par votre faisceau de ressources, vous avez besoin d'une instance de messageSource enregistrée (It être appelé messageSource)

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames" value="ValidationMessages"/>
</bean>

injectez votre instance MessageSource dans votre Vue

@Autowired
private MessageSource messageSource;

Et pour faire passer votre message, procédez comme suit

for (Object object : bindingResult.getAllErrors()) {
    if(object instanceof FieldError) {
        FieldError fieldError = (FieldError) object;

        /**
          * Use null as second parameter if you do not use i18n (internationalization)
          */

        String message = messageSource.getMessage(fieldError, null);
    }
}

votre validateur devrait ressembler à

/**
  * Use null as fourth parameter if you do not want a default message
  */
errors.rejectValue("<FIELD_NAME_GOES_HERE>", "answerform.questionId.invalid", new Object [] {"123"}, null);
31
répondu Arthur Ronald 2010-05-03 20:08:46

j'ai rencontré ce problème récemment, et j'ai trouvé un moyen plus facile (peut-être que c'est le soutien du printemps 3)

    List<FieldError> errors = bindingResult.getFieldErrors();
    for (FieldError error : errors ) {
        System.out.println (error.getObjectName() + " - " + error.getDefaultMessage());
    }

Il n'y a pas besoin de changer/ajouter la source du message.

21
répondu Hoàng Long 2017-10-06 03:25:11

Avec Java 8 Streams

bindingResult
.getFieldErrors()
.stream()
.forEach(f -> System.out.println(f.getField() + ": " + f.getDefaultMessage()));
6
répondu Krzysiek 2017-10-23 18:20:32

BEAN XML:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>messages</value>
        </list>            
    </property>
</bean>

<bean id="messageAccessor" class="org.springframework.context.support.MessageSourceAccessor">
    <constructor-arg index="0" ref="messageSource"/>
</bean> 

JAVA:

for (FieldError error : errors.getFieldErrors()) {
    logger.debug(messageAccessor.getMessage(error));
}

NOTE: Erreurs D'Appel.getDefaultMessage () ne renverra pas nécessairement le même message généré à partir du code + args. Le defaultMessage est une valeur séparée définie lors de l'appel des erreurs.rejectValue() la méthode. Voir Erreurs.API rejettvalue () ici

1
répondu splashout 2013-12-12 17:51:03

WebMvcConfigurerAdapter:

@Bean(name = "messageSourceAccessor")
public org.springframework.context.support.MessageSourceAccessor messageSourceAccessor() {
    return new MessageSourceAccessor( messageSource());
}

Contrôleur:

@Autowired
@Qualifier("messageSourceAccessor")
private MessageSourceAccessor           messageSourceAccessor;
...

StringBuilder sb = new StringBuilder();
for (ObjectError error : result.getAllErrors()) {
    if ( error instanceof FieldError) {
        FieldError fe = (FieldError) error;
        sb.append( fe.getField());
        sb.append( ": ");
    }
    sb.append( messageSourceAccessor.getMessage( error));
    sb.append( "<br />");
}
1
répondu Valerii Starovoitov 2017-11-24 01:58:54