【问题标题】:Spring Boot request validationSpring Boot 请求验证
【发布时间】:2018-06-03 15:51:50
【问题描述】:

我已经阅读了很多关于 Spring 请求验证的内容。我阅读了很多关于如何适当地实现它的文章,但我有一些问题。这是我的代码:

休息控制器:

    @Autowired
EmployeeManager employeeManager;

@Autowired
EmployeeValidator employeeValidator;

@InitBinder("employee")
public void setupBinder(WebDataBinder binder) {
    binder.addValidators(employeeValidator);
}

// -------------- CREATE EMPLOYEES --------------

@PostMapping(value = "add")
public ResponseEntity<EmployeeDTO> addEmployee(@Valid @RequestBody EmployeeDTO employee) {

    boolean isCreated = employeeManager.addEmployee(employee);

    if(isCreated) {
        return new ResponseEntity<>(employee, HttpStatus.CREATED);
    }

    return new ResponseEntity(new CustomError("Unable to create, employee with email " +
            employee.getEmail() + " already exist."), HttpStatus.CONFLICT);
}

验证器:

    package com.employee.api.EmployeeAPI.validator;


import com.employee.api.EmployeeAPI.model.dto.EmployeeDTO;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class EmployeeValidator implements Validator {

    private Pattern pattern;
    private Matcher matcher;

    private static final String STRING_PATTERN = "[a-zA-Z]+";
    private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
            + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

    @Override
    public boolean supports(Class<?> clazz) {
        return EmployeeDTO.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        EmployeeDTO employee = (EmployeeDTO) target;
        if (validateInputString(employee.getFirstName(), STRING_PATTERN)) {
            errors.rejectValue("firstName", "firstName.invalid");
        }

        if (validateInputString(employee.getLastName(), STRING_PATTERN)) {
            errors.rejectValue("lastName", "lastName.invalid");
        }

        if (validateInputString(employee.getJob(), STRING_PATTERN)) {
            errors.rejectValue("job", "job.invalid");
        }

        if (validateInputString(employee.getEmail(), EMAIL_PATTERN)) {
            errors.rejectValue("email", "email.invalid");
        }
    }

    private boolean validateInputString(String input, String regexPattern) {
        pattern = Pattern.compile(regexPattern);
        matcher = pattern.matcher(input);

        return (!matcher.matches() || input == null || input.trim().length() == 0);
    }

}

在配置中我添加了 bean:

@Bean
public EmployeeValidator beforeAddOrUpdateEmployeeValidator() {
    return new EmployeeValidator();
}

我不确定现在在添加员工时应该如何调用它,因为它现在肯定不起作用。您能否帮助我正确实施或指出正确的方向?

【问题讨论】:

    标签: spring validation spring-boot spring-validator


    【解决方案1】:

    我不熟悉 org.springframework.validation.Validator,但会建议您如何使用 javax.validation.ConstraintValidator (JSR-303) 进行所需的相同验证。您的控制器类很好,不需要更改。

    您需要创建一个自定义注释 @ValidEmployee 并用它来注释您的 dto:

    @ValidEmployee
    public class EmployeeDto {
        ...
    }
    

    有效的员工注释:

    import javax.validation.Constraint;
    import javax.validation.Payload;
    
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Constraint(validatedBy = EmployeeValidator.class)
    @Documented
    public @interface ValidEmployee {
        String message() default "{ValidEmployee.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    并在 isValid 方法中实现您的验证逻辑:

    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    public class EmployeeValidator implements ConstraintValidator<ValidEmployee, EmployeeDto> {
    
        @Override
        public void initialize(ValidEmployee constraintAnnotation) {
        }
    
        @Override
        public boolean isValid(EmployeeDto employee, ConstraintValidatorContext context) {
                // do your validation logic
        }
    
    }
    

    【讨论】:

    • 感谢您的回答。我看到验证器 bean 是在请求​​期间创建的。作为优化的一部分,我可以在启动时执行此验证器吗?我正在尝试减少查询所需的响应时间。
    猜你喜欢
    • 2020-10-18
    • 1970-01-01
    • 2020-03-14
    • 2018-08-08
    • 2018-12-05
    • 1970-01-01
    • 2023-04-05
    • 2020-02-17
    • 2021-08-09
    相关资源
    最近更新 更多