2015-12-15 20 views
9

Non riesco proprio a ottenere convalide per funzionare. Ho questo semplice punto finale che fa parte di un programma di avvio Primavera:@Valido che non funziona con JAX-RS utilizzando Spring Boot

@POST 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public Response create(@Valid UserDTO userDTO, @Context UriInfo uriInfo) { 
    User user = UserParser.parse(userDTO); 
    userService.save(user); 
    final URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build(); 
    return Response.created(uri).build(); 
} 

Poi, l'UserDTO per convalidare:

@Getter 
@Setter 
@JsonInclude(JsonInclude.Include.NON_NULL) 
public class UserDTO { 

    private Long id; 

    // redundant validations, for testing 
    @NotNull 
    @Size(min = 5, max = 80, message = "First name too short") 
    @NotBlank(message = "First name blank") 
    @NotEmpty(message = "First name empty") 
    private String firstName; 

    @NotNull 
    @Size(min = 2, max = 80, message = "Last name too short") 
    private String lastName; 

    @NotNull 
    private String email; 

} 

Ed elabora sempre qualsiasi richiesta, anche con campi vuoti. Ho anche creato un endpoint test per vedere se il problema stava avendo le convalide all'interno del DTO

@Path("/validator/{testInt}") 
@GET 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public String validator(@Valid @Min(value = 30, message = "testInt too small") @PathParam("testInt") Integer testInt) { 
    return String.valueOf(testInt); 
} 

Ma questo non funziona neanche, restituisce felicemente qualsiasi int che riceve. Nel caso in cui è importante, il mio punto finale è un @Service, e qui è alle corrispondenti parti del mio albero esperto di dipendenze:

[INFO] +- org.glassfish.jersey.ext:jersey-bean-validation:jar:2.22.1:compile 
[INFO] | +- org.glassfish.hk2.external:javax.inject:jar:2.4.0-b31:compile 
[INFO] | +- javax.validation:validation-api:jar:1.1.0.Final:compile 
[INFO] | +- org.hibernate:hibernate-validator:jar:5.2.2.Final:compile 
[INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile 
[INFO] | | \- com.fasterxml:classmate:jar:1.1.0:compile 
[INFO] | +- javax.el:javax.el-api:jar:2.2.4:compile 
[INFO] | \- org.glassfish.web:javax.el:jar:2.2.4:compile 

ho anche impostare i punti di interruzione all'interno HibernateValidator, e visto che due dei suoi metodi vengono chiamati, così sembra sta funzionando. Solo non convalidante.

EDIT: La mia configurazione maglia

public class JerseyConfig extends ResourceConfig { 

    public JerseyConfig() { 
     register(RequestContextFilter.class); 
     register(LoggingFilter.class); 
     register(JacksonFeature.class); 
     packages("com"); 
    } 
} 
+0

convalida dovrebbe funzionare la casella a meno di scansione META-INF è disabilitato, ma non sembra il caso. Ma se lo è, puoi registrare esplicitamente 'ValidationFeature' con Jersey. Se è già funzionante, e non è solo la risposta che ci si aspetta, è necessario configurare il comportamento del report. Imposta la proprietà 'ServerProperties.BV_SEND_ERROR_IN_RESPONSE' su true in Jersey. A parte questo, non posso riprodurre il comportamento semplicemente semplicemente non funzionante, con quello che hai fornito. –

risposta

0

Nel caso in cui è importante, il mio punto finale è un @Service

tenta di impostare lo stereotipo per @Controller

Controllare se questo bean è definito nella configurazione Web.

@Bean 
    public javax.validation.Validator validator() { 
     return new org.springframework.validation.beanvalidation.LocalValidatorFactoryBean(); 
    } 

controllare anche se la configurazione ha @EnableWebMvc annotazione

+0

Grazie, ma non funziona. Né Component. – mark951131b

+0

ha aggiornato la risposta – WeMakeSoftware

+0

Strano. Se aggiungo Bean, la convalida non funziona neanche. Ma se provo ad Autowire il validatore nel mio endpoint, ottengo 'org.springframework.beans.factory.NoUniqueBeanDefinitionException: Nessun bean qualificante di tipo [javax.validation.Validator] è definito: bean single matching previsto ma trovato 2: localValidatorFactoryBean, mvcValidator' E se rimuovo il bean e lascio Autowire, ottengo 'Nessun bean qualificante di tipo [javax.validation.Validator] trovato per dipendenza' – mark951131b

-1

@ suggerimento di Funtik su rendendolo un @Controller vale la pena provare, ma ho il sospetto il problema è che non stai gestire l'errore nel controller.

Non sono un esperto in questo, quindi consiglio di fare un po 'più di lettura, ma penso che sia necessario aggiungere un BindingResult, che verrà popolato in caso di errori di validazione. Lo verifichi e rispondi in modo appropriato. Quindi, vorrei cambiare il controller a qualcosa di simile:

@POST 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public Response create(@Valid UserDTO userDTO, BindingResult bindingResult, @Context UriInfo uriInfo) { 
    if (bindingResult.hasErrors()) { 
    return Response... // some error code, or however you want to handle validation errors 
    } 

    User user = UserParser.parse(userDTO); 
    userService.save(user); 
    final URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build(); 
    return Response.created(uri).build(); 
} 

Probabilmente non è un problema in questo momento, ma se si aggiunge un parametro annotato @ModelAttribute al metodo, tenere a mente che il parametro BindingResult ha bisogno di apparire immediatamente dopo, altrimenti le cose non funzionano. Non riesco a ricordare il problema esatto che vedi se non lo fai, ma è difficile da trovare se non sai quanto sopra. L'ho sicuramente visto documentato nei documenti di Spring da qualche parte, ma non riesco a trovare nulla di diverso da this forum post in questo momento.

+0

Grazie, ma ho provato anche quello. E anche se ha funzionato, quale no, non mi piace questo approccio, perché poi devo inquinare tutti i miei metodi con questo BindingResult, e ancora peggio, controllare il risultato da solo, che inquina ulteriormente il codice, e che è ciò che le convalide dovrebbero evitare in primo luogo. – mark951131b

+0

Prendo atto che non è elegante come potrebbe essere, ma mi interessa che tu dica che non funziona. In che modo non funziona? Penso che potrebbe aiutarti a trovare la causa principale del tuo problema. – DaveyDaveDave

0

ValidationFeature è auto rilevabile come per jersey 2.0. Non è necessario registrarlo esplicitamente.

Includere il flag, property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true) in jersey resource config per il messaggio di convalida da inviare nella risposta.

Assicurarsi che jersey-bean-validation.jar sia sul classpath (nel tuo caso lo è già).

Semplice esempio,

//Web Resource 
@Path("/accounts") 
public Object getaccount(@Valid @BeanParam AccountRequest); 

public class AccountRequest { 
@NotNull 
private String accountId; 
} 

riferiscono, https://jersey.java.net/documentation/latest/bean-validation.html

0

aggiungere la seguente configurazione per il metodo di JerseyConfig

public JerseyConfig() 
{ 
    register(YourEndpoint.class); 
    property(org.glassfish.jersey.server.ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); 
}