본문 바로가기
👨‍💻 2. 웹개발_Back end/2-4 JSP & Servlet

[JSP & Servlet] 5장 MVC 아키텍처 (4) - 뷰와 서블릿 분리 및 JSP 컨텍스트와 Action Tag

by 달님🌙 2021. 10. 14.
반응형

 

뷰와 서블릿 분리 

 

실습1) 뷰와 서블릿 분리 - 회원 등록

MemberAddServlet.java 두 부분 주석 처리

package spms.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

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

/**
 * Servlet implementation class MemberAddServlet
 */
@WebServlet("/member/add")
//HttpServlet은 GenericServlet을 상속받은 클래스
//service() 메소드를 호출방식에 따라 doGet(), doPost(), doPut(), doDelete()로 분리해놓음
public class MemberAddServlet extends HttpServlet {
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	//url에 주소 직접 입력 후 접속, 링크로 걸려있는 주소로 접속 -> get방식
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		RequestDispatcher rd = request.getRequestDispatcher("/member/MemberForm.jsp");
		
		/* 이 부분 주석 처리 */
		//		response.setContentType("text/html;charset=UTF-8");
//		PrintWriter out = response.getWriter();
//		
//		out.println("<html><head><title>회원등록</title></head>");
//		out.println("<body><h1>회원등록</h1>");
//		out.println("<form action='add' method='post'>");
//		out.println("이름 : <input type='text' name='name'><br>");
//		out.println("이메일 : <input type='text' name='email'><br>");
//		out.println("암호 : <input type='password' name='password'><br>");
//		out.println("<input type='submit' value='추가'>");
//		out.println("<input type='reset' value='취소'>");
//		out.println("</form></body></html>");
	}
	
	//입력폼에 입력된 정보를 submit할때 method 방식이 post이므로
	//doPost에서 데이터 입력 처리
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//request.setCharacterEncoding("UTF-8");
		
		Connection conn = null;
		PreparedStatement stmt = null;
		String sqlInsert = "INSERT INTO MEMBERS(EMAIL, PWD, MNAME, CRE_DATE, MOD_DATE)" + 
						   "VALUES(?, ?, ?, NOW(), NOW())";
		
		ServletContext sc = this.getServletContext();
//		String driver = sc.getInitParameter("driver");
//		String url = sc.getInitParameter("url");
//		String id = sc.getInitParameter("username");
//		String pw = sc.getInitParameter("password");
		
		try {
			//DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
//			Class.forName(driver);
//			conn = DriverManager.getConnection(url, id, pw);
			conn = (Connection)sc.getAttribute("conn");
			stmt = conn.prepareStatement(sqlInsert);
			stmt.setString(1, request.getParameter("email"));
			stmt.setString(2, request.getParameter("password"));
			stmt.setString(3, request.getParameter("name"));
			stmt.executeUpdate();
			
			//sendRedirect 밑의 결과 값 출력 안하고 바로 /member/list로 이동
			response.sendRedirect("list");
			
			/* 이 부분 주석 처리 */
//			response.setContentType("text/html;charset=UTF-8");
//			PrintWriter out = response.getWriter();
//			out.println("<html><head><title>회원등록결과</title>");
//			out.println("<meta http-equiv='Refresh' content='1; url=list'></head>");
//			out.println("<body><p>등록성공입니다!</p></body></html>");
			
			//응답헤더에 리프레쉬 정보를 추가
			//1초 후에 url=list로 보내라
			//response.addHeader("Refresh", "1;url=list");
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(stmt != null) {
					stmt.close();
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
			
			try {
				if(conn != null) {
					conn.close();
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}

 

MemberForm.jsp 파일 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 등록</title>
</head>
<body>
	<jsp:include page="/Header.jsp"/>
	<h1>회원 등록</h1>
	<form action="add" method="post">
		이름 : <input type="text" name="name"><br>
		이메일 : <input type="text" name="email"><br>
		암호 : <input type="password" name="password"><br>
		<input type="submit" value="추가">
		<input type="reset" value="취소">
	</form>
	<jsp:include page="/Tail.jsp"/>
</body>
</html>

 

실행 화면

새로운 회원이 추가됨

 

실습2) 뷰와 서블릿 분리 - 업데이트

MemberUpdateForm.jsp 파일 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <jsp:useBean id="member" scope="request" class="spms.vo.Member"></jsp:useBean>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보</title>
</head>
<body>
	<h1>회원 정보</h1>
	<form action="update" method="post">
		번호 : <input type="text" name="no" value="<%=member.getNo() %>" readonly><br>
		이름 : <input type="text" name="name" value="<%=member.getName() %>"><br>
		이메일 : <input type="text" name="email" value="<%=member.getEmail() %>"><br>
		가입일 : <%=member.getCreateDate() %><br>
		<input type="submit" value="저장">
		<input type="button" value="삭제" onclick="location.href='delete?no<%=member.getNo() %>';">
		<input type="button" value="취소" onclick="location.href='list';">

</body>
</html>

 

MemberUpdateServlet.java 파일 수정

/**
 * Servlet implementation class MemberUpdateServlet
 */
@WebServlet("/member/update")
public class MemberUpdateServlet extends HttpServlet {
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		String no = request.getParameter("no");
		String sqlSelect = "SELECT * FROM MEMBERS WHERE MNO = " + no;
		

		//서블릿 컨텍스트 객체 생성
		ServletContext sc = this.getServletContext();
		
		//컨텍스트 초기화 매개변수 꺼내 쓰기 -> sc.getIninParameter메소드로 접근
//		String driver = sc.getInitParameter("driver");
//		String url = sc.getInitParameter("url");
//		String id = sc.getInitParameter("username");
//		String pwd = sc.getInitParameter("password");
		
		try {
			//mysql 제어 객체 로딩
//			Class.forName(driver);
//			conn = DriverManager.getConnection(url, id, pwd);
			//servletcontext 데이터 보관소에 저장되어 있는 Connection 객체를 꺼내 씀
			conn = (Connection)sc.getAttribute("conn");
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sqlSelect);
			if(rs.next()) {
				request.setAttribute("member", new Member()
															.setNo(rs.getInt("mno"))
															.setEmail(rs.getString("email"))
															.setName(rs.getString("mname"))
															.setCreateDate(rs.getDate("cre_date")));
			} else {
				throw new Exception("해당 번호의 회원을 찾을 수 없습니다.");
			}
			
			RequestDispatcher rd = request.getRequestDispatcher("/member/MemberUpdateForm.jsp");
			rd.forward(request, response);
//			response.setContentType("text/html;charset=UTF-8");
//			PrintWriter out = response.getWriter();
//			out.println("<html><head><title>회원정보</title></head>");
//			out.println("<body><h1>회원정보</h1>");
//			out.println("<form action='update' method='post'>");
//			out.println("번호 : <input type='text' name='no' value='" + no + "' readonly> <br>");
//			out.println("이름 : <input type='text' name='name' value='" + rs.getNString("mname") + "'> <br>");
//			out.println("이메일 : <input type='text' name='email' value='" + rs.getNString("email") + "'> <br>");
//			out.println("가입일 : " + rs.getDate("cre_date") + "<br>");
//			out.println("<input type='submit' value='저장'>");
//			out.println("<input type='button' value='취소' onclick='location.href=\"list\"'>");
//			out.println("</form></body></html>");
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs != null) {
					rs.close();
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
			
			try {
				if(stmt != null) {
					stmt.close();
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//request.setCharacterEncoding("UTF-8");
		
		Connection conn = null;
		PreparedStatement stmt = null;
		String sqlUpdate = "UPDATE MEMBERS SET EMAIL=?, MNAME=?, MOD_DATE=NOW() WHERE MNO=?";
		
		//서블릿 컨텍스트 객체 생성
		ServletContext sc = this.getServletContext();
		
		String driver = sc.getInitParameter("driver");
		String url = sc.getInitParameter("url");
		String id = sc.getInitParameter("username");
		String pwd = sc.getInitParameter("password");
		
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, id, pwd);
			stmt = conn.prepareStatement(sqlUpdate);
			stmt.setString(1, request.getParameter("email"));
			stmt.setString(2, request.getParameter("name"));
			stmt.setInt(3, Integer.parseInt(request.getParameter("no")));
			stmt.executeUpdate();
			
			response.sendRedirect("list");
		} catch(Exception e) {
			e.printStackTrace();
		} finally {			
			try {
				if(stmt != null) {
					stmt.close();
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

}

 

실행 화면

- 이름 링크 클릭하면 업데이트 페이지로 이동

 

- 이름과 이메일 수정 후 저장 버튼 클릭

- 취소 버튼 클릭시 다시 회원 목록 페이지로 이동

 

- 회원 목록 페이지로 이동 및 정보 수정된 것을 확인

 

- 삭제 버튼 클릭하면 데이터가 바로 삭제 됨

 

9. JSP 컨텍스트

 

- 태그핸들러에 의해 처리 : jspcontext 데이터 보관소에 올라간다. 

-jsp:include 같은 태그들을 말함

MemberList.jsp

<body>
	<!-- 태그핸들러에 의해 처리 : jspcontext 데이터 보관소에 올라간다. -->
	<jsp:include page="/Header.jsp"/>
	<h1>회원 목록</h1>
	<p><a href="add">신규 회원</a></p>
	<%
		//MemberListServlet에서 request.setAttribute로 전달한 결과 값 꺼내쓰기
		ArrayList<Member> members = (ArrayList<Member>)request.getAttribute("memberList");
		for(Member member : members) {
	%>
	<%=member.getNo() %>,
	<a href="update?no=<%=member.getNo()%>"><%=member.getName() %></a>,
	<%=member.getEmail() %>,
	<%=member.getCreateDate() %>
	<a href="delete?no=<%=member.getNo()%>">삭제</a><br>
	<%} %>
	<jsp:include page="/Tail.jsp"/>
</body>

 

 

10. JSP Action Tag

 

MemberList.jsp

- Action Tag를 사용하여 자바코드를 줄일 수 있음

<%@ page import="spms.vo.Member"%>
<%@ page import="java.util.ArrayList" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 목록</title>
</head>
<body>
	<!-- jsp action tag 
		jsp:useBean, jsp:setProperty, jsp:getProperty, jsp:forward, jsp:include.....
		actiontag를 이용하면 jsp의 자바 소스를 줄일 수 있다 
	-->
	<jsp:include page="/Header.jsp"/>
	<h1>회원 목록</h1>
	<p><a href="add">신규 회원</a></p>
	<!-- servletrequest 데이터 보관소에서 memberList라는 객체를 꺼내옴 -->
	<!-- id : 사용할 객체 이름 -->
	<!-- scope : 어느 데이터 보관소에서 객체를 꺼내올지 결정 
				 request(servletrequest 데이터 보관소), 
				 session(HttpSession 데이터 보관소),
				 application(Servletcontext 데이터 보관소) -->
	<jsp:useBean id="members" 
				 scope="request" 
				 class="java.util.ArrayList" 
				 type="java.util.ArrayList<spms.vo.Member>"></jsp:useBean>
	<%
		//MemberListServlet에서 request.setAttribute로 전달한 결과 값 꺼내쓰기
		//ArrayList<Member> members = (ArrayList<Member>)request.getAttribute("memberList");
		for(Member member : members) {
	%>
	<%=member.getNo() %>,
	<a href="update?no=<%=member.getNo()%>"><%=member.getName() %></a>,
	<%=member.getEmail() %>,
	<%=member.getCreateDate() %>
	<a href="delete?no=<%=member.getNo()%>">삭제</a><br>
	<%} %>
	<jsp:include page="/Tail.jsp"/>
</body>
</html>

 

Header.jsp

<%@ page import="spms.vo.Member" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!-- servletrequest 데이터 보관소에서 memberList라는 객체를 꺼내옴 -->
    <!-- id : 사용할 객체 이름 -->
    <!-- scope : 어느 데이터 보관소에서 객체를 꺼내올지 결정 
				 request(servletrequest 데이터 보관소), 
				 session(HttpSession 데이터 보관소),
				 application(Servletcontext 데이터 보관소) -->
<jsp:useBean id="member" 
			 scope="session" 
			 class="spms.vo.Member">
</jsp:useBean>    
 
<%
	//HttpSession 데이터 보관소에 저장된 member 객체 꺼내서 사용
	//Member member = (Member)session.getAttribute("Member");
%>
<div style="background-color:#00008b; color:#ffffff; height:20px; padding:5px">
SPMS(Simple Project Management System)
<span style="float:right;">
	<%=member.getName() %>
	<a style="color:white;" href="<%=request.getContextPath() %>/auth/logout">로그아웃</a>
</span>
</div>

 

11. EL (Expression Language) 표기법

 

1) 개념

- EL(Expression Language) : 데이터 보관소에 들어있는 객체나, 리스트 또는 맵 등에 접근할 수 있다.

- actiontag를 사용하는 것보다 훨씬 간편하게 사용할 수 있어서 자주 사용됨 

 

2) 사용법

- 사용법1 : ${member.no} or ${member["no"]}

따로 scope를 지정하지 않기 때문에

jspContext -> ServletRequest -> HttpSession -> ServletContext순으로 데이터 검색

 

- 사용법2 : ${requestScope.member.no} or ${requestScope.member["no"]}

scope 지정방식

 

2) 실습

MemberUpdateForm.jsp - actiontag 지우고 EL표기법으로 변경

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보</title>
</head>
<body>
	<!-- EL(Expression Language)
		  : 데이터 보관소에 들어있는 객체나, 리스트 또는 맵 등에 접근할 수 있다.
		   actiontag를 사용하는 것보다 훨씬 간편하게 사용할 수 있어서 자주 사용됨 
		     사용법1 : ${member.no} or ${member["no"]}
		     따로 scope를 지정하지 않기 때문에 jspContext -> ServletRequest -> HttpSession -> ServletContext순으로 데이터 검색 
		     사용법2 : ${requestScope.member.no} or ${requestScope.member["no"]} 
		   scope 지정방식 -->
	<h1>회원 정보</h1>
	<form action="update" method="post">
		번호 : <input type="text" name="no" value="${member.no }" readonly><br>
		이름 : <input type="text" name="name" value="${member.name }"><br>
		이메일 : <input type="text" name="email" value="${member.email }"><br>
		가입일 : ${member.createDate }<br>
		<input type="submit" value="저장">
		<input type="button" value="삭제" onclick="location.href='delete?no=${member.no }';">
		<input type="button" value="취소" onclick="location.href='list';">

</body>
</html>

 

실행 화면

- 이름 클릭

 

- 이름 수정 후 저장

 

- 이름 변경된 것을 확인

 

12. JSTL 

 

1) 개념

- JSTL (JSP Standard Tag Library) : JSP 확장 라이브러리로 리스트나 배열 표출 시 자주 사용
- JSP에서 기본적으로 제공해주지 않기 때문에 taglib 링크를 걸어서 사용

 

2) 종류     

 

c:out : 출력문을 위한 태그

<c:out value="출력할 값">


     

 c:if : 조건문을 위한 태그

<c:if test="조건" var="변수명" scope="request|session|application">

 

c:choose : case-when 문법

<c:choose
      c:when test="참/거짓"
      c:when test="참/거짓"
      ....>

 

c:foreach : 반복적인 작업을 위한 태그

<c:foreach var="변수명" items="목록데이터" begin="시작" end="끝">

 

3) JSTL 실습

라이브러리 폴더에 파일 붙여넣기

 

MemberList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 목록</title>
</head>
<body>
	<!-- JSTL(JSP Standard Tag Library) : JSP 확장 라이브러리로 리스트나 배열 표출 시 자주 사용
										  JSP에서 기본적으로 제공해주지 않기 때문에 taglib 링크를 걸어서 사용
										  c:out : 출력문을 위한 태그
										  			c:out value="출력할 값"
										  c:if : 조건문을 위한 태그
										  		 c:if test="조건" var="변수명" scope="request|session|application"
										  c:choose : case-when 문법
										  			 c:choose
										  			 	c:when test="참/거짓"
										  			 	c:when test="참/거짓"
										  			 	....
										  c:foreach : 반복적인 작업을 위한 태그
										  			  c:foreach var="변수명" items="목록데이터" begin="시작인덱스" end="종료인덱스"-->
	<jsp:include page="/Header.jsp"/>
	<h1>회원 목록</h1>
	<p><a href="add">신규 회원</a></p>
	<!-- memberList라는 객체를 데이터 저장소에서 꺼냄
	     foreach문에서 memberList에 담겨있는 내용을 member라는 변수로 담아서 하나씩 사용하겠다 -->
	<c:forEach var="member" items="${memberList }">
	${member.no },
	<a href="update?no=${member.no }">${member.name }</a>,
	${member.email },
	${member.createDate }
	<a href="delete?no=${member.no }">삭제</a><br>
	</c:forEach>
	<jsp:include page="/Tail.jsp"/>
</body>
</html>

 

실행 화면 (로그인 -> 회원목록 페이지 뜨기)

 

 

반응형

댓글