我有用户实体,其用户名字段由@UniqueUsername
验证注释。在控制器中接收请求时,我使用@Valid
注释进行验证。当我创建用户时,这非常有效。但是,我在编辑现有用户时遇到了问题,因为我无法让 spring 忽略@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 {};
}
唯一用户名验证器
@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)
为了获取路径变量是否在UniqueUsernameValidator
内id
,您可以执行以下操作:
@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
并专门针对更新案例执行检查。希望这有帮助!