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;
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow