在Spring中是否可以跳过注释验证

时间:2020-06-16 13:44:34

标签: java spring spring-boot hibernate validation

我有一个用户实体,其用户名字段由@UniqueUsername验证注释。在控制器中接收请求时,我使用@Valid批注进行验证。当我创建用户时,这完美地工作。但是,我在编辑现有用户时遇到了问题,因为我无法冒充忽略@UniqueUsername,所以每次编辑都会失败。在编辑/更新用户信息时,有什么办法让弹簧忽略@UniqueUsername

这是我的简化代码:

用户

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    //my custom validator
    @UniqueUsername
    private String username;
    public int getId() {
    return id;

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

唯一用户名

@Constraint(validatedBy = UniqueUsernameValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueUsername {
    String message() default "Username already exists";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

UniqueUsernameValidator

@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void initialize(UniqueUsername username) {
    }

    @Override
    public boolean isValid(String username, ConstraintValidatorContext context) {
        return !userDetailsService.isUsernameAlreadyInUse(username);
    }
}

控制器中的方法如下:

public String updateUser(@PathVariable("id") int id, @Valid User user, BindingResult result, Model model) 

1 个答案:

答案 0 :(得分:1)

为了获取是否id中的路径变量UniqueUsernameValidator,您可以执行以下操作:

@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void initialize(UniqueUsername username) {
    }

    @Override
    public boolean isValid(String username, ConstraintValidatorContext context) {
        Map<String, String> uriVars = (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);

        if (uriVars != null) {
          String idStr = uriVars.get("id");

          if (idStr != null) {
            int id = Integer.valueOf(ValidationUtils.getPathVariable(request, "id"));

            return !userDetailsService.isUserNameAlreadyInUseForAnotherId(userName, id);
          }
        }

        return !userDetailsService.isUsernameAlreadyInUse(username);
    }
}

您可以从注入的HttpServletRequest获取路径变量,并实现新的服务方法isUserNameAlreadyInUseForAnotherId并针对更新情况进行检查。希望这会有所帮助!

相关问题