Spring 验证器:同时具有注释和验证器实现 [英] Spring validator: having both annotation and validator implementation
问题描述
是否可以同时拥有表单验证器和注释约束?
Is it possible to have both a validator for a form and annotation constraints?
例如要在表单对象中包含此字段:
For example to have in a form object this field:
@NotEmpty
private String date;
然后在验证器中验证日期的模式.
but then validate the date's pattern in a validator.
我知道有模式注释,但我只是想看看是否可以同时使用两种类型的验证.
I know there is the pattern annotation but I just want to see if I can use both types of validating.
推荐答案
这里是一个非常好的站点的链接,该站点解释了如何将 JSR-303 验证器与 spring 验证器相结合.
Here is the link to a very good site where it's explained how you can combine the JSR-303 validator with the spring validator.
接下来我将介绍我的解决方案.希望有帮助.
I'll present next my solution that works. Hope it helps.
我的抽象验证器:
import java.util.Map;
import java.util.Set;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.validation.Errors;
public abstract class AbstractValidator implements org.springframework.validation.Validator, ApplicationContextAware,
ConstraintValidatorFactory {
@Autowired
private Validator validator;
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
Map<String, T> beansByNames = applicationContext.getBeansOfType(key);
if (beansByNames.isEmpty()) {
try {
return key.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e);
}
}
if (beansByNames.size() > 1) {
throw new RuntimeException("Only one bean of type '" + key.getName() + "' is allowed in the application context");
}
return (T) beansByNames.values().iterator().next();
}
public boolean supports(Class<?> c) {
return true;
}
public void validate(Object objectForm, Errors errors) {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(objectForm);
for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
String propertyPath = constraintViolation.getPropertyPath().toString();
String message = constraintViolation.getMessage();
errors.rejectValue(propertyPath, "", message);
}
addExtraValidation(objectForm, errors);
}
protected abstract void addExtraValidation(Object objectForm, Errors errors);
}
一个实际的验证器:
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import ro.scorpionsoftware.demo3.dao.AbstractValidator;
@Component(value="doctorValidator")
public class DoctorValidator extends AbstractValidator {
@Override
protected void addExtraValidation(Object objectForm, Errors errors) {
//perform typical validation
//can autowire to context
}
}
控制器:(最后是@Valid 与验证器的绑定)
A controller: (At the end it's the binding of the @Valid with the validator)
@Controller
public class DoctorEditController {
@Autowired
private DoctorValidator doctorValidator;
@RequestMapping(value = "/doctorEdit", method = RequestMethod.POST)
public String processSubmit(
@ModelAttribute("doctorForm") @Valid DoctorForm df,
BindingResult result,
ModelMap model) {
...
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(doctorValidator);
}
}
在上下文中声明 JSR-303 验证器:
In context declare the JSR-303 validator:
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
通过这种方法,您可以在实际验证器和您想要实现的任何其他自定义注释中获取上下文.
With this approach you can get the context in both the actual validator and any other custom annotation you'd like to implement.
这篇关于Spring 验证器:同时具有注释和验证器实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!