관리 메뉴

거니의 velog

(3) 모델2 방식으로 효율적으로 개발하기 3 본문

Java/Java_JSP Model2

(3) 모델2 방식으로 효율적으로 개발하기 3

Unlimited00 2023. 9. 23. 11:39

(3) 회원 정보 수정 및 삭제 기능 구현

* 이번에는 회원 정보를 수정하고 삭제하는 기능을 구현해 보자.

* 회원 정보를 수정하는 과정은 다음과 같다.

(1) 회원 정보 수정창에서 회원 정보를 수정하고 '수정하기'를 클릭해 /member/modMember.do로 컨트롤러에 요청한다.

(2) 컨트롤러는 전송된 회원 수정 정보를 가져온 후 테이블에서 회원 정보를 수정한다.

(3) 수정을 마친 후 컨트롤러는 다시 회원 목록창을 보여준다.
* 삭제하는 과정도 크게 다르지 않다.

(1) 회원 목록창에서 '삭제'를 클릭해 요청명 /member/delMember.do와 회원 ID를 컨트롤러로 전달한다.

(2) 컨트롤러는 request의 getPathInfo() 메서드를 이용해 요청명을 가져온다.

(3) 회원 ID를 SQL문으로 전달해 테이블에서 회원 정보를 삭제한다.

1. sec02.ex02 패키지를 만들고 앞에서 사용한 자바 실습 파일들을 붙여 넣는다. 그리고 test03 폴더를 만들고 JSP 파일들을 붙여 넣는다.

2. 브라우저에서 컨트롤러에 요청하면 request의 getPathInfo() 메서드를 이용해 수정 요청명인 /modMemberForm.do와 /modMember.do를 가져온 후 분기하여 작업을 수행하도록 MemberController 클래스를 다음과 같이 작성한다.

package sec02.ex02;

import java.io.IOException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/member/*")
public class MemberController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	MemberDAO memberDAO;

	public void init() throws ServletException {
		memberDAO = new MemberDAO();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)	throws ServletException, IOException {
		doHandle(request, response);
	}

	private void doHandle(HttpServletRequest request, HttpServletResponse response)	throws ServletException, IOException {
		String nextPage = null;
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		String action = request.getPathInfo();
		System.out.println("action:" + action);
		
		if (action == null || action.equals("/listMembers.do")) {
			List<MemberVO> membersList = memberDAO.listMembers();
			request.setAttribute("membersList", membersList);
			nextPage = "/test03/listMembers.jsp";
			
		} else if (action.equals("/addMember.do")) {
			String id = request.getParameter("id");
			String pwd = request.getParameter("pwd");
			String name = request.getParameter("name");
			String email = request.getParameter("email");
			MemberVO memberVO = new MemberVO(id, pwd, name, email);
			memberDAO.addMember(memberVO);
			request.setAttribute("msg", "addMember");
			nextPage = "/member/listMembers.do";
			
		} else if (action.equals("/memberForm.do")) {
			nextPage = "/test03/memberForm.jsp";
			
		}else if(action.equals("/modMemberForm.do")){ // 회원 수정창 요청 시 ID로 회원정보를 조회한 후 수정창으로 포워딩한다.
		     String id=request.getParameter("id");
		     MemberVO memInfo = memberDAO.findMember(id); // 회원 정보 수정창을 요청하면서 전송된 ID를 이용해 수정 전 회원 정보를 조회한다.
		     request.setAttribute("memInfo", memInfo); // request에 바인딩하여 회원 정보 수정창에 수정하기 전 회원 정보를 전달한다.
		     nextPage="/test03/modMemberForm.jsp";
		     
		}else if(action.equals("/modMember.do")){ // 테이블의 회원 정보를 수정한다.
		     String id=request.getParameter("id");
		     String pwd=request.getParameter("pwd");
		     String name= request.getParameter("name");
	         String email= request.getParameter("email"); // 회원 정보 수정창에서 전송된 수정 회원 정보를 가져온 후 MemberVO 객체 속성에 설정한다.
		     MemberVO memberVO = new MemberVO(id, pwd, name, email);
		     memberDAO.modMember(memberVO);
		     request.setAttribute("msg", "modified"); // 회원 목록창으로 수정 작업 완료 메시지를 전달한다.
		     nextPage="/member/listMembers.do";
		     
		}else if(action.equals("/delMember.do")){ // 회원 ID를 SQL문으로 전달해 테이블의 회원 정보를 삭제한다.
		     String id=request.getParameter("id"); // 삭제할 회원 ID를 받아온다.
		     memberDAO.delMember(id);
		     request.setAttribute("msg", "deleted"); // 회원 목록 창으로 삭제 작업 완료 메시지를 출력한다.
		     nextPage="/member/listMembers.do";
		     
		}else {
			List<MemberVO> membersList = memberDAO.listMembers();
			request.setAttribute("membersList", membersList);
			nextPage = "/test03/listMembers.jsp";
		}
		RequestDispatcher dispatch = request.getRequestDispatcher(nextPage);
		dispatch.forward(request, response);
	}

}

3. MemberDAO 클래스를 다음과 같이 작성한다. 회원 ID를 이용해 회원 정보를 조회하고, 수정 회원 정보를 갱신하고, 회원 ID로 회원 정보를 삭제하는 메서드를 추가한다.

package sec02.ex02;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class MemberDAO {
	private DataSource dataFactory;
	private Connection conn;
	private PreparedStatement pstmt;

	public MemberDAO() {
		try {
			Context ctx = new InitialContext();
			Context envContext = (Context) ctx.lookup("java:/comp/env");
			dataFactory = (DataSource) envContext.lookup("jdbc/oracle");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<MemberVO> listMembers() {
		List<MemberVO> membersList = new ArrayList();
		try {
			conn = dataFactory.getConnection();
			String query = "select * from t_member order by joinDate desc";
			System.out.println(query);
			pstmt = conn.prepareStatement(query);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next()) {
				String id = rs.getString("id");
				String pwd = rs.getString("pwd");
				String name = rs.getString("name");
				String email = rs.getString("email");
				Date joinDate = rs.getDate("joinDate");
				MemberVO memberVO = new MemberVO(id, pwd, name, email, joinDate);
				membersList.add(memberVO);
			}
			rs.close();
			pstmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return membersList;
	}

	public void addMember(MemberVO m) {
		try {
			conn = dataFactory.getConnection();
			String id = m.getId();
			String pwd = m.getPwd();
			String name = m.getName();
			String email = m.getEmail();
			String query = "INSERT INTO t_member(id, pwd, name, email)" + " VALUES(?, ? ,? ,?)";
			System.out.println(query);
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.setString(2, pwd);
			pstmt.setString(3, name);
			pstmt.setString(4, email);
			pstmt.executeUpdate();
			pstmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public MemberVO findMember(String _id) {
		MemberVO memInfo = null;
		try {
			conn = dataFactory.getConnection();
			String query = "select * from t_member where id = ?"; // 전달된 ID로 회원 정보를 조회한다.
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, _id);
			System.out.println(query);
			ResultSet rs = pstmt.executeQuery();
			rs.next();
			String id = rs.getString("id");
			String pwd = rs.getString("pwd");
			String name = rs.getString("name");
			String email = rs.getString("email");
			Date joinDate = rs.getDate("joinDate");
			memInfo = new MemberVO(id, pwd, name, email, joinDate);
			pstmt.close();
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return memInfo;
	}

	public void modMember(MemberVO memberVO) {
		String id = memberVO.getId();
		String pwd = memberVO.getPwd();
		String name = memberVO.getName();
		String email = memberVO.getEmail();
		try {
			conn = dataFactory.getConnection();
			String query = "update t_member set pwd=?, name=?, email=? where id=?"; // 전달된 수정 회원 정보를 update문을 이용해 수정한다.
			System.out.println(query);
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, pwd);
			pstmt.setString(2, name);
			pstmt.setString(3, email);
			pstmt.setString(4, id);
			pstmt.executeUpdate(); // SQL문을 실행한다.
			pstmt.close();
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void delMember(String id) {
		try {
			conn = dataFactory.getConnection();
			String query = "delete from t_member where id=?";
			System.out.println(query); // delete문을 이용해 전달된 ID의 회원 정보를 삭제한다.
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.executeUpdate(); // SQL문을 실행한다.
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

4. listMembers.jsp를 다음과 같이 작성한다. 회원 추가, 수정, 삭제 작업 후에 다시 회원 목록 창을 요청할 경우 컨트롤러에서 가져온 msg 값에 따라 작업 결과를 alert 창에 출력한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"
	isELIgnored="false" 
%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<%
	request.setCharacterEncoding("UTF-8");
	// 회원 추가, 수정, 삭제 작업 후 컨트롤러에서 넘긴 msg 값에 따라 작업 결과를 alert 창에 출력한다.
%>
<html lang="ko">

    <head>
        <c:choose>
            <c:when test='${msg=="addMember" }'>
                <script>
                    window.onload = function() {
                        alert("회원을 등록했습니다.");
                    }
                </script>
            </c:when>
            <c:when test='${msg=="modified" }'>
                <script>
                    window.onload = function() {
                        alert("회원 정보를 수정했습니다.");
                    }
                </script>
            </c:when>
            <c:when test='${msg=="deleted" }'>
                <script>
                    window.onload = function() {
                        alert("회원 정보를 삭제했습니다.");
                    }
                </script>
            </c:when>
        </c:choose>

        <meta charset="UTF-8">
        <title>회원 정보 출력창</title>
        <style>
            .cls1 {
                font-size: 40px;
                text-align: center;
            }

            .cls2 {
                font-size: 20px;
                text-align: center;
            }
        </style>

    </head>

    <body>
        <p class="cls1">회원정보</p>
        <table align="center" border="1">
            <tr align="center" bgcolor="lightgreen">
                <td width="7%"><b>아이디</b></td>
                <td width="7%"><b>비밀번호</b></td>
                <td width="7%"><b>이름</b></td>
                <td width="7%"><b>이메일</b></td>
                <td width="7%"><b>가입일</b></td>
                <td width="7%"><b>수정</b></td>
                <td width="7%"><b>삭제</b></td>

            </tr>

            <c:choose>
                <c:when test="${empty  membersList}">
                    <tr>
                        <td colspan="5">
                            <b>등록된 회원이 없습니다.</b>
                        </td>
                    </tr>
                </c:when>
                <c:when test="${!empty membersList}">
                    <c:forEach var="mem" items="${membersList }">
                        <tr align="center">
                            <td>${mem.id }</td>
                            <td>${mem.pwd }</td>
                            <td>${mem.name}</td>
                            <td>${mem.email }</td>
                            <td>${mem.joinDate}</td>
                            <%-- ID를 전달해 수정과 삭제를 요청한다. --%>
                            <td><a href="${contextPath}/member/modMemberForm.do?id=${mem.id }">수정</a></td>
                            <td><a href="${contextPath}/member/delMember.do?id=${mem.id }">삭제</a></td>
                        </tr>
                    </c:forEach>
                </c:when>
            </c:choose>
        </table>
        <a href="${contextPath}/member/memberForm.do">
            <p class="cls2">회원 가입하기</p>
        </a>
    </body>

</html>

5. modMemberForm.jsp를 다음과 같이 작성한다. 회원 정보 수정창에서 수정된 회원 정보를 입력하고 수정하기를 클릭하면 action 속성에 설정한 요청명 /member/modMember.do와 회원 ID를 전달해 수정을 요청하도록 구현한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8"
    isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<%
  request.setCharacterEncoding("UTF-8");
%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>회원 정보 수정창</title>
        <style>
            .cls1 {
                font-size: 40px;
                text-align: center;
            }
        </style>
    </head>

    <body>
        <h1 class="cls1">회원 정보 수정창</h1>
        <%-- 수정하기 클릭 시 컨트롤러에서 /member/modMember.do로 요청한다. --%>
        <form method="post" action="${contextPath}/member/modMember.do?id=${memInfo.id}">
            <table align="center">
                <tr>
                    <td width="200">
                        <p align="right">아이디</p>
                    </td>
                    <td width="400"><input type="text" name="id" value="${memInfo.id}" disabled></td> <%-- 조회한 회원 정보를 텍스트 박스에 표시한다. --%>

                </tr>
                <tr>
                    <td width="200">
                        <p align="right">비밀번호</p>
                    </td>
                    <td width="400"><input type="password" name="pwd" value="${memInfo.pwd}"> <%-- 조회한 회원 정보를 텍스트 박스에 표시한다. --%>
                    </td>
                </tr>
                <tr>
                    <td width="200">
                        <p align="right">이름</p>
                    </td>
                    <td width="400"><input type="text" name="name" value="${memInfo.name}"></td>
                </tr>
                <tr>
                    <td width="200">
                        <p align="right">이메일</p>
                    </td>
                    <td width="400"><input type="text" name="email" value="${memInfo.email}"></td>
                </tr>
                <tr>
                    <td width="200">
                        <p align="right">가입일</p>
                    </td>
                    <td width="400"><input type="text" name="joinDate" value="${memInfo.joinDate }" disabled></td>
                </tr>
                <tr align="center">
                    <td colspan="2" width="400"><input type="submit" value="수정하기">
                        <input type="reset" value="다시입력">
                    </td>
                </tr>
            </table>
        </form>
    </body>

</html>

6. 회원 목록창에서 차두리의 회원 정보를 수정해 보자. "수정"을 클릭하여 http://localhost8090/pro17/member/modMemberForm.do 로 요청한다.

- http://localhost:8090/pro17/member/listMembers.do

7. 회원 정보 수정창이 나타난다. 차두리의 회원 정보(비밀번호, 이메일 주소)를 다음과 같이 수정하고 "수정하기"를 클릭한 후 http://localhost8090/pro17/member/modMember.do로 요청한다.

8. '수정 완료' 메시지가 나타나고 다음과 같이 수정된 회원 목록을 표시한다. 차두리의 회원 정보가 제대로 수정된 모습을 볼 수 있다.

9 이번에는 차두리의 회원 정보를 삭제해 보자. 다음과 같이 삭제를 클릭한다.

10. 그러면 '삭제 완료' 메시지가 나타난 후 다시 회원 목록을 표시한다. 목록에서 차두리가 사라진 것을 볼 수 있다.

* 지금까지 커맨드 패턴을 이용해 기본적인 회원 관리 기능, 즉 조회부터 추가, 수정 및 삭제까지 MVC로 구현해 봤다. 다음에는 JSP 학습의 마지막 과정으로 이제까지 배운 모든 서블릿과 JSP 기능을 활용하여 모델2 기반의 답변형 게시판을 구현해 보자.