pba*_*ski 3 java validation model-view-controller spring
如果有可能针对不同的控制器方法定制验证器,我想获得这种验证方法的答案。
简单验证器
@Component
public class UserDtoValidator implements Validator {
@Autowired
UserService userService;
@Override
public boolean supports(Class<?> aClass) {
return UserDto.class.isAssignableFrom(aClass);
}
@Override
public void validate(Object target, Errors errors) {
UserDto userDto = (UserDto) target;
}
//how to make 'if' below to be applied only for certain method in controller
//in this case for controller createUser method
if (userService.findByUserName(userDto.getUserName())!=null) {
throw new InvalidPayloadException("Creating user requires unique userName");
}
//second 'if' for controller updateUser method
if (userService.findByUserName(userDto.getUserName())==null) {
throw new InvalidPayloadException("Updating unexisting users is not allowed");
}
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
在这里,验证器有两种相反的情况:
1使用唯一的用户名创建用户
2更新用户-必需的用户名
@Controller
@RequestMapping(value = "/api/users")
public class ApiUserController extends ExceptionsResolver {
@Autowired
private UserService userService;
@Autowired
private UserDtoValidator userDtoValidator;
@InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(userDtoValidator);
}
@RequestMapping(consumes = "application/json", produces = "application/json", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity createUser(@Valid @RequestBody UserDto userDto) throws JsonProcessingException {
userService.saveUser(userDto);
return new ResponseEntity(userDto, HttpStatus.ACCEPTED);
}
@RequestMapping(value = "/{userName}", consumes = "application/json", method = RequestMethod.PUT)
@ResponseBody
public ResponseEntity<UserDto> updateUser(@Valid @RequestBody UserDto userDto, @PathVariable String userName) {
return new ResponseEntity("User updated", HttpStatus.ACCEPTED);
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我知道PUT应该创建新的,但是在这里我只需要PUT即可进行更新。
您真正关心的是用户名是否存在。在某些情况下,您希望这样做,在某些情况下,您则不需要。
理论上,您可以使用@Username带有exists属性的注释。这与Adi的相似isUpdate,但不要称之为isUpdate。您不在乎需要验证的操作,仅在乎用户名是否存在。
验证组是针对此问题而设计的,即在不同情况下以不同的方式验证bean。创建两个验证组NewUser和ExistingUser。将@Valid您的通话替换为@ControllerSpring的@Validated。
public ResponseEntity createUser(@Validated(NewUser.class) @RequestBody UserDto userDto) throws JsonProcessingException {}
public ResponseEntity<UserDto> updateUser(@Validated(ExistingUser.class) @RequestBody UserDto userDto, @PathVariable String userName) {}
Run Code Online (Sandbox Code Playgroud)
在UserDto课堂上,理论上您会将该username属性标记为
@Username(exists = true, groups = ExistingUser.class);
@Username(exists = false, groups = NewUser.class);
public String getUsername() {}
Run Code Online (Sandbox Code Playgroud)
但是Java不允许您这样做。因此,您需要一种变通方法来设置多个用户名约束。在Bean验证API中的所有位置都使用了此功能,例如NotNull
/**
* Defines several <code>@NotNull</code> annotations on the same element
* @see javax.validation.constraints.NotNull
*
* @author Emmanuel Bernard
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@interface List {
NotNull[] value();
}
Run Code Online (Sandbox Code Playgroud)
有了这些东西之后,您只需要一个UsernameValidator可以根据exists标志检查用户名是否存在的验证器,其余的将由验证组负责。
| 归档时间: |
|
| 查看次数: |
4019 次 |
| 最近记录: |