我正在尝试理解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();}
它是如何工作的?可能吗?如果没有,有什么替代方案? 谢谢! 安德烈
答案 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扩展的相关源代码,它只是几十行代码。