接收参数的CDI验证

时间:2012-06-22 13:09:58

标签: java rest cdi validation facade

我正在尝试理解CDI,目前只有很少的结果。 :( 实际上我很喜欢这个例子的Web服务门面:

@GET
@Path("/greeting/{name}")
@produces(mediatype.text_plain)
public String sayHello(@PathParam("name") String name)
{
    return "Hello " + name;
}

因为使用CDI注释我想在每次将字符串作为参数发送时在服务器端进行检查,就像:(注意@NameValidator注释)

@GET
@Path("/greeting/{name}")
@Produces(mediatype.text_plain)
public String sayHello( @NameValidator @PathParam("name") String name)
{
    return "Hello " + name;
}

在外部类中,验证可以是类似的东西:

if (name == "Andrea") {
    throw new Exception();}

它是如何工作的?可能吗?如果没有,有什么替代方案? 谢谢! 安德烈

2 个答案:

答案 0 :(得分:3)

您可以使用CDI's interceptor annotations并执行以下操作:

...
@Validated
public String sayHello(@Validator(MyValidator.class) String name) {
    ...

@Validated将方法绑定到ValidationInterceptor类左右,您使用@AroundInvoke方法及其InvocationContext参数来检查传递的参数并验证它们。

这种方法的一个“难点”是你必须使用反射来获取每个参数的@Validator注释和指定的验证器类,然后在最终进行实际验证之前创建/检索相应的实例。

稍微不同的方法是将验证器的公共超类/接口Instance<T>注入ValidationInterceptor并使用验证器限定符注释sayHello参数:

// in ValidationInterceptor:

@Inject
private Instance<Validator> validatorInstance;

@AroundInvoke
public Object validate(InvocationContext context) {

    // get Annotation instances for target method parameters
    // ...

    Validator validator =
        validatorInstance.select(annotations).get();

    // ... validator.validate(parameter); ...

}

// sayHello:

...
@Validated
public String sayHello(@NameValidator String name) {
    ...

要从InvocationContext获取参数注释,请执行以下操作:

Annotation[][] annotations = context.getMethod().getParameterAnnotations();

您还可以考虑在@AfterBeanDiscovery事件处理程序中预处理这些注释。

答案 1 :(得分:3)

对于该验证问题,我建议Seam Validation,它将CDI桥接到Hibernate-Validator。这可以让你熟悉Hibernate end的定义良好的验证API,使你能够编写如下代码:

public void registerUser(@Valid UserData data) {...};

如果您不能使用Seam 3依赖项,您可以轻松获取CDI扩展的相关源代码,它只是几十行代码。