2017-02-23 7 views
0

Ich habe einen Dropwizard-Dienst, der eine PUT eines JSON-Dokuments akzeptiert, das eine Bean darstellt. Ich mache Gebrauch von Zwang Anmerkungen in der Bean-Implementierung und verwenden Sie die @Valid Anmerkung in meiner Ressource-Methode:Dropwizard und Überprüfen von Listen von Objekten

@PUT 
public Response write(@Valid MyBean bean); 

und alles funktioniert recht gut.

Nun möchte ich jedoch eine Array von Objekten in der JSON übergeben. Ich änderte einfach die Methode Signatur

@PUT 
public Response write(@Valid List<MyBean> beans); 

und es funktioniert im Allgemeinen, aber wenn es Validierungsfehler sind dann die Antwort ist nicht sehr benutzerfreundlich. Zum Beispiel, wenn ich in 100 Bohnen im Array schreiben, und ein von ihnen ist eine ‚Namen‘ Eigenschaft fehlt, dann ist die Antwort

{"errors":["name may not be empty"]} 

ohne Angabe von die Bohne in der Anfrage hat das Problem.

Gibt es eine Möglichkeit, dies zu überwinden?

Fehlt das, gibt es eine Möglichkeit für mich, einen Validator in der Resource-Klasse zu erhalten, so dass ich all dies selbst handhaben kann?

Antwort

0

Die Art, wie Sie dies möchten, ist möglicherweise nicht möglich. Hier ist ein Standalone-Test, was geschieht und wie Hibernate Wold wie für Sie hinein Haken:

public class ListBeanValidationTest { 

    public static void main(String[] args) { 
     List<Bean> asList = Arrays.asList(new Bean("test"), new Bean("test2")); 

     Validator v = Validators.newConfiguration().messageInterpolator(new MsgInterpolator()).buildValidatorFactory().getValidator(); 

     // this is what DW does but i am lazy so you get the main version 
     if(asList instanceof Iterable) { 
      Iterable values = (Iterable) asList; 
      Set<ConstraintViolation<Object>> violations = new HashSet<>(); 
      for(Object value : values) { 
       violations.addAll(v.validate(value)); 
      } 

      violations.forEach(System.out::println); 
     } 
    } 

    public static class Bean { 

     Bean(String name) { 
      this.name = name; 
     } 

     String name; 

     @NotEmpty(message="bean not empty ${name}") 
     String wrong; 
    } 

    public static class MsgInterpolator implements MessageInterpolator { 

     @Override 
     public String interpolate(String messageTemplate, Context context) { 
      return interpolate(messageTemplate, context, Locale.getDefault()); 
     } 

     @Override 
     public String interpolate(String messageTemplate, Context context, Locale locale) { 
      Object validatedValue = context.getValidatedValue(); 


      return null; 
     } 

    } 
} 

Die MessageInterpolator ist das Problem hier. Es hat keine Instanz der Bean zu dem Zeitpunkt, zu dem es die Nachricht für Sie interpoliert, so dass Sie leider keinen Verweis darauf verwenden können. Das bedeutet, dass Sie dies auf andere Weise tun müssen.

Sie können einen Verweis auf Ihre validator erhalten (wie Sie dies tun, ist es Ihnen überlassen, Sie können es in der DW-Umgebung finden. Ich verwende DI über Guice dafür).

Wenn Sie dies auf die DW-Weise tun möchten, können Sie in Erweiterung suchen: JacksonMessageBodyProvider - das ist die Klasse, die die Validierung für DW-Ressourcen durchführt.

Ich hoffe, dass

hilft können Sie auch über die Möglichkeiten der Validierung lesen, die hier zur Verfügung stehen: https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/chapter-message-interpolation.html#section-custom-message-interpolation

- artur

+0

Danke - ich landete nur es selbst zu tun (nicht sicher, warum ich dachte, den Validator zu injizieren würde schwierig sein) –

+0

Ich frage mich, ob das eine gute Ergänzung wäre. Wenn Sie jedoch Ihre Bestätigungsnachricht von einer anderen Eigenschaft derselben Bean abhängig machen, wie validieren Sie diese? Sie erhalten eine Abhängigkeitsprüfung bis zu dem Punkt, an dem die gesamte Bean null ist. An diesem Punkt wird der Nachrichteninterpolator bei der Validierung die NPE verwenden, was nicht wirklich gut wäre. Ich kann mir vorstellen, dass das ihre Motivation war, dies nicht zu tun. Außerdem: Die Hibernate-Validierung unterstützt standardmäßig keine Listen oder Arrays, weshalb dies möglicherweise nie ein Problem war. DW hackt das an sich :) – pandaadb

Verwandte Themen