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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow