게시판 구현 / 1. 회원가입 / JsonObject 만들기
[요약]
[과제]
- 아이디 중복체크
* 중복체크 후에 아이디 값이 변경되면 다시 중복체크 버튼을 활성화
- 닉네임 중복체크
- 비밀번호 영문자, 숫자, 특수문자 지정 및 알림
- 비밀번호 일치여부 확인
* 비밀번호 일치 시, 비밀번호를 변경해도 비밀번호 일치로 나오는 현상
- 회원가입 submit
[Join.jsp 수정 : 4가지 기능 구현 / script 에서 수정]
- (1) 아이디 중복체크 여부
- (2) 닉네임 중복체크 여부
- (3) 비밀번호 유효성 검사 여부
- (4) 비밀번호 일치 여부
- (5) 회원가입 submit
우선
- (1) 아이디 중복체크 여부
- (2) 닉네임 중복체크 여부 (아이디 중복체크 여부와 동일)
<script>
...
<div class="container mt-3 mb-5 w-25">
// #join-form
<form id="join-form" action="/member/join.do" method="post">
<div class="form-group">
<label for="username">아이디</label>
// #username
<input type="text" class="form-control" id="username" name="username" required>
<div class="d-flex justify-content-end mt-2">
// #btn-id-check
<button type="button" class="btn btn-secondary" id="btn-id-check">중복체크</button>
</div>
</div>
...
$(() => {
// 4가지 변수선언
// (1) 아이디 중복체크 여부
let idCheck = false;
// (2) 닉네임 중복체크 여부
let nicknameCheck = false;
// (3) 비밀번호 유효성 검사 여부
let passwordCheck = false;
// (4) 비밀번호 일치 여부
let passwordConfirm = false;
// (1) ajax를 통한 아이디 중복체크
$("#btn-id-check").on("click", (e) => {
// 어떤식으로 구현되는지 확인하기 위해 추가
console.log($("#join-form").serialize());
// 중복체크 버튼 클릭 시 아이디값이 비어 있으면
if($("#username").val() === "") {
alert("아이디를 입력하세요.");
$("#username").focus();
return;
}
// ajax를 이용해서 백엔드와 비동기 통신
$.ajax({
// controller에서 해당 url 메서드 검색
url: "/member/usernameCheck.do",
// post 방식
type: "post",
// 유니코드 방식(생략 가능)
contentType: "x-www-form-urlencoded",
// serialize(): 선택된 폼 태그의 input들의 name속성을
// 키로 입력된 값들을 밸류로 가져오면서 유니코드로 변환한 데이터
// 형태로 만들어준다.
data: $("#join-form").serialize(),
// success: 요청 url로부터 정상적으로 응답을 받았을 때 실행될 내용 정의
success: (obj) => {
// Json String을 Json Object로 변경
// JSON.parse()
const jsonObj = JSON.parse(obj);
console.log(obj);
console.log(jsonObj);
if(jsonObj.usernameCheckMsg === 'usernameOk') {
if(confirm(`사용가능한 아이디입니다. \${\$("#username").val()}를 사용하시겠습니까?`)) {
idCheck = true;
// 이 코드는 jQuery를 사용하여 HTML 엘리먼트의 속성을 변경하는 것입니다.
// $("#btn-id-check"): 이 부분은 jQuery 선택자로,
// ID가 "btn-id-check"인 HTML 엘리먼트를 선택합니다.
// .attr("disabled", true): 이 부분은 선택한 엘리먼트의 속성을
// 변경하는 것입니다. 여기서는 "disabled" 속성을
// "true"로 설정합니다.
// 이렇게 하면 ID가 "btn-id-check"인 버튼 엘리먼트가
// 비활성화됩니다. 사용자가 그 버튼을 클릭할 수 없게 됩니다.
$("#btn-id-check").attr("disabled", true);
}
return;
}
alert("중복된 아이디입니다.");
idCheck = false;
$("#username").focus();
},
// rror: 요청이 실패했을 때 실행할 내용 정의.
error: (err) => {
console.log(err);
}
});
});
// 중복체크 후에 아이디 값이 변경되면 다시 중복체크 버튼을 활성화
$("#username").on("change", (e) => {
idCheck = false;
$("#btn-id-check").attr("disabled", false);
});
- (참고) Sserialize 를 사용해서 객체형태로 저장됨
- (참고) String이 아닌 JsonSting으로 사용하는 이유는 아래 게시글 참고
2024.07.16 - [분류 전체보기] - ajax에서 return 값이 String이 아닌 JSON 형태여야 하는 이유
ajax에서 return 값이 String이 아닌 JSON 형태여야 하는 이유
JSON (JavaScript Object Notation) 문자열은 일반적인 문자열과 몇 가지 차이점이 있습니다.이러한 차이점은 JSON 문자열을 처리하는 데 유용한 기능을 제공합니다.다음은 JSON 문자열에서만 사용할 수 있
maverick11471.tistory.com
- (3) 비밀번호 유효성 검사 여부
- (4) 비밀번호 일치 여부
<script>
...
<div class="form-group mt-3">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" name="password" required>
<p id="password-check" style="color: red; font-size: 0.8rem;">
비밀번호는 영문자, 숫자, 특수문자 조합의 9자리 이상으로 설정해주세요.
</p>
</div>
<div class="form-group mt-3">
<label for="password-confirm">비밀번호 확인</label>
<input type="password" class="form-control" id="password-confirm" name="password-confirm" required>
<p id="password-confirm-result" style="font-size: 0.8rem;"></p>
</div>
...
// 비밀번호 유효성 검사 메소드 (정규표현식)
// .test: 정규 표현식으로 문자열이 해당 패턴과 일치하는지 확인하는 데 사용
const validatePassword = (pw) => {
return /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*+=-]).{9,}$/.test(pw);
}
// 비밀번호 input의 내용이 변경되면 validatePassword 메소드로 유효성 검사 진행
$("#password").on("change", (e) => {
console.log(validatePassword($("#password").val()));
// 위의 validatePassword 메서드 이용
if(validatePassword($("#password").val())) {
passwordCheck = true;
// 위 password-check 문구 숨기기
$("#password-check").hide();
} else {
passwordCheck = false;
$("#password-check").show();
}
// 비밀번호 일치 시, 비밀번호를 변경해도 비밀번호 일치로 나오는 현상 해결
if($("#password").val() === $("#password-confirm").val()) {
passwordConfirm = true;
// 위에 비밀번호 일치여부<p> 내용은 따로 기입하지 않고
// 여기서 문구가 나타나도록 한다.
$("#password-confirm-result").text("비밀번호가 일치합니다.");
$("#password-confirm-result").css("color", "green");
} else {
passwordConfirm = false;
$("#password-confirm-result").text("비밀번호가 일치하지 않습니다.");
$("#password-confirm-result").css("color", "red");
}
});
// 비밀번호 확인
$("#password-confirm").on("change", (e) => {
$("#password-confirm-result").show();
if($("#password").val() === $("#password-confirm").val()) {
passwordConfirm = true;
$("#password-confirm-result").text("비밀번호가 일치합니다.");
$("#password-confirm-result").css("color", "green");
return;
}
passwordConfirm = false;
$("#password-confirm-result").text("비밀번호가 일치하지 않습니다.");
$("#password-confirm-result").css("color", "red");
});
[mapper 수정]
// 이미 가입되어 있으면 COUNT(*) == 1
// 가입되어 있지 않으면 COUNT(*) == 0
<select id="usernameCheck" parameterType="string" resultType="int">
SELECT COUNT(*)
FROM MEMBER
WHERE USERNAME = #{username}
</select>
[Dao 수정]
public int usernameCheck(String username) {
return mybatis.selectOne("MemberDao.usernameCheck", username);
}
[service + serviceImpl 수정]
String usernameCheck(String username);
@Override
public String usernameCheck(String username) {
int usernameCheck = memberDao.usernameCheck(username);
// String 값을 그대로 리턴하는 경우는 거의 없고
// 대부분 json 형태의 String을 리턴하여 사용한다.
// Java에서 Json 데이터 형태로 만드는 방식1 - JsonView
// Java에서 Json 데이터 형태로 만드는 방식1 - ObjectMapper
// ObjectMapper 객체를 이용한 json 형태의 데이터 만들기
ObjectMapper objectMapper = new ObjectMapper();
// Json 데이터 형태는 키와 밸류로 매핑되어 있는 데이터 형태이기 때문에
// Map을 사용해서 키와 밸류로 매핑되어 있는 데이터 형태로 만들어준다.
// (참고) .jsp: Json String을 Json Object로 변경했음
Map<String, String> jsonMap = new HashMap<>();
if(usernameCheck == 0) {
jsonMap.put("usernameCheckMsg", "usernameOk");
} else {
jsonMap.put("usernameCheckMsg", "usernameFail");
}
String jsonString = "";
try {
// writerWithDefaultPrettyPrinter(): 들여쓰기랑 엔터값이 포함하여 시인성이 높은 형태로 데이터를 써주는 writer
jsonString = objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(jsonMap);
} catch (JsonProcessingException je) {
System.out.println(je.getMessage());
}
return jsonString;
}
[controller 수정]
@PostMapping("/usernameCheck.do")
// Controller 메소드에서 String을 리턴하면 해당 String으로 jsp 파일을 찾게 된다.
// jsp 파일 자체가 respone(응답 객체)의 body에 담겨서 리턴되는데
// jsp 파일이나 html 파일이 아닌 리턴할 값을 response(응답 객체)의 body에 담아주려면
// @ResponseBody 어노테이션을 사용한다. @ResponseBody 어노테이션이 달려있는 메소드에서는
// viewResolver가 동작하지 않는다.
@ResponseBody
public String usernameCheck(MemberDto memberDto) {
System.out.println(memberService.usernameCheck(memberDto.getUsername()));
return memberService.usernameCheck(memberDto.getUsername());
}
- (5) 회원가입 submit
[join.jsp 수정]
<script>
// submit 시 위에 선언한 변수들을 활용하여 미흡한 분야를 보완한다.
$("#join-form").on("submit", (e) => {
// id 중복체크가 되지 않았을 때
if(!idCheck) {
// <form> 태그는 제출 시 페이지를 새로 고치는 기본 동작을 하려는데,
// e.preventDefault가 HTML 요소의 기본 동작을 방지하는 데 사용
e.preventDefault();
alert("아이디 중복체크를 진행하세요.");
return;
}
if(!passwordCheck) {
e.preventDefault();
alert("비밀번호는 영문자, 숫자, 특수문자 조합의 9자리 이상으로 지정하세요.");
return;
}
if(!passwordConfirm) {
e.preventDefault();
alert("비밀번호가 일치하지 않습니다.");
return;
}
if(!nicknameCheck) {
e.preventDefault();
alert("닉네임 중복체크를 진행하세요.");
return;
}
});