1

我正在尝试了解 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();}

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

4

2 回答 2

3

您可以使用CDI 的拦截器注释并执行以下操作:

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

Where@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您还可以考虑在事件处理程序中预处理这些注释。

于 2012-06-22T14:26:42.790 回答
3

对于那个验证问题,我会建议Seam Validation,它将 CDI 连接到Hibernate-Validator。这将您连接到 Hibernate 端定义良好的验证 API 上,使您能够编写如下代码:

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

如果您无法忍受 Seam 3 依赖项,您可以轻松获取 CDI 扩展的相关源代码,只需几十行代码。

于 2012-06-22T15:05:20.857 回答