如何将自定义验证器与 dropwizard 一起使用?

How do I use a custom validator with dropwizard?

我有一个由其他人编写的 REST api,其中处理对特定 url 请求的方法接受一堆从路径参数填充的参数。

@POST
@Path("/{classid}/{studentid}/details")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@SuppressWarnings("unchecked")


public Response processFile(@FormDataParam("sourceFile") InputStream aStream, @PathParam("classid") String classId, @PathParam("studentid")  String studentId, @Context HttpServletRequest httpRequest) {

// Code to do stuff and return a response
}

写这篇文章的人使用过 DropWizard,我以前没有使用它的经验。我的任务是通过将 studentId 字段与数据库中的值进行比较来验证它。这将非常简单,但我被告知要使用自定义验证器来完成。我对编写注释很陌生,但经过大量挖掘后写了一个这样的注释,

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = StudentIdValidator.StudentIdValidation.class)

public @interface StudentIdValidator {

    String message() default "{Invalid Id}";

      Class<?>[] groups() default {};

      Class<? extends Payload>[] payload() default {};


      class StudentIdValidation implements ConstraintValidator<StudentIdValidator, String> {

        @Override
        public void initialize(StudentIdValidator constraintAnnotation) {
            System.out.println("Annotation initialize !!!!!!!!!");
        }


        @Override
        public boolean isValid(String value, ConstraintValidatorContext context)                                                                            {
                // TODO Auto-generated method stub
                System.out.println("Annotation called");
                return false;
            }
        }
    }

在此之后,我将注释添加到我想要 运行 验证的字段中,

public Response processFile(@FormDataParam("sourceFile") InputStream     aStream, @PathParam("classid") String classId, @StudentIdValidator     @PathParam("studentid")  String studentId, @Context HttpServletRequest     httpRequest)

现在的问题是,当我 run/debug 代码...没有调用此验证器时,我也不知道如何在 studentId 验证中获取 studentId 的值 class.所以我又挖了一些并将其添加到应用程序文件

class MyApplication extends Application<MyConfiguration> {
    ........

    @Override
   public void run(MyConfiguration myConfiguration, Environment                     currentEnvironment) {

     currentEnvironment.jersey().register(StudentIdValidator.class);

    }

我真是无计可施了。任何帮助将不胜感激。抱歉格式不正确。

这很简单。我会把我的例子贴在这里,因为我已经写好了,我很懒,不想带走你有趣的经历:)

编辑:我认为你的问题是你没有用@Valid

注释你的资源

所以我们开始:

您在验证器方面走在正确的轨道上。这些是我的:

public class CustomValidator implements ConstraintValidator<CustomValidation, String> {

    @Override
    public void initialize(CustomValidation constraintAnnotation) {

    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {

        System.out.println("Validation called");

        return false;
    }

}

这是注释:

@Constraint(validatedBy = {CustomValidator.class})
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface CustomValidation {


      String message() default "Some message";

      Class<?>[] groups() default {};
      Class<? extends Payload>[] payload() default {};
}

申请:

public class Application extends io.dropwizard.Application<Configuration>{

    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {
        MetricRegistry metrics = environment.metrics();
        environment.jersey().register(new HelloResource(metrics));

    }

    public static void main(String[] args) throws Exception {
        new Application().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test.yaml");
    }
}

以及资源:

@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class HelloResource {

    private MetricRegistry service;

    public HelloResource(MetricRegistry service) {
        this.service = service;
    }

    @GET
    public String hello() {

        Timer timer = service.timer("test");

        try(Context t = timer.time()) {
            return "Hello World";
        }

    }


    @GET
    @Path("/test2")
    public void test(@Valid @CustomValidation @QueryParam("arg") String test) {
        System.out.println(test);
    }
}

不要介意指标,它们与它无关。重要的部分是您需要告诉 DW 您想要验证的内容。

在资源中,查看测试方法。我用 @Valid 注释我需要的参数(告诉 DW 进行验证)@CustomValidation(告诉 DW 使用什么验证器)。

这实际上不是 Dropwizard 功能,而是一个休眠验证器实现。

它在幕后的工作方式是当通过调用构造函数请求时,hibernate 即时创建验证器 class。如果你有简单的验证(比如比较一个字符串),现在这个工作非常好。如果您需要依赖项,那么它会变得稍微棘手一些。我也有一个例子,你可以在这里阅读:

此示例使用 guice,但它演示了如何将您自己的创建机制与验证挂钩。这样您就可以控制验证器的创建并使用数据源注入或初始化它们以访问您的数据库。

我希望能回答你的问题,

亚瑟

dropwizard 中的自定义验证与 hibernate 自定义验证器相同。

关注 link : hibernate validator-customconstraints