spring
Spring JSR 303 Bean Validation
Sök…
Introduktion
Våren har JSR303 bönvalideringsstöd. Vi kan använda detta för att göra inmatning av bönor validering. Separat valideringslogik från affärslogik med JSR303.
JSR303 Annoteringsbaserade valideringar i Springs-exempel
Lägg till JSR 303-implementering till din klassväg. Den populära som används är viloläge-validerare från Hibernate.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
Låt oss säga att det finns ett vilopi för att skapa användare i systemet
@RequestMapping(value="/registeruser", method=RequestMethod.POST)
public String registerUser(User user);
Input-json-exemplet skulle se ut som nedan
{"username" : "[email protected]", "password" : "password1", "password2":"password1"}
User.java
public class User {
private String username;
private String password;
private String password2;
getXXX and setXXX
}
Vi kan definiera JSR 303-valideringar i User Class enligt nedan.
public class User {
@NotEmpty
@Size(min=5)
@Email
private String username;
@NotEmpty
private String password;
@NotEmpty
private String password2;
}
Vi kan också behöva ha en affärsvaliderare som lösenord och lösenord2 (bekräfta lösenord) är samma, för detta kan vi lägga till en anpassad validerare som nedan. Skriv en anpassad kommentar för att kommentera datafältet.
@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 {};
}
Skriv en Validator-klass för att tillämpa Validation-logik.
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());
}
}
Lägger till denna validering i User Class
@GoodPassword
public class User {
@NotEmpty
@Size(min=5)
@Email
private String username;
@NotEmpty
private String password;
@NotEmpty
private String password2;
}
@Valid utlöser validering under våren. BindingResult är ett objekt som injiceras av våren som har en lista över fel efter validering.
public String registerUser(@Valid User user, BindingResult result);
JSR 303-kommentaren har meddelandeattribut på dem som kan användas för att tillhandahålla anpassade meddelanden.
@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 - Anpassa felmeddelanden
Anta att vi har en enkel klass med valideringsanteckningar
public class UserDTO {
@NotEmpty
private String name;
@Min(18)
private int age;
//getters/setters
}
En controller för att kontrollera UserDTO-giltigheten.
@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);
}
}
Och ett 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"));
}
Både namn och ålder är ogiltiga, så i BindingResultat har vi två valideringsfel. Var och en har en rad koder.
Koder för Min-check
0 = "Min.userDTO.age"
1 = "Min.age"
2 = "Min.int"
3 = "Min"
Och för NotEmpty check
0 = "NotEmpty.userDTO.name"
1 = "NotEmpty.name"
2 = "NotEmpty.java.lang.String"
3 = "NotEmpty"
Låt oss lägga till en anpassad.properties-fil för att ersätta standardmeddelanden.
@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);
}
}
Om vi lägger till filen custom.properties-filen
NotEmpty=The field must not be empty!
Det nya värdet visas för felet. För att lösa meddelandevaliderare tittar du igenom koderna från början för att hitta rätt meddelanden.
Så när vi definierar NotEmpty
nyckeln i .properties-filen för alla fall där @NotEmpty
anteckningen används används vårt meddelande.
Om vi definierar ett meddelande
Min.int=Some custom message here.
Alla kommentarer där vi app min kontroll för heltal värden använder det nyligen definierade meddelandet.
Samma logik kan tillämpas om vi måste lokalisera valideringsfelmeddelandena.
@ Giltig användning för att validera kapslade POJO: er
Anta att vi har en POJO-klassanvändare som vi behöver validera.
public class User {
@NotEmpty
@Size(min=5)
@Email
private String email;
}
och en styrmetod för att validera användarinstansen
public String registerUser(@Valid User user, BindingResult result);
Låt oss utöka användaren med en kapslad POJO-adress som vi också behöver validera.
public class Address {
@NotEmpty
@Size(min=2, max=3)
private String countryCode;
}
Lägg bara till @Valid
annotation i adressfältet för att köra validering av kapslade POJO: er.
public class User {
@NotEmpty
@Size(min=5)
@Email
private String email;
@Valid
private Address address;
}