Как получить текст ошибки в контроллере от BindingResult - PullRequest
23 голосов
/ 02 мая 2010

У меня есть контроллер, который возвращает JSON. Он принимает форму, которая проверяет себя с помощью весенних аннотаций. Я могу получить список FieldError из BindingResult, но они не содержат текст, который JSP будет отображать в теге. Как я могу получить текст ошибки для отправки обратно в 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 класс это просто 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...
}

Вызов BindingResult.getAllErrors () возвращает массив объектов FieldError, но он не содержит фактических ошибок.

Ответы [ 5 ]

33 голосов
/ 02 мая 2010

Отказ от ответственности: я все еще не использую Spring-MVC 3.0

Но я думаю, что тот же подход, который использовался в Spring 2.5, может удовлетворить ваши потребности

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

Я надеюсь, что это может быть полезно для вас

UPDATE

Если вы хотите получить сообщение, предоставляемое вашим комплектом ресурсов, вам нужен зарегистрированный экземпляр messageSource (он должен называться messageSource)

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

Вставьте ваш экземпляр MessageSource в ваш View

@Autowired
private MessageSource messageSource;

И чтобы получить ваше сообщение, сделайте следующее

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

Ваш валидатор должен выглядеть так:

/**
  * 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);
22 голосов
/ 12 сентября 2011

Я недавно столкнулся с этой проблемой и нашел более простой способ (возможно, это поддержка Spring 3)

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

Нет необходимости изменять / добавлять источник сообщения.

11 голосов
/ 23 октября 2017

с потоками Java 8

bindingResult
.getFieldErrors()
.stream()
.forEach(f -> System.out.println(f.getField() + ": " + f.getDefaultMessage()));
1 голос
/ 24 ноября 2017

WebMvcConfigurerAdapter:

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

Контроллер:

@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 голос
/ 12 декабря 2013

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

ПРИМЕЧАНИЕ: Вызов Errors.getDefaultMessage () не обязательно вернет то же сообщение, которое генерируется из кода + аргументы. DefaultMessage - это отдельное значение, определенное при вызове метода Errors.rejectValue (). См. API ошибок .rejectValue () здесь

...