팝업을 이용하여 도로명 주소와 지번 주소 모두 보여주기 부분 join.jsp로 코드 복사해와서 수정
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
const fnCheckPassword = () => {
$('#pw').keyup((ev) => {
let pw = $(ev.target).val();
// 비밀번호 : 8~20자, 영문,숫자,특수문자, 2가지 이상 포함
let validPwCount = /[A-Z]/.test(pw) // 대문자가 있으면 true
+ /[a-z]/.test(pw) // 소문자가 있으면 true
+ /[0-9]/.test(pw) // 숫자가 있으면 true
+ /[^A-Za-z0-9]/.test(pw); // 특수문자가 있으면 true
pwPassed = pw.length >= 8 && pw.length <= 20 && validPwCount >= 2;
if(pwPassed){
$('#msg_pw').text('사용 가능한 비밀번호입니다.');
} else {
$('#msg_pw').text('비밀번호는 8~20자, 영문/숫자/특수문자를 2가지 이상 포함해야 합니다.');
}
})
}

const fnCheckPassword2 = () => {
$('#pw2').blur((ev) => {
let pw = $('#pw').val();
let pw2 = ev.target.value;
pw2Passed = (pw !== '') && (pw === pw2);
if(pw2Passed){
$('#msg_pw2').text('');
} else {
$('#msg_pw2').text('비밀번호 입력을 확인하세요.');
}
})
}
@Override
public void join(HttpServletRequest request, HttpServletResponse response) {
String email = request.getParameter("email");
String pw = mySecurityUtils.getSHA256(request.getParameter("pw"));
String name = mySecurityUtils.preventXSS(request.getParameter("name"));
String gender = request.getParameter("gender");
String mobile = request.getParameter("mobile");
String postcode = request.getParameter("postcode");
String roadAddress = request.getParameter("roadAddress");
String jibunAddress = request.getParameter("jibunAddress");
String detailAddress = mySecurityUtils.preventXSS(request.getParameter("detailAddress"));
String event = request.getParameter("event");
UserDto user = UserDto.builder()
.email(email)
.pw(pw)
.name(name)
.gender(gender)
.mobile(mobile)
.postcode(postcode)
.roadAddress(roadAddress)
.jibunAddress(jibunAddress)
.detailAddress(detailAddress)
.agree(event.equals("on") ? 1 : 0)
.build();
int joinResult = userMapper.insertUser(user);
try {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>");
if(joinResult == 1) {
request.getSession().setAttribute("user", userMapper.getUser(Map.of("email", email)));
userMapper.insertAccess(email);
out.println("alert('회원 가입되었습니다.')");
out.println("location.href='" + request.getContextPath() + "/main.do'");
} else {
out.println("alert('회원 가입이 실패했습니다.')");
out.println("history.go(-2)");
}
out.println("</script>");
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
const fnModifyUser = () => {
$('#btn_modify').click(() => {
if(!namePassed){
alert('이름을 확인하세요.');
return;
} else if(!mobilePassed){
alert('휴대전화번호를 확인하세요.');
return;
}
$.ajax({
// 요청
type: 'post',
url: getContextPath() + '/user/modify.do',
data: $('#frm_mypage').serialize(),
// 응답
dataType: 'json',
success: (resData) => { // {"modifyResult": 1}
if(resData.modifyResult === 1){
alert('회원 정보가 수정되었습니다.');
} else {
alert('회원 정보가 수정되지 않았습니다.');
}
}
})
})
}
if(modifyResult == 1) {}
세션 정보 업데이트 하는 if문
로그인한 사용자의 마이페이지로 업데이트 했다는 것은 로그인한 사용자의 정보가 바뀌었다는 거니까 (매퍼 통해서 db는 수정해줬고) 세션도 따로 수정해줘야 함
컨트롤러 작업도 가입에서 했던 것과 같은 원리라서 생략

각자 해보기였다.
궁금하면 걍 6교시 초반부 영상을 보자 5분만에 설명끝나서 생략
@Component
public class RequiredLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if(session != null && session.getAttribute("user") == null) {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("if(confirm('로그인이 필요한 기능입니다. 로그인할까요?')){");
out.println("location.href='" + request.getContextPath() + "/user/login.form'");
out.println("} else {");
out.println("history.back()");
out.println("}");
out.println("</script>");
out.flush();
out.close();
return false; // 가로챈 컨트롤러 요청이 동작하지 않는다.
}
return true; // 가로챈 컨트롤러 요청이 동작한다.
}
}
<interceptors>
<interceptor>
<mapping path="/user/mypage.form"/>
<mapping path="/user/modifyPw.form"/>
<mapping path="/free/write.form"/>
<beans:bean class="com.gdu.myhome.intercept.RequiredLoginInterceptor" />
</interceptor>
<interceptor>
<mapping path="/user/agree.form"/>
<mapping path="/user/join.form"/>
<mapping path="/user/login.form"/>
<beans:bean class="com.gdu.myhome.intercept.ShouldNotLoginInterceptor" />
</interceptor>
</interceptors>
<mapping path="/user/mypage.form"/>은 mypage로 넘어갈 때 동작한다는 뜻const fnLeaveUser = () => {
$('#btn_leave').click(() => {
if(confirm('회원 탈퇴하시겠습니까?')){
$('#frm_mypage').prop('action', getContextPath() + '/user/leave.do');
$('#frm_mypage').submit();
}
})
}

Optional<String> opt = Optional.ofNullable(request.getParameter("userNo"));
int userNo = Integer.parseInt(opt.orElse("0"));
이렇게 optional 처리를 해주면 null 값에도 대비해줄 수 있다. userNo가 null 값일 경우 0을 보내라는 뜻. 회원번호 0은 없는 사용자이기 때문에 if(insertLeaveUserResult == 1 && deleteUserResult == 1) 에 통과되지 않는다 (원래는 그 밑에 else가 수행되어야 하지만 if문 위에서 null 값에 대한 if문을 추가로 만들어줬기 때문에 else 문이 수행될 일은 거의 없다)
(나머지는 특별히 설명 필요 없어서 과정 안 적음. 순서대로 따라가면서 공부하면 된다,)