오늘은 검증 로직을 살짝 다듬어주었다. 전에는 완전하게 적용을 하지 않아서 엉망이었는데 오늘 다 정리해 버렸다. 이해가 잘 안 되는 부분이 있어서 하루 종일 찾아보다 저녁 되서야 완성시키고 로직 정리를 했다.
내용은 아래와 같다.
@PostMapping("/user/regUser/insert")
public String InsertRegUser(@Validated @ModelAttribute UserVo userVo, BindingResult bindingResult) throws Exception{
log.info(this.getClass().getName() + "회원가입 로직 처리 시작");
if (bindingResult.hasErrors()) {
log.info(" 회원가입 로직 처리 중 Errors 처리 bindingResult ={}", bindingResult);
return "user/regUser";
}
UserDTO userDTO = new UserDTO(userVo.getUserNo(), userVo.getUserName(), userVo.getUserPn(), userVo.getUserEmail(), userVo.getUserId(), userVo.getUserPw(), userVo.getUserAddr());
log.info("UserDTO ={}", userDTO);
userService.InsertUser(userDTO);
return "/user/logIn";
}
회원가입 기능을 만들면서 Controller에 다 떄려 넣은 검증 로직을 따로 빼서 관리하기로 했다.
그 결과 Controller가 깔끔해지고 있는 중이다.
<div class="form-floating">
<input th:type="text" id="userName" th:field="*{userName}" th:errorclass="field-error" th:class="form-control" placeholder="이름">
<label for="userName" th:text="#{label.userVo.userName}">이름</label>
<div th:class="field-error" th:errors="*{userName}">이름 오류</div>
</div>
프론트를 먼저 보면 label에 th:text="#{label.userVo.userName}" 코드를 추가해 주었다.
label.userVo.userName=이름을 입력해주세요.
label.userVo.userPn=휴대폰 번호를 입력해주세요.
label.userVo.userEmail=이메일을 입력해주세요.
label.userVo.userId=아이디를 입력해주세요.
label.userVo.userPw=비밀번호를 입력해주세요.
label.userVo.userAddr=주소를 입력해주세요.
errors.properties를 만들어 주었다. messages.properties에서 관리해도 되는데 일반 메시지랑 오류랑 구분하는 게 좋을 것 같아서 따로 빼서 관리했다.
# error 메시지 파일 생성 및 등록
spring.messages.basename=messages,errors
application.properties에서 errors.properties를 등록해주었다. 원래는 기본 값으로 messages를 사용하는데 기본 메시지랑 에러 메시지랑 구분하기 위해 따로 errors.properties를 만들어 주었으므로 위 코드처럼 설정해 주어야 한다.
@Slf4j
@Component
public class UserValidator implements Validator {
먼저 UserValidator를 만들어주고 Validator를 구현했다.
Validator interface는 2개의 메소드를 지원한다.
boolean supports(Class<?> clazz); 와 void validate(Object target, Errors errors); 를 지원하고 있다.
@Override
public boolean supports(Class<?> clazz) {
return UserVo.class.isAssignableFrom(clazz);
}
supports에서 UserVo (View에서 회원가입 정보를 가지고 오는 Model 객체)를 리턴한다.
아직 supports를 제대로 사용해 보지는 못 했는데 만약 여러 검증이 있을 때 supports에서 해당 검증에 맞는 객체가 들어왔는지 체크한다고 한 것 같다. 즉, 들어온 객체가 검증 대상 타입인지 체크를 한다.
아직 추가로 공부가 필요한 부분인데 아마 로그인 검증을 짤 때 사용하지 않을까 싶다.
@Override
public void validate(Object target, Errors errors) {
UserVo userVo = (UserVo) target;
/**
* 1. @Valid 검증 로직 실행
*/
if (!StringUtils.hasText(userVo.getUserName())) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "label");
}
if (!StringUtils.hasText(userVo.getUserPn())) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userPn", "label");
}
if (!StringUtils.hasText(userVo.getUserEmail())) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userEmail", "label");
}
if (!StringUtils.hasText(userVo.getUserId())) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userId", "label");
}
if (!StringUtils.hasText(userVo.getUserPw())) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userPw", "label");
}
if (!StringUtils.hasText(userVo.getUserAddr())) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userAddr", "label");
}
}
validate 메소드는 파라미터로 target을 사용하는데 검증 값을 담고있는 userVo를 target으로 등록해 검증해야 할 객체임을 알게 해 준다.
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "label"); userName 검증만 보면 처음에는 errors와 필드, 에러코드를 적게 되어있다. 여기에 들어가는 에러 코드는 아래를 참고한다.
label.userVo.userName=이름을 입력해주세요.
errors.properties에서 정의한 에러 코드를 가지고 온다. 이 에러 코드는 View에서 설정한 것과 일치한다.
<div class="form-floating">
<input th:type="text" id="userName" th:field="*{userName}" th:errorclass="field-error" th:class="form-control" placeholder="이름">
<label for="userName" th:text="#{label.userVo.userName}">이름</label>
<div th:class="field-error" th:errors="*{userName}">이름 오류</div>
</div>
<label for="userName" th:text="#{label.userVo.userName}">이름</label> th:text로 에러 코드를 적어주었다. 검증에 걸리면 여기에 errors.properties에서 설정한 labe.userVo.uerName 에러 코드가 나오게 된다.
에러 코드는 이름을 입력해주세요.라고 적어두었다.
<style>
.field-error {
border-color: #dc3545;
color: #dc3545;
}
</style>
에러 코드가 눈에 잘 안 띄어서 빨간색 컬러를 넣어주었다.
@Slf4j
@Controller
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
private final UserValidator userValidator;
@InitBinder
public void init(WebDataBinder dataBinder) {
log.info("init binder {}", dataBinder);
dataBinder.addValidators(userValidator);
}
@RequiredArgsConstructor를 사용해서 단일 생성자인 경우 파라미터 값이 여러개라도 @Autowired 를 사용하지 않아도 되도록 설정해 주었고 private final UserValidator userValidator;를 등록해 주었다.
@InitBinder 를 통해서 해당 Controller에서 @Validated 어노테이션이 있는 곳이 검증 로직을 거쳐가도록 설정해 주었다.
이렇게 회원가입에 대한 검증 처리는 마쳤고, 로그인 처리는 찾아보니 몇 가지 방법이 있는 것 같다.
groups를 사용하거나 전송 객체를 분리하거나인데 가능하면 객체 분리식으로 사용하려고 한다. (로그인 검증을 하기 위해서 사용하는 게 아니라 회원가입, 로그인이 서로 다른 검증이 들어가야 하기 때문에 선택지가 늘어난 것이다.)
'Project > 소경관' 카테고리의 다른 글
[소경관] : Apache poi 라이브러리를 사용하여 View에서 Excel 파일 읽어 저장하기 (0) | 2022.04.30 |
---|---|
[소경관] : 카카오 주소 API 사용하기 (0) | 2022.04.21 |
[소경관] : Filter 적용하여 미인증 사용자 체크하기 (0) | 2022.04.17 |
[소경관] : Session으로 logout 구현하기 (0) | 2022.04.17 |
[소경관] : Session 적용하기 (0) | 2022.04.17 |
댓글