2012-06-22 38 views
1

我想了解CDI,目前只有很少的结果。 :( 其实我stucked与像本例中,Web服务门面:接收参数的CDI验证

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

由于使用CDI注解,我想每次做检查服务器端的字符串被作为参数,有comething像(注意:@NameValidator注释)

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

的validaton可以是这样的事情,在外部类:

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

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

回答

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事件处理程序预先处理这些注释。

3

对于验证问题,我建议Seam Validation,它将CDI桥接到Hibernate-Validator。挂接你的Hibernate最终的明确定义的验证,API使你写出这样的代码:

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

如果你不能与接缝3依赖性生活,你可以轻松拍摄的相关源代码CDI扩展,它只有几十行代码。