我有一个返回JSON的控制器。它采用一种形式,通过弹簧注释验证自己。我可以从BindingResult获取FieldError列表,但它们不包含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对象的数组,但它没有实际的错误。
答案 0 :(得分:33)
免责声明:我仍然不使用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());
}
}
我希望它对你有用
<强>更新强>
如果您想获取资源包提供的消息,则需要注册的messageSource实例(必须称为messageSource)
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="ValidationMessages"/>
</bean>
在View
中注入MessageSource实例@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);
答案 1 :(得分:22)
我最近遇到了这个问题,并找到了一种更简单的方法(也许是Spring 3的支持)
List<FieldError> errors = bindingResult.getFieldErrors();
for (FieldError error : errors ) {
System.out.println (error.getObjectName() + " - " + error.getDefaultMessage());
}
无需更改/添加消息来源。
答案 2 :(得分:11)
使用Java 8 Streams
bindingResult
.getFieldErrors()
.stream()
.forEach(f -> System.out.println(f.getField() + ": " + f.getDefaultMessage()));
答案 3 :(得分:1)
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()不一定会返回从代码+ args生成的相同消息。 defaultMessage是在调用Errors.rejectValue()方法时定义的单独值。见Errors.rejectValue() API Here
答案 4 :(得分:1)
<强> 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 />");
}
答案 5 :(得分:1)
要获取与每个字段相关联的所有错误的 Map
:
@Autowired
private MessageSource messageSource;
Map<String, List<String>> errorMap = bindingResult.getFieldErrors().stream()
.collect(Collectors.groupingBy(FieldError::getField,
Collectors.mapping(e -> messageSource.getMessage(e, LocaleContextHolder.getLocale()),
Collectors.toList())));
//In this example, each field/key is mapped to a
//List of all the errors associated with that field
要获得一个 Map
,并将与每个字段关联的错误合并为一个 String
:
@Autowired
private MessageSource messageSource;
Map<String, String> errorMap = bindingResult.getFieldErrors().stream()
.collect(Collectors
.toMap(FieldError::getField,
e -> messageSource.getMessage(e, LocaleContextHolder.getLocale()),
(a,b)->a + "<br/>" + b));
//In this example, multiple errors for the same field are separated with <br/>,
//the line break element, to be easily displayed on the front end