2017-02-04 2 views
0

Ich möchte die Eingabe mit einem Constraint-Validator validieren. Mein Problem ist, dass ich einige Informationen benötigt, die in ServletContext enthalten sind, zum Beispiel den Pfad der Eigenschaftendatei, um die Request Bean zu validieren. Ich finde, dass mit Spring ich @Autowired Annotation verwenden kann, aber leider kann ich dieses Framework nicht verwenden.Zugriff auf ServletContext in einem ConstraintValidator

Die Einschränkung:

@Constraint(validateBy = MyValidationClass.class) 
@Target(PARAMETER) 
@Retention(RUNTIME) 
public @interface MyValidation { 
    ... 
} 

Und was will ich in Constraint-Validator ist so etwas wie dieses:

@Override 
public boolean isValid(RequestBean value, ConstraintValidatorContext context) { 
    Properties props = servletContext.getAttribute("ws.props") 
    // my validation 
} 

Wie kann ich das erreichen?

Antwort

0

Dies ist möglicherweise nicht die beste Lösung. (EDIT: Sie könnten eine bessere Lösung in meinem EDIT am Ende finden)

Aber ich denke, Sie könnten einfach erstellen ServletContainerInitializer, speichert die ServletContext in einer statischen Variable und greifen Sie auf diese innerhalb der Initialisierung.

Was ich hier nicht sehr schön finde ist, dass Sie eine tiefe Abhängigkeit von einer statischen Methode haben. Aber sonst könnten Sie einen Weg finden, in den Prozess, der die ConstraintValidator instanziiert.

EDIT: Ich habe gerade die Hibernator Validator-Dokumentation nachgeschlagen. Und ich denke, das Kapitel hier wäre für Sie interessant sein, wenn Sie die hibernator Validator Implementierung verwenden: https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#__code_constraintvalidatorfactory_code

Nach dieser würde ich eine eigenes ConstraintValidatorFactory zu schaffen und eine neue Schnittstelle ServletContextAware mit einem Setter setServletContext(ServletContext). Dann kann die Validiererfabrik überprüfen, ob die Klasse, die instanziiert werden soll, diese Schnittstelle implementiert und ServletContext setzt. Die neue ConstraintValidatorFactory könnte verwendet werden, um eine neue ValidatorFactory zu erstellen, die zum Erstellen der erforderlichen Validatoren verwendet wird.

Nur einige nicht-geprüft Codebeispiele:

interface ServletContextArea { 
    public void setServletContext(ServletContext context); 
} 


public class ServletContextConstraintValidatorFactory implements ConstraintValidatorFactory { 
    private ServletContext servletContext; 

    public ServletContextConstraintValidatorFactory(ServletContext servletContext) { 
     this.servletContext = servletContext; 
    } 

    @Override 
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { 
     // create instance from key as validator 

     if(validator instanceof ServletContextAware) { 
      ((ServletContextAware) validator).setServletContext(this.servletContext); 
     } 
     //... 

     return validator; 
    } 

    @Override 
    public void releaseInstance(ConstraintValidator<?, ?> instance) { 
     //... 
    } 
} 

// somewhere in the code where you have the servletContext available 
ValidatorFactory validatorFactory = Validation.byDefaultProvider() 
    .configure() 
    .constraintValidatorFactory(new ServletContextConstraintValidatorFactory(servletContext)) 
    .buildValidatorFactory(); 
Validator validator = validatorFactory.getValidator(); 
Verwandte Themen