2012-06-22 52 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擴展,它只有幾十行代碼。