我在使用 @InitBinder 注释实现两个验证器时遇到问题。
Controller 代码:
@Autowired
private SessionValidator sessionValidator;
@Autowired
private ChannelValidator channelValidator;
@InitBinder
public void initBinder(WebDataBinder binder){
binder.addValidators(sessionValidator, channelValidator);
}
@RequestMapping(method = RequestMethod.GET)
public UserInfo findBySession(
@Valid @ModelAttribute Session session,
@Valid @ModelAttribute Channel channel){
//...
}
session 验证器:
@Component
public class SessionValidator implements Validator {
@Override
public boolean supports(Class<?> aClass){
return Session.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors){
//...
}
}
channel 验证器:
@Component
public class ChannelValidator implements Validator {
@Override
public boolean supports(Class<?> aClass){
return Channel.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors){
//...
}
}
调用 Controller 时收到以下异常:
Caused by: java.lang.IllegalStateException: Invalid target for Validator [com.almundo.p13n.dna.validators.ChannelValidator@4e642ee1]: Session(null, null)
任何人都知道如何解决它?提前致谢!
最佳答案
您绑定(bind)了两个验证器,但对于每个要验证的参数,仅支持其中一个。SessionValidator
支持Session
参数但不支持 Channel
参数和反向ChannelValidator
支持Channel
参数但不支持 Session
范围。
而异常(exception)。
作为第一种选择,您可以在每个 Spring Validator 子类中支持这两种参数类型。这有点笨拙,但应该可以:
@Override
public boolean supports(Class<?> aClass){
return Channel.class.equals(aClass) || Session.class.equals(aClass);
}
您当然应该检查
validate()
中的类型并且仅当它与验证器类匹配时才执行验证。作为第二种选择,通过实现
javax.validation.ConstraintValidator
使用标准验证 API为每个类验证并通过在 Controller 中显式验证参数。作为第三种选择,如果有意义,您可以直接注释
Session
上的约束。和 Channel
类。所以,你仍然可以使用 @Valid
在参数声明中保持自动验证。
关于 Spring 验证 : getting "Invalid target for Validator" when using two validators,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51830519/