Validering i vårstøvel

1. Oversikt

Når det gjelder validering av brukerinngang, gir Spring Boot sterk støtte for denne vanlige, men kritiske, oppgaven rett ut av esken.

Selv om Spring Boot støtter sømløs integrasjon med tilpassede validatorer, de facto-standarden for å utføre validering er Hibernate Validator, Bean Validation framework's referanseimplementering.

I denne veiledningen, vi vil se på hvordan du validerer domenegen objekter i Spring Boot.

2. Maven-avhengighetene

I dette tilfellet lærer vi hvordan vi validerer domeneobjekter i Spring Boot ved å bygge en grunnleggende REST-kontroller.

Kontrolleren vil først ta et domeneobjekt, deretter vil det validere det med Hibernate Validator, og til slutt vil det fortsette det til en H2-database i minnet.

Prosjektets avhengighet er ganske standard:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 1.4.197 runtime 

Som vist ovenfor inkluderte vi spring-boot-starter-web i vår pom.xml fil fordi vi trenger den for å opprette REST-kontrolleren. I tillegg, la oss sørge for å sjekke de nyeste versjonene av spring-boot-starter-jpa og H2-databasen på Maven Central.

Fra og med Boot 2.3, må vi også eksplisitt legge til vår-boot-starter-validering avhengighet:

 org.springframework.boot spring-boot-starter-validering 

3. En enkel domene klasse

Med prosjektets avhengigheter allerede på plass, må vi neste definere et eksempel på JPA-enhetsklasse, hvis rolle bare vil være modellering av brukere.

La oss ta en titt på denne klassen:

@Entity offentlig klasse bruker {@Id @GeneratedValue (strategi = GenerationType.AUTO) privat lang id; @NotBlank (message = "Navn er obligatorisk") privat strengnavn; @NotBlank (message = "E-post er obligatorisk") privat streng e-post; // standard konstruktører / settere / getters / toString}

Gjennomføringen av vår Bruker enhetsklasse er ganske anemisk, men den viser i et nøtteskall hvordan du bruker Bean Validation's begrensninger for å begrense Navn og e-post Enger.

For enkelhets skyld begrenset vi målfeltene med bare @NotBlank begrensning. Vi spesifiserte også feilmeldingene med beskjed Egenskap.

Derfor, når Spring Boot validerer klasseinstansen, de begrensede feltene må ikke være null og den trimmede lengden må være større enn null.

I tillegg gir Bean Validation mange andre nyttige begrensninger i tillegg @NotBlank. Dette gjør at vi kan bruke og kombinere forskjellige valideringsregler til de begrensede klassene. For mer informasjon, vennligst les de offisielle dokumentene for validering av bønner.

Siden vi bruker Spring Data JPA for å lagre brukere i H2-databasen i minnet, må vi også definere et enkelt repositorgrensesnitt for å ha grunnleggende CRUD-funksjonalitet på Bruker gjenstander:

@Repository offentlig grensesnitt UserRepository utvider CrudRepository {}

4. Implementering av en REST-kontroller

Selvfølgelig må vi implementere et lag som lar oss få verdiene tildelt våre Bruker objektets begrensede felt.

Derfor kan vi validere dem og utføre noen flere oppgaver, avhengig av valideringsresultatene.

Spring Boot gjør denne tilsynelatende komplekse prosessen veldig enkel gjennom implementeringen av en REST-kontroller.

La oss se på implementeringen av REST-kontrolleren:

@RestController offentlig klasse UserController {@PostMapping ("/ brukere") ResponseEntity addUser (@Valid @RequestBody brukerbruker) {// vedvarer brukeren returnere ResponseEntity.ok ("Brukeren er gyldig"); } // standardkonstruktører / andre metoder} 

I en vår-REST-sammenheng implementeringen av addUser () metoden er ganske standard.

Selvfølgelig er den mest relevante delen bruken av @Gyldig kommentar.

Når Spring Boot finner et argument kommentert med @Gyldig, den starter automatisk JSR 380-implementeringen - Hibernate Validator - og validerer argumentet.

Når målargumentet ikke klarer valideringen, kaster Spring Boot a MethodArgumentNotValidException unntak.

5. Den @ExceptionHandler Kommentar

Selv om det er veldig praktisk å ha Spring Boot som validerer Bruker gjenstand sendt videre til addUser () metode automatisk, er den manglende siden av denne prosessen hvordan vi behandler valideringsresultatene.

De @ExceptionHandler kommentar lar oss håndtere spesifiserte typer unntak gjennom en enkelt metode.

Derfor kan vi bruke den til å behandle valideringsfeilene:

@ResponseStatus (HttpStatus.BAD_REQUEST) @ExceptionHandler (MethodArgumentNotValidException.class) public Map handleValidationExceptions (MethodArgumentNotValidException ex) {Map feil = ny HashMap (); ex.getBindingResult (). getAllErrors (). forEach ((error) -> {String fieldName = ((FieldError) error) .getField (); String errorMessage = error.getDefaultMessage (); errors.put (fieldName, errorMessage); }); returfeil; }

Vi spesifiserte MethodArgumentNotValidException unntak som unntak som skal håndteres. Følgelig vil Spring Boot kalle denne metoden når den angitte Bruker objektet er ugyldig.

Metoden lagrer navnet og ettervalideringsfeilmeldingen til hvert ugyldige felt i a Kart. Neste sender den Kart tilbake til klienten som en JSON-representasjon for videre behandling.

Enkelt sagt, REST-kontrolleren lar oss enkelt behandle forespørsler til forskjellige sluttpunkter, validere Bruker objekter, og send svarene i JSON-format.

Designet er fleksibelt nok til å håndtere kontrollerresponser gjennom flere nettnivåer, alt fra malmotorer som Thymeleaf, til et fullverdig JavaScript-rammeverk som Angular.

6. Testing av REST-kontrolleren

Vi kan enkelt teste funksjonaliteten til REST-kontrolleren vår med en integrasjonstest.

La oss begynne å håne / autolading av UserRepository grensesnitt implementering, sammen med UserController eksempel, og en MockMvc gjenstand:

@RunWith (SpringRunner.class) @WebMvcTest @ AutoConfigureMockMvc public class UserControllerIntegrationTest {@MockBean private UserRepository userRepository; @Autowired UserController userController; @Autowired privat MockMvc mockMvc; // ...} 

Siden vi bare tester nettlaget, bruker vi @WebMvcTest kommentar. Det lar oss enkelt teste forespørsler og svar ved hjelp av settet med statiske metoder implementert av MockMvcRequestBuilders og MockMvcResultMatchers klasser.

La oss nå teste addUser () metode med en gyldig og en ugyldig Bruker objekt sendt i anmodningsorganet:

@Test offentlig ugyldig når PostRequestToUsersAndValidUser_thenCorrectResponse () kaster unntak {MediaType textPlainUtf8 = ny MediaType (MediaType.TEXT_PLAIN, Charset.forName ("UTF-8")); Strengbruker = "{\" navn \ ": \" bob \ ", \" e-post \ ": \" [e-postbeskyttet] \ "}"; mockMvc.perform (MockMvcRequestBuilders.post ("/ users") .content (user) .contentType (MediaType.APPLICATION_JSON_UTF8)). andExpect (MockMvcResultMatchers.status (). isOk ()). andExpect (MockMvcent. textPlainUtf8)); } @Test offentlig ugyldig når PostRequestToUsersAndInValidUser_thenCorrectResponse () kaster unntak {String bruker = "{\" navn \ ": \" \ ", \" e-post \ ": \" [e-postbeskyttet] \ "}"; mockMvc.perform (MockMvcRequestBuilders.post ("/ users") .content (user) .contentType (MediaType.APPLICATION_JSON_UTF8)). andExpect (MockMvcResultMatchers.status (). isBadRequest ()) .andExpect (MockMat. ", Is.is (" Navn er obligatorisk "))). OgExpect (MockMvcResultMatchers.content () .contentType (MediaType.APPLICATION_JSON_UTF8)); }} 

I tillegg kan vi teste REST controller API bruker en gratis applikasjon for testing av livssyklus for API, som Postman.

7. Kjøre prøveprogrammet

Til slutt kan vi kjøre eksempelprosjektet vårt med en standard hoved() metode:

@SpringBootApplication public class Application {public static void main (String [] args) {SpringApplication.run (Application.class, args); } @Bean offentlig CommandLineRunner-kjøring (UserRepository userRepository) kaster Unntak {retur (String [] args) -> {User user1 = new User ("Bob", "[email protected]"); Bruker bruker2 = ny bruker ("Jenny", "[e-postbeskyttet]"); userRepository.save (user1); userRepository.save (user2); userRepository.findAll (). forEach (System.out :: println); }; }} 

Som forventet, bør vi se et par Bruker gjenstander som er skrevet ut i konsollen.

En POST-forespørsel til // localhost: 8080 / brukere sluttpunkt med et gyldig Bruker objektet vil returnere String “Brukeren er gyldig”.

Likeledes en POST-forespørsel med en Bruker objekt uten Navn og e-post verdiene vil returnere følgende svar:

{"name": "Navn er obligatorisk", "email": "E-post er obligatorisk"}

8. Konklusjon

I denne artikkelen, vi lærte det grunnleggende om å utføre validering i Spring Boot.

Som vanlig er alle eksemplene vist i denne artikkelen tilgjengelig på GitHub.