회원정보 조회
📍 fn:split(문자열, '구분자')
${fn:split(loginMember.memberAddress, ',,') }
📍 String.join(",,", address)
<a href="${contextPath}/member/myPage/info" id="nickname">${loginMember.memberNickname}</a>
@WebServlet("/member/myPage/info")
public class MyPageInfoServlet extends HttpServlet {
// 메인페이지 -> 별명 클릭 시 요청(GET)
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path="/WEB-INF/views/member/myPage-info.jsp";
req.getRequestDispatcher(path).forward(req, resp);
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 문자열 관련 함수(메소드) 제공 JSTL (EL 형식으로 작성) -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My page</title>
<link rel="stylesheet" href="${contextPath}/resources/css/main-style.css">
<link rel="stylesheet" href="${contextPath}/resources/css/myPage-style.css">
<script src="https://kit.fontawesome.com/8f020b2fa9.js"
crossorigin="anonymous"></script>
</head>
<body>
<main>
<jsp:include page="/WEB-INF/views/common/header.jsp"></jsp:include>
<!-- 마이페이지 - 내 정보 -->
<section class="myPage-content">
<!-- 사이드메뉴 include -->
<jsp:include page="/WEB-INF/views/member/sideMenu.jsp"></jsp:include>
<!-- 오른쪽 마이페이지 주요 내용 -->
<section class="myPage-main">
<h1 class="myPage-title">내 정보</h1>
<span class="myPage-explanation">원하는 회원 정보를 수정할 수 있습니다.</span>
<form action="info" method="POST" name="myPage-form" onsubmit="return infoValidate()">
<div class="myPage-row">
<label>닉네임</label>
<input type="text" id="memberNickname" name="memberNickname" value="${ loginMember.memberNickname }" maxlength="10">
</div>
<div class="myPage-row">
<label>전화번호</label>
<input type="text" id="memberTel" name="memberTel" value="${ loginMember.memberTel }" maxlength="11">
</div>
<!-- 주소 --> <!-- fn:split(문자열, '구분자') -->
<c:set var="addr" value="${fn:split(loginMember.memberAddress, ',,') }"></c:set>
<div class="myPage-row info-title">
<span>주소</span>
</div>
<div class="myPage-row info-address">
<input type="text" name="memberAddress" value="${addr[0]}" maxlength="6">
<button type="button" id="info-address-btn">검색</button>
</div>
<div class="myPage-row info-address">
<input type="text" name="memberAddress" value="${addr[1]}">
</div>
<div class="myPage-row info-address">
<input type="text" name="memberAddress" value="${addr[2]}">
</div>
<button id="info-update-btn">수정하기</button>
</form>
</section>
</section>
</main>
<jsp:include page="/WEB-INF/views/common/footer.jsp"></jsp:include>
<!-- myPage.js 추가 -->
<script src="${contextPath}/resources/js/member/myPage.js"></script>
</body>
</html>
회원정보 수정
<form action="info" method="POST" name="myPage-form" onsubmit="return infoValidate()">
@WebServlet("/member/myPage/info")
// 회원 정보 수정 요청(POST)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 파라미터 얻어오기 + 배열 -> 문자열로 만들기
String memberNickname = req.getParameter("memberNickname");
String memberTel = req.getParameter("memberTel");
String[] address = req.getParameterValues("memberAddress");
String memberAddress = null;
if (!address[0].equals("")) { // 우편번호가 빈칸이 아니라면 == 주소 작성
memberAddress = String.join(",,", address);
}
// *** 세션에서 로그인한 회원 정보 얻어오기 ***
HttpSession session = req.getSession();
// 얕은 복사(세선에 있는 회원정보 객체 주소)
// -> loginMember를 수정하면 세선에 저장된 내용 수정된다.
Member loginMember = (Member)(session.getAttribute("loginMember"));
int memberNo = loginMember.getMemberNo(); // 회원 번호 얻어오기 성공
// 업데이트에 필요한 정보를 모아둔 Member 객체 생성
Member mem = new Member();
mem.setMemberNo(memberNo);
mem.setMemberNickname(memberNickname);
mem.setMemberTel(memberTel);
mem.setMemberAddress(memberAddress);
try {
MemberService service = new MemberService();
int result = service.updateMember(mem);
// 수정 성공/실패에 따른 메세지 출력 제어
if(result>0) { // 성공
session.setAttribute("message", "회원정보가 수정되었습니다.");
// DB는 수정됐지만
// 로그인한 회원 정보가 담겨있는 Session 정보는 그대로다
// -> 동기화 작업
loginMember.setMemberNickname(memberNickname);
loginMember.setMemberTel(memberTel);
loginMember.setMemberAddress(memberAddress);
} else { // 실패
session.setAttribute("message", "회원정보 수정 실패");
}
// 성공/실패 여부 관계없이 "내 정보"화면을 재요청
// 절대 경로
resp.sendRedirect(req.getContextPath() + "/member/myPage/info");
// 상대 경로
// resp.sendRedirect("info");
} catch (Exception e) {
e.printStackTrace();
}
}
/** 회원 정보 수정 서비스
* @param mem
* @return result
* @throws Exception
*/
public int updateMember(Member mem) throws Exception {
Connection conn = getConnection();
int result = dao.updateMember(conn, mem);
if(result>0) commit(conn);
else rollback(conn);
close(conn);
return result;
}
/** 회원정보 수정 DAO
* @param conn
* @param mem
* @return result
* @throws Exception
*/
public int updateMember(Connection conn, Member mem) throws Exception {
int result = 0;
try {
String sql = prop.getProperty("updateMember");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, mem.getMemberNickname());
pstmt.setString(2, mem.getMemberTel());
pstmt.setString(3, mem.getMemberAddress());
pstmt.setInt(4, mem.getMemberNo());
result= pstmt.executeUpdate();
} finally {
close(pstmt);
}
return result;
}
<!-- 회원정보 수정 -->
<entry key="updateMember">
UPDATE MEMBER SET
MEMBER_NICK=?,
MEMBER_TEL=?,
MEMBER_ADDR=?
WHERE MEMBER_NO=?
</entry>
function infoValidate(){
const memberNickname = document.getElementById("memberNickname");
const memberTel = document.getElementById("memberTel");
const regExp1 = /^[a-zA-Z0-9가-힣]{2,10}$/; // 닉네임 정규식
const regExp2 = /^0(1[01679]|2|[3-6][1-5]|70)\d{3,4}\d{4}$/; // 전화번호 정규식
// 010 011 016 017 019
// 02 031 032 041 042 051 052
// 070
// 닉네임 유효성 검사
if(memberNickname.value.trim().length==0){ // 미작성 시
/* alert("닉네임을 입력해주세요.");
memberNickname.focus();
memberNickname.value="";
return false; */
return printAlert(memberNickname, "닉네임을 입력해주세요.");
}
if(!regExp1.test(memberNickname.value)){ // 유효하지 않은 경우
/* alert("닉네임은 영어/숫자/한글 2~10 글자 사이로 작성해주세요");
memberNickname.focus();
memberNickname.value="";
return false; */
return printAlert(memberNickname, "닉네임은 영어/숫자/한글 2~10 글자 사이로 작성해주세요.");
}
// 전화번호 유효성 검사
if(memberTel.value.trim().length==0){ // 미작성 시
/* alert("전화번호를 입력해주세요(-제외)");
memberTel.focus();
memberTel.value="";
return false; */
return printAlert(memberTel, "전화번호를 입력해주세요(-제외)");
}
if(!regExp2.test(memberTel.value)){
/* alert("전화번호 형식이 올바르지 않습니다.");
memberTel.focus();
memberTel.value="";
return false; */
return printAlert(memberTel, "전화번호 형식이 올바르지 않습니다.");
}
return true; // true 반환해서 form 제츨 수행
}
// 경고 출력 + 포커스 + false + 비우기
function printAlert(el, message){ // 매개변수 el은 요소
alert(message);
el.focus();
el.value="";
return false;
}
// 비밀번호 변경 제출 시 유효성 검사
function changePwValidate(){
// 비밀번호 변경 관련 input 요소 얻어오기
const currentPw = document.getElementById("currentPw");
const newPw = document.getElementsByName("newPw")[0];
const newPwConfirm = document.getElementsByName("newPwConfirm")[0];
// 비밀번호 정규식
/* const regExp = /^[a-zA-Z0-9\!\@\#\-\_]{6,30}$/; */
const regExp = /^[\w!@#_-]{6,30}/;
// 형재 비밀번호 미작성
if(currentPw.value.trim().length == 0){
return printAlert(currentPw, "현재 비밀번호를 입력해주세요");
}
// 새 비밀번호 미작성
if(newPw.value.trim().length == 0){
newPwConfirm.value="";
return printAlert(newPw, "새 비밀번호를 입력해주세요");
}
// 유효하지 않은 경우
if(!regExp.test(newPw.value)){
newPwConfirm.value="";
return printAlert(newPw,"영어, 숫자, 특수문자(!,@,#,-,_) 6~30글자 사이로 작성해주세요.")
}
// 새 비밀번호 미작성
if(newPwConfirm.value.trim().length == 0){
return printAlert(newPwConfirm, "새 비밀번호 확인을 입력해주세요");
}
// 새 비밀번호 != 새 비밀번호 확인
if(newPw.value != newPwConfirm.value){
newPwConfirm.value="";
return printAlert(newPw,"새 비밀번호가 일치하지 않습니다.")
}
return true; // 위 조건을 모두 수행하지 않은 경우 true 반환
}
// 회원탈퇴 유효성 검사
function secessionValidate(){
const memberPw = document.getElementsByName("memberPw")[0];
const agree = document.getElementById("agree");
if(memberPw.value.trim().length==0){
return printAlert(memberPw, "비밀번호를 입력해주세요");
}
if(!agree.checked){
alert("약관 동의 후 탈퇴 버튼을 클릭해주세요");
return false;
}
// 정말 탈퇴할지 확인
// - window.confirm("내용") : 대화상자에 확인/취소 생성
// 확인 클릭 시 true/ 취소 클릭 시 false
if(!confirm("정말 탈퇴하시겠습니까?")){ // 취소를 누른 경우
return false;
} else{
}
return true;
/* if(memberPw.value.trim().length !=0 && agree.checked){
if(confirm("정말 탈퇴하시겠습니까?")){
return true;
} else{
return false;
}
} */
}
// 회원 프로필 이미지 변경(미리보기)
const inputImage = document.getElementById("input-image");
if(inputImage != null){ // inputImage 요소가 화면에 존재할 때
// input type ="file"요소는 파일이 선택될 때 change 이벤트가 발생한다.
inputImage.addEventListener("change", function(){
// this : 이벤트가 발생한 요소(input type = "file")
// files : input type = "file"만 사용 가능한 속성으로
// 선택된 파일 목록(배열)을 반환
//console.log(this.files);
//console.log(this.files[0]);
if(this.files[0] != undefined) { // 파일이 선택되었을 때
const reader = new FileReader();
// 자바스크립트에서의 FileReader
// - 웹 애플리케이션이 비동기적으로 데이터를 읽기 위하여 사용하는 객체
reader.readAsDataURL(this.files[0]);
// FileReader.readAsDataURL(파일)
// - 지정된 파일의 내용을 읽기 시작함
// - 읽어오는 게 완료되면 result 속성 data: 에
// 읽어온 파일의 위치를 나타내는 URL이 포함된다.
// -> 해당 URL을 이용해서 브라우저에 이미지를 볼 수 있다.
// FileReader.onload = function(){}
// - FileReader가 파일을 다 읽어온 경우 함수를 수행
reader.onload = function(e){ // 고전 이벤트 모델
// e : 이벤트 발생 객체
// e.target : 이벤트가 발생한 요소(객체) -> FileReader
// e.target.result : FileReader가 읽어온 파일의 URL
// 프로필 이미지의 src 속성의 값을 FileReader가 읽어온 파일의 URL로 변경
const profileImage = document.getElementById("profile-image");
profileImage.setAttribute("src", e.target.result);
// -> setAttribute() 호출 시 중복되는 속성이 존재하면 덮어쓰기
document.getElementById("delete").value == 0;
// 새로운 이미지가 선택되었기 때문에 1 -> 0 (안 눌러짐 상태)로 변경
}
}
})
}
function profileValidate(){
const inputImage = document.getElementById("input-image");
const del = document.getElementById("delete"); // hidden 타입
if(inputImage.value == "" && del.value==0){
// 빈문자열 == 파일 선택 X / del 값이 0 == x를 누르지도 않았다.
// -> 아무것도 안 하고 변경버튼을 클릭한 경우
alert("이미지를 선택한 후 변경 버튼을 클릭해주세요.");
return false;
}
return true;
}
// 프로필 이미지 옆 X 버튼 클릭 시
document.getElementById("delete-image").addEventListener("click", function(){
// 0 : 안 눌러짐
// 1 : 눌러짐
const del = document.getElementById("delete");
if(del.value==0){ // 눌러지지 않은 경우라면
// 1) 프로필 이미지를 기본 이미지로 변경
document.getElementById("profile-image").setAttribute("src", contextPath + "/resources/images/user.png");
// 2) input type='file'에 저장된 값(value)에 "" 대입
document.getElementById("input-image").value="";
del.value = 1; // 눌러진 걸로 인식
}
})