Study Web Development

1월 27일

이전으로

Servlet & JSP

9. MVC

mvcPage

프로젝트 생성 및 설정
  1. WEB-INF 폴더의 member.properties 하단에 다음의 내용을 추가
/member/modifyPassword.do=kr.member.action.ModifyPasswordAction
/member/updateMyPhoto.do=kr.member.action.UpdateMyPhotoAction
/member/deleteUserForm.do=kr.member.action.DeleteUserFormAction
/member/deleteUser.do=kr.member.action.DeleteUserAction
  1. webapp 폴더의 하위 폴더로 upload 생성
Model
  1. 새 클래스 ModifyPasswordAction 생성
package kr.member.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;

public class ModifyPasswordAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpSession session = request.getSession();
		Integer user_num = (Integer)session.getAttribute("user_num");
		if(user_num==null) { // 로그인되어 있지 않은 경우
			return "redirect:/member/loginForm.do";
		}

		// 로그인되어 있는 경우
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		// 전송된 데이터 반환
		String id = request.getParameter("id");
		String origin_passwd = request.getParameter("origin_passwd"); // 현재 비밀번호
		String passwd = request.getParameter("passwd"); // 새 비밀번호

		// 현재 로그인한 아이디
		String user_id = (String)session.getAttribute("user_id");

		MemberDAO dao = MemberDAO.getInstance();
		MemberVO member = dao.checkMember(id);
		boolean check = false;
		
		// 사용자가 입력한 아이디가 존재하고 로그인한 아이디와 일치하는지 체크
		if(member!=null && id.equals(user_id)) {
			// 비밀번호 일치 여부 체크
			check = member.isCheckedPassword(origin_passwd);
		}
		
		if(check) { // 인증 성공
			// 비밀번호 변경
			dao.updatePassword(passwd, user_num);
		}
		
		request.setAttribute("check", check);
		
		// JSP 경로 반환
		return "/WEB-INF/views/member/modifyPassword.jsp";
	}

}
  1. 새 클래스 UpdateMyPhotoAction 생성
package kr.member.action;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.codehaus.jackson.map.ObjectMapper;

import com.oreilly.servlet.MultipartRequest;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;
import kr.util.FileUtil;

public class UpdateMyPhotoAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String, String> mapAjax = new HashMap<String, String>();
		
		HttpSession session = request.getSession();
		Integer user_num = (Integer)session.getAttribute("user_num");
		if(user_num==null) { // 로그인되어 있지 않은 경우
			mapAjax.put("result", "logout"); // Ajax 통신할 것이므로 redirect하는 대신 로그인 여부를 JSON 형식 데이터로 보내고 JSP에서 UI 처리
		}
		else { // 로그인되어 있는 경우
			MemberDAO dao = MemberDAO.getInstance();
			MemberVO db_member = dao.getMember(user_num); // 이전 이미지 파일 정보 읽기
			
			// 전송된 파일 업로드 처리
			MultipartRequest multi = FileUtil.createFile(request);
			// 서버에 저장된 파일명 반환
			String photo = multi.getFilesystemName("photo"); // photo는 Ajax 통신으로 전송받은 데이터의 식별자
			// 프로필 수정
			dao.updateMyPhoto(photo, user_num);
			
			// 세션에 저장된 프로필 사진 정보 갱신
			session.setAttribute("user_photo", photo);
			
			// 이전 프로필 이미지 삭제
			FileUtil.removeFile(request, db_member.getPhoto());
			
			mapAjax.put("result", "success");
		}
		
		// JSON 데이터로 변환
		ObjectMapper mapper = new ObjectMapper();
		String ajaxData = mapper.writeValueAsString(mapAjax);
		
		request.setAttribute("ajaxData", ajaxData);
		
		// JSP 경로 반환
		return "/WEB-INF/views/common/ajax_view.jsp";
	}

}
  1. 새 클래스 DeleteUserFormAction 생성
package kr.member.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import kr.controller.Action;

public class DeleteUserFormAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpSession session = request.getSession();
		Integer user_num = (Integer)session.getAttribute("user_num");
		if(user_num==null) { // 로그인되어 있지 않은 경우
			return "redirect:/member/loginForm.do";
		}
		
		// JSP 경로 반환
		return "/WEB-INF/views/member/deleteUserForm.jsp";
	}

}
  1. 새 클래스 DeleteUserAction 생성
package kr.member.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;
import kr.util.FileUtil;

public class DeleteUserAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpSession session = request.getSession();
		Integer user_num = (Integer)session.getAttribute("user_num");
		if(user_num==null) { // 로그인되어 있지 않은 경우
			return "redirect:/member/loginForm.do";
		}
		
		// 로그인되어 있는 경우
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		// 전송된 데이터 반환
		String id = request.getParameter("id");
		String passwd = request.getParameter("passwd");
				
		// 로그인한 아이디
		String user_id = (String)session.getAttribute("user_id");

		MemberDAO dao = MemberDAO.getInstance();
		MemberVO db_member = dao.checkMember(id);		
		boolean check = false;
		
		// 사용자가 입력한 아이디가 존재하고 로그인한 아이디와 일치하는지 체크
		if(db_member!=null && id.equals(user_id)) {
			// 비밀번호 일치 여부 체크
			check = db_member.isCheckedPassword(passwd);
		}
		
		if(check) { // 인증 성공
			// 회원 정보 삭제
			dao.deleteMember(user_num);
			// 프로필 사진 삭제
			FileUtil.removeFile(request, db_member.getPhoto());
			// 로그아웃
			session.invalidate();
		}
		
		request.setAttribute("check", check);
		
		// JSP 경로 반환
		return "/WEB-INF/views/member/deleteUser.jsp";
	}

}
View
  1. member 폴더에 새 JSP 파일 modifyPassword.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	if(${check}) {
		alert('비밀번호를 수정했습니다.');
		location.href = 'myPage.do';
	}
	else {
		alert('아이디 또는 비밀번호가 불일치합니다!');
		history.go(-1);
	}
</script>
  1. member 폴더에 새 JSP 파일 deleteUserForm.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 탈퇴</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/layout.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
	$(function() {
		$('#delete_form').submit(function() {
			let isValid = true; // submit()의 return 값 지정
			
			$('li').each(function() {
				let input = $(this).find('input');
				if(!input.val().trim()) {
					let word = $(this).find('label').text();
					let post = (word.charCodeAt(word.length-1) - ''.charCodeAt(0)) % 28 > 0 ? '' : '';
					alert(word + post + ' 입력하세요!');
					input.val('').focus();
					isValid = false; // submit()의 return 값 지정
					return false; // each() 루프 중단
				}
			}); // end of each
			
			if($('#passwd').val()!=$('#cpasswd').val()) {
				if(isValid) alert('비밀번호와 비밀번호 확인이 불일치합니다!');
				$('#cpasswd').val('').focus();
				isValid = false; // submit()의 return 값 지정;
			}
			
			return isValid;
		}); // end of submit
		
		// 비밀번호 확인을 입력한 후 다시 비밀번호를 수정하면 비밀번호 확인을 초기화
		$('#passwd').keyup(function() {
			$('#cpasswd').val('');
			$('#message_cpasswd').text('');
		}); // end of keyup
		
		// 비밀번호와 비밀번호 확인 일치 여부 체크
		$('#cpasswd').keyup(function() {
			if($('#passwd').val()==$('#cpasswd').val()) {
				$('#message_cpasswd').text('비밀번호 일치');
			}
			else {
				$('#message_cpasswd').text('');
			}
		}); // end of keyup
	});
</script>
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<h2>회원 탈퇴</h2>
	<form action="deleteUser.do" method="post" id="delete_form">
		<ul>
			<li>
				<label for="id">아이디</label>
				<input type="text" name="id" id="id" maxlength="12">
			</li>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" maxlength="12">
			</li>
			<li>
				<label for="cpasswd">비밀번호 확인</label>
				<input type="password" name="cpasswd" id="cpasswd" maxlength="12">
				<span id="message_cpasswd"></span>
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="회원 탈퇴">
			<input type="button" value="MyPage" onclick="location.href = 'myPage.do';">
		</div>
	</form>
</div>
</body>
</html>
  1. member 폴더에 새 JSP 파일 deleteUser.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if test="${check}">
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 탈퇴</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<h2>회원 탈퇴</h2>
	<div class="result-display">
		<div class="align-center">
			회원 탈퇴가 완료되었습니다.
			<p>
			<input type="button" value="홈으로" onclick="location.href = '${pageContext.request.contextPath}/main/main.do';">
		</div>
	</div>
</div>
</body>
</html>
</c:if>
<c:if test="${!check}">
	<script type="text/javascript">
		alert('아이디 또는 비밀번호가 불일치합니다!');
		history.go(-1);
	</script>
</c:if>
DAO
  1. kr.util 패키지에 새 클래스 FileUtil 생성
package kr.util;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

public class FileUtil {
	// 인코딩 타입
	public static final String ENCODING_TYPE = "UTF-8";
	// 최대 업로드 사이즈
	public static final int MAX_SIZE = 5*1024*1024;
	// 업로드 경로
	public static final String UPLOAD_PATH = "/upload";
	
	// 파일 업로드
	public static MultipartRequest createFile(HttpServletRequest request) throws Exception {
		// 업로드 절대 경로
		String upload = request.getServletContext().getRealPath(UPLOAD_PATH); // ServletContext = JSP의 Application
		return new MultipartRequest(request, upload, MAX_SIZE, ENCODING_TYPE, new DefaultFileRenamePolicy());
	}
	
	// 파일 삭제
	public static void removeFile(HttpServletRequest request, String filename) {
		if(filename!=null) {
			// 업로드 절대 경로
			String upload = request.getServletContext().getRealPath(UPLOAD_PATH);
			File file = new File(upload + "/" + filename);
			if(file.exists()) file.delete();
		}
	}
}

다음으로