spring
Spring JSR 303 Boonvalidatie
Zoeken…
Invoering
Spring heeft JSR303 bonenvalidatie-ondersteuning. We kunnen dit gebruiken om input bean validatie te doen. Afzonderlijke validatielogica van bedrijfslogica met JSR303.
JSR303 Op annotaties gebaseerde validaties in Springs-voorbeelden
Voeg elke JSR 303-implementatie toe aan uw klassenpad. De meest gebruikte is de slaapstand-validator van de slaapstand.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
Laten we zeggen dat er een rest-API is om een gebruiker in het systeem te maken
@RequestMapping(value="/registeruser", method=RequestMethod.POST)
public String registerUser(User user);
Het input-json-monster ziet er als volgt uit
{"username" : "[email protected]", "password" : "password1", "password2":"password1"}
User.java
public class User {
private String username;
private String password;
private String password2;
getXXX and setXXX
}
We kunnen JSR 303-validaties voor gebruikersklasse definiëren zoals hieronder.
public class User {
@NotEmpty
@Size(min=5)
@Email
private String username;
@NotEmpty
private String password;
@NotEmpty
private String password2;
}
Mogelijk hebben we ook een zakelijke validator nodig, zoals wachtwoord en wachtwoord2 (wachtwoord bevestigen), hiervoor kunnen we een aangepaste validator toevoegen, zoals hieronder. Schrijf een aangepaste annotatie voor het annoteren van het gegevensveld.
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface GoodPassword {
String message() default "Passwords wont match.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Schrijf een Validator-klasse voor het toepassen van Validatielogica.
public class PastValidator implements ConstraintValidator<GoodPassword, User> {
@Override
public void initialize(GoodPassword annotation) {}
@Override
public boolean isValid(User user, ConstraintValidatorContext context) {
return user.getPassword().equals(user.getPassword2());
}
}
Deze validatie toevoegen aan gebruikersklasse
@GoodPassword
public class User {
@NotEmpty
@Size(min=5)
@Email
private String username;
@NotEmpty
private String password;
@NotEmpty
private String password2;
}
@Valid activeert validatie in het voorjaar. BindingResult is een object geïnjecteerd door de lente dat na validatie een lijst met fouten bevat.
public String registerUser(@Valid User user, BindingResult result);
JSR 303-annotatie heeft berichtattributen die kunnen worden gebruikt voor het aanbieden van aangepaste berichten.
@GoodPassword
public class User {
@NotEmpty(message="Username Cant be empty")
@Size(min=5, message="Username cant be les than 5 chars")
@Email(message="Should be in email format")
private String username;
@NotEmpty(message="Password cant be empty")
private String password;
@NotEmpty(message="Password2 cant be empty")
private String password2;
}
Spring JSR 303 Validation - Foutmeldingen aanpassen
Stel dat we een eenvoudige klasse hebben met validatieaantekeningen
public class UserDTO {
@NotEmpty
private String name;
@Min(18)
private int age;
//getters/setters
}
Een controller om de geldigheid van de UserDTO te controleren.
@RestController
public class ValidationController {
@RequestMapping(value = "/validate", method = RequestMethod.POST)
public ResponseEntity<String> check(@Valid @RequestBody UserDTO userDTO,
BindingResult bindingResult) {
return new ResponseEntity<>("ok" , HttpStatus.OK);
}
}
En een test.
@Test
public void testValid() throws Exception {
TestRestTemplate template = new TestRestTemplate();
String url = base + contextPath + "/validate";
Map<String, Object> params = new HashMap<>();
params.put("name", "");
params.put("age", "10");
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/json");
HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, headers);
String res = template.postForObject(url, request, String.class);
assertThat(res, equalTo("ok"));
}
Zowel naam als leeftijd zijn ongeldig, dus in het BindingResult hebben we twee validatiefouten. Elk heeft een reeks codes.
Codes voor Min check
0 = "Min.userDTO.age"
1 = "Min.age"
2 = "Min.int"
3 = "Min"
En voor NotEmpty check
0 = "NotEmpty.userDTO.name"
1 = "NotEmpty.name"
2 = "NotEmpty.java.lang.String"
3 = "NotEmpty"
Laten we een bestand custom.properties toevoegen om standaardberichten te vervangen.
@SpringBootApplication
@Configuration
public class DemoApplication {
@Bean(name = "messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.setBasename("classpath:custom");
bean.setDefaultEncoding("UTF-8");
return bean;
}
@Bean(name = "validator")
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Als we de regel toevoegen aan het bestand custom.properties
NotEmpty=The field must not be empty!
De nieuwe waarde wordt weergegeven voor de fout. Om het bericht op te lossen, kijkt u door de codes vanaf het begin om de juiste berichten te vinden.
Dus wanneer we de NotEmpty
sleutel in het .properties-bestand definiëren voor alle gevallen waarin de annotatie @NotEmpty
wordt gebruikt, wordt ons bericht toegepast.
Als we een bericht definiëren
Min.int=Some custom message here.
Alle annotaties waarbij we min controleren op gehele getallen gebruiken het nieuw gedefinieerde bericht.
Dezelfde logica zou kunnen worden toegepast als we de validatiefoutmeldingen moeten lokaliseren.
@Geldig gebruik om geneste POJO's te valideren
Stel dat we een POJO-klasse gebruiker hebben die we moeten valideren.
public class User {
@NotEmpty
@Size(min=5)
@Email
private String email;
}
en een controller-methode om het gebruikersexemplaar te valideren
public String registerUser(@Valid User user, BindingResult result);
Laten we de gebruiker uitbreiden met een genest POJO-adres dat we ook moeten valideren.
public class Address {
@NotEmpty
@Size(min=2, max=3)
private String countryCode;
}
Voeg gewoon @Valid
annotation on address field toe om validatie van geneste POJO's uit te voeren.
public class User {
@NotEmpty
@Size(min=5)
@Email
private String email;
@Valid
private Address address;
}