Dropwizard中的Java复杂验证?

时间:2012-12-14 16:52:42

标签: java json validation jax-rs dropwizard

我想在REST端点上接受JSON并将其转换为正确的类型以便立即验证。

端点如下所示:

@POST
public Response createCar(@Valid Car car) { 
    // persist to DB
    // ... 
}

但是Car有很多子类,例如: Van,SelfDrivingCar,RaceCar等。如何在端点上接受不同的JSON表示,同时保留验证码 在资源中简洁如@Valid Car car

再次:我发送JSON就像(这里,它是Car的子类的表示,即SelfDrivingCar):

{ 
    "id" : "t1",                      // every Car has an Id
    "kind" : "selfdriving",           // every Car has a type-hint
    "max_speed" : "200 mph",          // some attribute
    "ai_provider" : "fastcarsai ltd." // this is SelfDrivingCar-specific
}

并且我希望验证机制查看kind属性,创建适当子类的实例,例如SelfDrivingCar并执行验证。

我知道我可以为所有类型的汽车创建不同的端点,但那似乎并不干净。而且我知道我可以使用真实的Validator代替注释并手工完成,所以我只是问这个问题是否有一些优雅的捷径。

2 个答案:

答案 0 :(得分:5)

验证框架不负责提取正确的多态类型并对其进行验证。事实上,在验证启动时,对象已经创建。它只能与那时的工作一起使用。但请注意:

public Response createCar(@Valid Car car) {
    // ...
}

无论“汽车”的运行时类型是什么,都会调用验证。很明显,您要做的是确保car变量在运行时绑定到正确的类型。这是 反序列化框架 的责任。您需要确定使用应用程序中使用的JSON库执行此操作的正确方法,但是使用Jackson,您可以使用@JsonTypeInfo注释来确定多态类型的范围。

@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="kind")
public class Car implements Serializable {
}

答案 1 :(得分:1)

使用DW 0.7.1

在我的案例中,我有一个自定义用户类,我在那里添加:

@ValidationMethod(message="user_name is null or empty")
public boolean isUserName() {       
    if (Strings.isNullOrEmpty(user_name)) {
        return false;
    } else {
        return true;
    }
}

现在使用了@Valid,我在我的测试中得到了一个javax.validation.ConstraintViolationException - > @Test(预期= javax.validation.ConstraintViolationException.class)