Spring MVC 如何从BindingResult中获取控制器中的错误文本?

kd3sttzy  于 12个月前  发布在  Spring
关注(0)|答案(6)|浏览(144)

我有一个返回JSON的控制器。它采用了一种形式,通过spring注解来验证自己。我可以从BindingResult获取FieldError列表,但是它们不包含JSP将在<form:errors>标记中显示的文本。如何获取要以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对象数组,但它没有实际的错误。

yfwxisqw

yfwxisqw1#

我最近遇到了这个问题,并且找到了一个更简单的方法(也许是Spring 3的支持)

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

无需更改/添加消息源。

4szc88ey

4szc88ey2#

Java 8 Streams

bindingResult
.getFieldErrors()
.stream()
.forEach(f -> System.out.println(f.getField() + ": " + f.getDefaultMessage()));
ycggw6v2

ycggw6v23#

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

yb3bgrhw

yb3bgrhw4#

WebMvcConfigureerAdapter:

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

d4so4syb5#

要获取与每个字段关联的所有错误的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
dfty9e19

dfty9e196#

免责声明:我仍然不使用Spring-MVC 3.0
但我认为Spring2.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>

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

相关问题