WebDataBinder는 매개변수 바인딩의 역할을 한다. 또한 내부에 검증 기능을 포함하고 있다. 먼저 타입 변환을 해주고 그 후에 데이터 검증을 실시 하며, 변환 결과나 에러는 Errors에 저장한다.
@Controller
@RequiredArgsConstructor
public class AccountController {
...
@InitBinder("signUpForm")
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.addValidators(signUpFormValidator);
}
...
@PostMapping("/sign-up")
public String signUpSubmit(@Valid @ModelAttribute SignUpForm signUpForm, Errors errors, Model model) {
if (errors.hasErrors()) {
return "account/sign-up";
}
...
}
}
package com.example.account;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@Component
@RequiredArgsConstructor
public class SignUpFormValidator implements Validator {
private final AccountRepository accountRepository;
@Override
public boolean supports(Class<?> clazz) {
//SignUpForm == clazz
//SignUpForm == subItem 자손 객체도 넘어올 수 있음
return clazz.isAssignableFrom(SignUpForm.class);
}
@Override
public void validate(Object target, Errors errors) {
SignUpForm signUpForm = (SignUpForm) target;
if (accountRepository.existsByEmail(signUpForm.getEmail())) {
errors.rejectValue("email", "invalid.email", new Object[]{signUpForm.getEmail()}, "이미 사용중인 이메일입니다.");
}
if (accountRepository.existsByNickname(signUpForm.getNickname())) {
errors.rejectValue("nickname", "invalid.nickname", new Object[]{signUpForm.getNickname()}, "이미 사용중인 닉네임입니다.");
}
}
}
모든 컨트롤러에 적용하고 싶으면 WebMvcConfigurer 인터페이스를 구현하면 된다.
@SpringBootApplication
public class App implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(ItemServiceApplication.class, args);
}
@Override
public Validator getValidator() {
return new SignUpFormValidator();
}
}
package com.example.account;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@Data
public class SignUpForm {
@NotBlank
@Length(min = 3, max = 20)
@Pattern(regexp = "^[ㄱ-ㅎ가-힣a-z0-9_-]{3,20}$")
private String nickname;
@Email
@NotBlank
private String email;
@NotBlank
@Length(min = 8, max = 50)
private String password;
}
<div class="form-group">
<label for="nickname">닉네임</label>
<input id="nickname" type="text" th:field="*{nickname}" class="form-control">
<small class="form-text text-danger" th:if="${#fields.hasErrors('nickname')}" th:errors="*{nickname}">Nickname Error</small>
</div>
참조
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2