2016-06-15 12 views
1

Ich habe eine REST-API geschrieben von jemand anderem, in dem die Methode, die die Anfrage an eine bestimmte URL behandelt, eine Reihe von Parametern akzeptiert, die von Pfadparametern aufgefüllt werden.Wie verwende ich einen benutzerdefinierten Validator mit Dropwizard?

Die Person, die dies geschrieben hat, hat DropWizard verwendet und ich habe keine vorherige Erfahrung daran zu arbeiten. Ich habe die Aufgabe, das Feld studentId zu validieren, indem ich es mit Werten in der Datenbank vergleiche. Dies wäre ziemlich einfach, aber mir wurde gesagt, es mit einem benutzerdefinierten Validator zu tun. Ich bin ziemlich neu zu schreiben Anmerkungen aber nach viel zu graben eine Anmerkung wie dieser,

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

Danach schrieb ich die Anmerkung zum Feld hinzugefügt ich die Validierung wie diese laufen wollte,

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

Nun das Problem ist, dass, wenn ich den Code ausführen/debuggen ... dieser Validator nicht aufgerufen wird, auch habe ich keine Idee, wie Sie den Wert von studentId innerhalb der Validierungsklasse studentId erhalten. Also grub ich etwas mehr und fügte das zur Anwendungsdatei hinzu

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

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

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

    } 

Ich bin buchstäblich am Ende meines Verstandes. Jede Hilfe wird sehr geschätzt. Entschuldige die schlechte Formatierung.

Antwort

5

das ist ziemlich einfach. Ich werde mein Beispiel hier einfügen, da ich es aufgeschrieben habe und ich bin faul und möchte deine lustige Erfahrung nicht wegbringen :)

Edit: Ich denke, dein Problem ist, dass du deine Ressource nicht mit @ beschriftet hast. Gültige

so hier gehen wir:

Sie sind auf dem richtigen Weg mit dem Validator. Dies sind 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; 
    } 

} 

Und dies ist die Annotation:

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

Die Anwendung:

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"); 
    } 
} 

Und die Ressource:

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

Ich habe nichts dagegen die Metriken haben sie nichts damit zu tun. Der wichtige Teil ist, dass Sie DW mitteilen müssen, was Sie validiert haben möchten.

In der Ressource, siehe die Testmethode. Ich annotate das Argument, das ich brauche mit @Valid (teilt DW mit, um zu validieren) @CustomValidation (teilt DW mit, was Validator benutzt).

Dies ist nicht wirklich eine Dropwizard-Funktion, sondern eine Implementierung des Hibernate-Validators.

Die Art, wie es unter der Haube funktioniert, ist, dass Hibernate die Validator-Klasse im laufenden Betrieb erstellt, wenn sie durch Aufrufen des Konstruktors angefordert wird. Nun funktioniert das sehr gut, wenn Sie eine einfache Validierung haben (wie zB einen String vergleichen). Wenn Sie Abhängigkeiten benötigen, wird es etwas komplizierter.Ich habe ein Beispiel dafür, wie gut, dass man hier nachlesen kann:

With dropwizard validation, can I access the DB to insert a record

Dieses Beispiel verwendet guice, aber es zeigt, wie Sie Ihre eigene Kreation Mechanismus in Validierung Haken kann. Auf diese Weise können Sie Ihre Validiererstellung steuern und sie mit einer Datenquelle injizieren oder initialisieren, um auf Ihre Datenbank zuzugreifen.

Ich hoffe, dass beantwortet Ihre Fragen,

Artur

+0

und einige weitere Informationen über Validierer und wie die Validierung mit Gruppen erreichen aktiviert, hier: http://stackoverflow.com/questions/37463570/dropwizard-validate-a-field-only -on-post/37480676 # 37480676 – pandaadb

+0

Danke für Ihre Antwort. Wenn ich es versuchte, bekam ich diese Warnung org.glassfish.jersey.internal.inject.Providers: Ein Provider com.shuvro.application.validator.StudentIdValidatior $ StudentIdValidation registriert in SERVER-Laufzeit implementiert keine Provider-Schnittstellen in der Laufzeit SERVER. Aufgrund von Constraint-Konfigurationsproblemen wird der Provider com.shuvro.application.validator.StudentIdValidator.StudentIdValidatior $ StudentIdValidation ignoriert. –

+0

Hallo - Sie müssen Ihren Validator nicht registrieren. Es ist keine Jersey-Komponente, daher weiß Jersey nicht, was damit zu tun ist – pandaadb