responseentity responsebody requestmapping requestbody mvc example java json spring spring-mvc spring-annotations

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