我遇到了在球衣上触发自定义约束验证的问题。我想激活方法或静态方法的约束。我试过的是在方法上放置一个自定义注释和@ValidateOnExecution
,但是仍然没有触发自定义验证器类。
@LocationIsValid
@ValidateOnExecution
public static List<Double> getLocation(String location) {
...
}
我怀疑问题是bean注释不支持静态方法,所以我删除了static关键字并通过创建一个新对象来访问该方法。但是,自定义LocationIsValid
验证程序仍未激活。
结果我最终放置了一个验证工厂来手动验证这个变量。
public static List<Double> getLocation(String location) {
...
// split the location string into a list of double
...
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
validator.validate(location, LocationIsValid.class);
}
但是自定义约束不会让步。我希望有人可以告诉我下一步该做什么,或者解决这个问题的其他建议。
更多信息
当注释放在资源字段的顶部时,它可以正常工作。
public class Product {
...
@LocationIsValid
private List<Double> location;
...
}
更新
即使我已将方法更改为普通实例方法,它仍然无法正常工作。请注意,我有两个重载方法,一个是资源getter,另一个是将字符串转换为位置。
产品型号
public class Product {
@Id
@JsonSerialize(using = ObjectIdSerializer.class)
private ObjectId id;
@Size(min = 5)
private String name;
@NotNull
@LocationIsValid
private List<Double> location;
private Date dateCreated;
private Date dateModified;
public Product() {
}
public List<Double> getLocation() {
return location;
}
@ValidateOnExecution
@LocationIsValid
public List<Double> getLocation(String location) {
String[] locationString = location.split(";");
if (locationString.length != 2) {
return null;
}
List<Double>locations = new ArrayList<Double>();
for (int i = 0; i < locationString.length; i++) {
locations.add(Double.parseDouble(locationString[i]));
}
return locations;
}
// Other setters getters
}
产品资源
@GET
public ProductList getProducts(@QueryParam("near") String location) {
// parse the locations variable
Product product = new Product();
// did not work
// I have placed a breakpoint on the LocationIsValid
List<Double> locations = product.getLocation(location);
}
注意:我很确定问题不在LocationIsValid中,因为它在我将其验证为实体时正常工作@Valid Product product
我使用Jersey 2.4.1和jersey-bean-validation 2.4.1依赖
答案 0 :(得分:0)
正如您所说,Bean Validation规范不支持静态方法的验证。实例方法的验证应该可以,你可以发布你的JAX-RS资源的整个代码吗?是否在该资源上定义了getLocation()
? JAX-RS应该触发对资源类方法的方法约束(无论是参数还是返回值约束)的验证。
答案 1 :(得分:0)
问题是我实际上并没有使用控制器中Product对象的@Valid
来调用验证器。原因是我只需要验证位置变量而不是整个Product对象。所以我想解决它的唯一方法是在资源函数内以编程方式调用验证器工厂。请注意,之前我没有成功使用验证器验证属性的原因是因为我从未调用过正确的方法。下面是使用验证工厂验证资源对象中特定属性的代码。
@GET
public ProductList getProducts(@QueryParam("near") String location) {
// parse the locations variable
List<Double> locations = Product.getLocation(location);
// validate the value
Set<ConstraintViolation<Product>> constraints = Validation
.buildDefaultValidatorFactory()
.getValidator()
.validateValue(Product.class, "location", locations, Default.class);
if (locations == null || locations.size() != 2
|| constraints.size() > 0) {
throw new ConstraintViolationException(constraints);
}
}
如果有人有更好的想法或建议来解决此问题,请告知我们。