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

查看:169
本文介绍了如何使用带有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字段与db中的值进行比较来验证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功能,但是而是一个hibernate验证器实现。

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.

我希望能回答你的问题,

I hope that answers your questions,

Artur

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

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