로그인/회원가입 입력 폼 예외 처리
회원가입 페이지에 들어가서 아이디/비밀번호/닉네임을 입력하면 새로운 유저가 유저DB에 등록되고 다시 로그인 페이지에서 로그인이 가능하다. 하지만 회원가입/로그인 과정에서 유저의 입력으로 인한 예외가 발생할 수 있고, 해당 예외에 대한 메세지를 유저에게 보내고 내부에서 처리해야 한다.
유저 입력에 의해 발생하는 예외들
회원가입 과정에서 발생하는 예외들
- 입력창을 공백 상태로 등록을 하려는 경우
- 입력한 아이디가 이미 존재하는 경우
- 비밀번호와 비밀번호 확인이 일치하지 않는 경우
- 입력한 닉네임이 이미 존재하는 경우
로그인 과정에서 발생하는 예외들
- 아이디 또는 비밀번호를 입력해 로그인에 실패하는 경우
- 입력창을 공백 상태로 로그인한 경우
유저에게 예외 알리기
유저의 입력에 의한 예외 발생시, 그 사실을 유저에게 알려 유저의 입력이 수정되도록 해야 한다.
1. Alert 창 사용
처음 개발 시, 로그인/회원가입시 예외가 발생할 경우, 해당 페이지를 다시 리다이랙션하고, Alert 창을 띄우려고 했다. 하지만 Alert 창을 띄우려면 자바스크립트 코드를 빌려써야 하고 그과정에서 컨트롤러에 자바코드와 자바스크립트 코드가 섞이거나, 또는 뷰 스크립트 복잡해 질것이 우려되었다. 그래서 Alert 창을 사용하지 않기로 했다.
(자바 코드로 Alert 창 띄울수 없는지 확인이 필요할 것 같다. 안된다면 jstl으로 라도...)
2. 뷰에 메세지로 띄우기
처음 설계 단계에서는 Alert 창을 띄우는 것만 생각해보았는데 실제 로그인 페이지들을 살펴보니 Alert창 보다는 그냥 뷰에 메세지를 표시하는 방식이 많았다. 그래서 이 방식으로 하기로 결정
리다이랙션의 문제점
리다이랙션을 하면 뷰가 아니라 '서블릿'을 호출한다. 그렇기때문에 기존 서블릿이 갖고 있던 데이터(특히 모델이 갖고 있던)는 모두 지워진다. 그래서 이전 페이지에 전혀 의존하지 않는 새로운 페이지를 로딩할 경우는 상관없지만, 그렇지 않은 경우는 리다이랙션을 하지 않고, 그냥 뷰 파일을 인클루딩 해야 한다.
예외처리의 경우, 예외 메세지를 페이지에 표시할거기 때문에 서블릿을 리다이랙션 할 경우, 예외 메세지가 사라져 버린다. 그렇기 때문에 뷰를 호출해야 한다.
if (userDao.existId(newUser.getId())) {
// TODO alert duplicate issue
model.clear();
model.put("alert", "이미 존재하는 아이디입니다");
return "redirect:join.do";
}
즉, 이딴식으로 코드 짜면 model에 넣었던 alert 데이터는 사라져 버린다...(이런 실수는 하지 말자)
구현
public class JoinController implements Controller, DataBinding {
@Override
public String execute(Map<String, Object> model) throws Exception {
User newUser = (User) model.get("newUser");
String passwordCheck = (String) model.get("passwordCheck");
if (newUser.getName() == null) {
// enter join form
if (newUser.getId() == null) {
return "/auth/JoinForm.jsp";
}
// checking input form is blank
if (newUser.getId().equals("") || newUser.getPassword().equals("") || passwordCheck.equals("")) {
model.clear();
model.put("alert", "일부 항목이 공백입니다");
return "/auth/JoinForm.jsp";
}
// checking id is duplicate
if (userDao.existId(newUser.getId())) {
model.clear();
model.put("alert", "이미 존재하는 아이디입니다");
return "/auth/JoinForm.jsp";
}
// checking pwd/pwd check are same
if (!newUser.getPassword().equals(passwordCheck)) {
model.clear();
model.put("alert", "비밀번호와 비밀번호 확인일 일치하지 않습니다");
return "/auth/JoinForm.jsp";
}
// all form is valid
model.put("id", newUser.getId());
model.put("password", newUser.getPassword());
return "/auth/JoinForm2.jsp";
} else {
// checking name is duplicate
if (userDao.existName(newUser.getName())) {
model.put("id", newUser.getId());
model.put("password", newUser.getPassword());
model.put("alert", "이미 존재하는 이름입니다");
return "/auth/JoinForm2.jsp";
} else {
userDao.insert(newUser);
return "redirect:login.do";
}
}
}
}
수정된 JoinController의 execute() 메서드이다. if 문을 통해 예외별로 조사를 한후, 예외 조건에 성립하는 경우, 예외메세지를 key를 "alert"로 하여 model에 삽입한다. 그후, 예외가 발생한 페이지의 뷰를 다시 인클루딩한다. 그러면 모델에 넣어두었던 alert는 그대로 남아있다. 그리고 기존에 예외가 발생했던 입력 데이터는 모두 지워준다.(model.clear())
뷰는 alert 데이터가 존재하는 경우, 해당 메세지를 화면에 표시한다.
자동화
예외 조건 조사 - 예외 처리 - 예외 메세지 저장 - 예외 발생 페이지 다시 로딩 이 과정이 모든 예외에서 반복된다. 코드의 가독성도 떨어지고, 비효율적이므로 추후 자동화가 필요할 것 같다.
'프로젝트 이야기 > CRUD 미니 게시판' 카테고리의 다른 글
220323 [bug] : 줄바뀜이 읽기/수정 폼에서 적용이 안되는 문제 (0) | 2022.03.23 |
---|---|
220322 (5) : 객체 생성 자동화 (0) | 2022.03.22 |
220311 (3) : 인스턴스 생성 자동화하기 (feat. Reflection API) (0) | 2022.03.12 |
220310 (2) : 유저 기능 구현 (0) | 2022.03.10 |
220304 (1) : 피드 CRUD(생성/읽기/수정/삭제)기능 구현 (0) | 2022.03.08 |