Java 对接收到的参数进行CDI验证

Java 对接收到的参数进行CDI验证,java,rest,cdi,validation,facade,Java,Rest,Cdi,Validation,Facade,我正在努力理解CDI,目前几乎没有结果:( 事实上,我对web服务facade很感兴趣,例如: @GET @Path("/greeting/{name}") @produces(mediatype.text_plain) public String sayHello(@PathParam("name") String name) { return "Hello " + name; } 因为使用CDI注释,每次将字符串作为参数发送时,我都希望在服务器端进行检查,以获得如下内容:(注意@N

我正在努力理解CDI,目前几乎没有结果:( 事实上,我对web服务facade很感兴趣,例如:

@GET
@Path("/greeting/{name}")
@produces(mediatype.text_plain)
public String sayHello(@PathParam("name") String name)
{
    return "Hello " + name;
}
因为使用CDI注释,每次将字符串作为参数发送时,我都希望在服务器端进行检查,以获得如下内容:(注意
@NameValidator
annotation)

在外部类中,Validation可以是类似的任何内容:

if (name == "Andrea") {
    throw new Exception();}
它是如何工作的?有可能吗?如果没有,有什么替代方案? 非常感谢。 Andrea

您可以使用并执行以下操作:

...
@Validated
public String sayHello(@Validator(MyValidator.class) String name) {
    ...
Annotation[][] annotations = context.getMethod().getParameterAnnotations();
其中
@Validated
将该方法绑定到
ValidationInterceptor
类,在该类中,您可以使用
@AroundInvoke
方法及其
InvocationContext
参数来检查传递的参数并对其进行验证

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

稍微不同的方法是将验证器的公共超类/接口的
实例
注入到
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) {
    ...

您也可以考虑在<代码> @后备发现> /代码>事件处理程序中对这些注释进行预处理。

您可以使用和做一些类似的事情:

...
@Validated
public String sayHello(@Validator(MyValidator.class) String name) {
    ...
Annotation[][] annotations = context.getMethod().getParameterAnnotations();
其中
@Validated
将该方法绑定到
ValidationInterceptor
类,在该类中,您可以使用
@AroundInvoke
方法及其
InvocationContext
参数来检查传递的参数并对其进行验证

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

稍微不同的方法是将验证器的公共超类/接口的
实例
注入到
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) {
    ...

您也可以考虑在<代码> @后备发现>代码>事件处理程序中对这些注释进行预处理。

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

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

对于我要提出的验证问题,它将CDI与之连接起来。这使您能够使用Hibernate end定义良好的验证API编写如下代码:

public void registerUser(@Valid UserData data) {...};
如果您不能接受Seam 3依赖项,那么您可以轻松地获取CDI扩展的相关源代码,它只是几十行代码