如何在 dropwizard 中使用自定义验证器? [英] How do I use a custom validator with dropwizard?

查看:28
本文介绍了如何在 dropwizard 中使用自定义验证器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a REST api written by someone else in which the method that handles the request to a particular url accepts a bunch of parameters that are populated from path parameters.

@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 字段.这将非常简单,但有人告诉我使用自定义验证器来完成.我对写注释很陌生,但经过多次挖掘后写了这样的注释,

The person who wrote this has used DropWizard and I have no previous experience working on it. I have the task of validating the studentId field by comparing it with values in the db. This would be pretty straightforward but I have been told to do it using a custom validator. I am pretty new to writing annotations but after much digging wrote an annotation like this,

@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;
            }
        }
    }

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

After this I added the annotation to the field I wanted to run the validation on like this,

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

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

Now the problem is that, when the I run/debug the code...this validator is not being called, also I have no idea how to get the value of studentId inside the studentId validation class. So I dug some more and added this to the application file

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

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

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

    }

我真的是在我的智慧的尽头.非常感谢任何帮助.很抱歉格式不正确.

I am literally at the end of my wits. Any help will be very VERY appreciated. Sorry about the poor formatting.

推荐答案

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

this is pretty straight forward. I will paste my example here since I had it written up and I am lazy and don't want to take your fun experience away :)

我认为您的问题是您没有使用 @Valid 注释您的资源

I think your issue is that you didn't annotate your resource with @Valid

所以我们开始:

您在验证器的正确轨道上.这些是我的:

You are on the right track with the validator. These are mine:

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 您想要验证的内容.

Don't mind the metrics, they have nothing to do with it. The important part is that you need to tell DW what you want to have validated.

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

In the resource, see the test method. I annotate the argument I need with @Valid (tells DW to validate) @CustomValidation (tells DW what validator to use).

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

This is not actually a Dropwizard feature, but rather a hibernate validator implementation.

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

The way it works under the hood is that hibernate creates the Validator class on the fly when requested by invoking the constructor. Now this works very fine if you have simple validation (like say comparing a string). If you need dependencies, then it gets slightly more tricky. I have an example for that as well, that you can read up on here:

与dropwizard 验证,我可以访问数据库插入记录

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

This example uses guice, but it demonstrates how you can hook your own creation mechanism into validation. That way you can control your validator creation and inject or initialise them with a datasource to access your database.

希望能回答您的问题

阿图尔

这篇关于如何在 dropwizard 中使用自定义验证器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆