java - responsebody - Cómo obtener el texto de error en el controlador desde BindingResult
responseentity spring rest example (5)
Con Java 8 Streams
bindingResult
.getFieldErrors()
.stream()
.forEach(f -> System.out.println(f.getField() + ": " + f.getDefaultMessage()));
Tengo un controlador que devuelve JSON. Toma una forma, que se valida a sí misma a través de anotaciones de primavera. Puedo obtener la lista FieldError de BindingResult, pero no contienen el texto que un JSP mostraría en la etiqueta. ¿Cómo puedo obtener el texto de error para enviar de vuelta en 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;
}
}
La clase JSONREsponse es solo un 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...
}
Llamar a BindingResult.getAllErrors () devuelve una matriz de objetos FieldError, pero no tiene los errores reales.
Conocí este problema recientemente, y encontré una manera más fácil (tal vez sea el soporte de Spring 3)
List<FieldError> errors = bindingResult.getFieldErrors();
for (FieldError error : errors ) {
System.out.println (error.getObjectName() + " - " + error.getDefaultMessage());
}
No es necesario cambiar / agregar el origen del mensaje.
Descargo de responsabilidad: todavía no uso Spring-MVC 3.0
Pero creo que el mismo enfoque utilizado por Spring 2.5 puede satisfacer sus necesidades
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());
}
}
Espero que te pueda ser útil
ACTUALIZAR
Si desea obtener el mensaje proporcionado por su paquete de recursos, necesita una instancia de messageSource registrada ( debe llamarse messageSource)
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="ValidationMessages"/>
</bean>
Inyecte su instancia de MessageSource dentro de su vista
@Autowired
private MessageSource messageSource;
Y para recibir su mensaje, haga lo siguiente
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);
}
}
Su Validator debería verse como
/**
* 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);
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));
}
NOTA: Llamar a Errors.getDefaultMessage () no devolverá necesariamente el mismo mensaje que se genera desde el código + args. El defaultMessage es un valor separado definido al llamar al método Errors.rejectValue (). Ver la API Errors.rejectValue () aquí
WebMvcConfigurerAdapter:
@Bean(name = "messageSourceAccessor")
public org.springframework.context.support.MessageSourceAccessor messageSourceAccessor() {
return new MessageSourceAccessor( messageSource());
}
Controlador:
@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 />");
}