today_is

[ jsp ] MVC 패턴 본문

java

[ jsp ] MVC 패턴

ye_rang 2023. 12. 24. 22:59

오늘의 목표

먼저 MVC패턴의 장점을 배우고, 목적에 맞게 로직을 분리해보자 

 


 

 JSP (model 1 의 장단점) 

장점
1) HTML 과 Java 코드를 함께 사용할 수 있다


2) Java 코드를 편리하게 사용하기 위한 라이브러리가 있다

: EL 태그 / JSTL 태그


3) 개발 로직과 화면 구성을 동시에 수행할 수 있다



단점
1) 사이트 규모가 커지면, 파일 관리가 어려워진다


2) 개발 로직과 화면 구성을 동시에 수행할 수 있다

:  유지 보수가 까다로움


3) HTML과 Java 코드를 분리하여 처리 및 표현을 별도로 개발하는 편이 더 좋다
: MVC패턴을 사용하는 궁극적 이유 !!


 MVC 패턴 사용이유 

1)  모델과 뷰의 분리
: 무조건 사용자가 직접 DB에 접근할 수 있으면 안되기 때문

모델은 데이터, 뷰는 보이는 화면을 의미

 

 

2) 유지보수 편리 
: 모델과 뷰를 분리시켜서 컨트롤러에서 통제하게 만들기 위해서이다.
 (사용자는 항상 프로그램을 통해서 데이터에 접근하고 처리)

 

 

MVC패턴의 형태 

: Model-View-Controller 가 분리되어 있는 형태

Model(Database)
View(HTML)
Controller(Java)

 

 


 

Servlet 을 사용하는 Model2 방식

 

Ex02Servlet

: 1 ~ 100까지의 랜덤 정수 2개를 생성하여, 두 정수의 합계가 나온다

 

 

이 결과값을 ex02.jsp 에 전달하여 출력해보자 !

package day22;

import java.io.IOException;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Ex02Servlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Random ran = new Random();
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		
		int n1 = ran.nextInt(100) + 1;
		int n2 = ran.nextInt(100) + 1;
		
		String data = String.format("%d + %d = %d", n1, n2, n1 + n2);
		
		
		//	요청은 서블릿이 받았지만, 응답은 JSP가 함
		//	JSP로 넘겨주기 전에, 서블릿에서 생성한 데이터를 넘겨준다
		
		//	jsp의 경로를 WEB-INF 아래에 넣어두면
		//  단독 실행은 불가능하지만 포워드는 가능
		req.setAttribute("data", data);
		req.getRequestDispatcher("/WEB-INF/views/ex02.jsp").forward(req, resp);
	}
}

 

 

 

ex02.jsp

: Ex02Servlet 에서 넘겨준 데이터를 받아서 출력

 

 

 유의할점 

 

: 이 페이지를 실행하면 원하는 결과값이 안뜬다 !
url에 .jsp 를 지우고 enter

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>


<h1>서블릿에서 넘겨준 데이터를 화면에 출력하기</h1>
<hr>

<h3>${data }</h3>



</body>
</html>

 

 


 

 

Ex03Servlet

[ doGet ] 은 기본값 . ex03-form을 실행할 때

: 별도의 데이터 처리가 없는 상황

 

[ doPost ] 는 ex03-form에 있는 form을 제출할 때

: form을 제출함으로써, 데이터의 처리가 일어나야하는 상황

package day22;

import java.io.IOException;

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

@WebServlet("/ex03")
public class Ex03Servlet extends HttpServlet {
	
	
	private static final long serialVersionUID = 1L;
	
	private final String prefix = "/WEB-INF/views/";
	private final String suffix = ".jsp";
	
	
	//	서블릿은 요청메서드에 따라 doGet 및 doPost 함수를 별도로 사용할 수 있다

	
	@Override	//	처리 내용 없이 JSP만 보여주면 된다 (곧바로 포워드)
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String viewName = "ex03-form";
		req.getRequestDispatcher(prefix + viewName + suffix).forward(req, resp);
	}
	
	
	@Override	//	처리만 수행하고 JSP로 넘기지 않는다 (다른 주소로 리다이렉트)
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		String userid = req.getParameter("userid");
		String userpw = req.getParameter("userpw");
		HttpSession session = req.getSession();
		
		if("test".equals(userid) && "1234".equals(userpw)) {
			session.setAttribute("login", "테스트");
		}
		String cpath = req.getContextPath();
		resp.sendRedirect(cpath + "/ex03");
	}

}

 

 

 

ex03-form.jsp

[ 로그인이 되어있지 않을때 ] userid 와 userpw 를 입력하여 로그인 시도

[ 로그인이 되어있을때 ] ${login} 님 안녕하세요 + 로그아웃 버튼

 

 

로그인 성립 조건 

: Ex03Servlet 를 참고

 

if("test".equals(userid) && "1234".equals(userpw)) {
session.setAttribute("login", "테스트");
}

 

userid 가 test 이면서

userpw 가 1234 일때만 로그인 성공

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>


<h1>서블릿 활용 로그인 테스트</h1>
<hr>

<c:if test="${empty login }">
	<form method="POST">
		<p><input type="text" name="userid" placeholder="ID" required autofocus></p>
		<p><input type="password" name="userpw" placeholder="Password" required></p>
		<p><input type="submit" value="로그인"></p>
	</form>
</c:if>


<c:if test="${not empty login }">
	<h3>${login }님 안녕하세요</h3>
	<c:set var="cpath" value="${pageContext.request.contextPath }" />
	<a href="${cpath }/logout"><button>로그아웃</button></a>
</c:if>

<!--   라이브러리 파일 넣기  -->

</body>
</html>

 

 


 

Study_review

오늘은 정보처리기사 필기를 공부했을때 알게되었던 MVC패턴을 직접 실습해보았다 

 

용어로만 접했던 MVC패턴은 단순하게 로직을 분리시켜서 유지보수를 높인다는 것 밖에 몰랐었다..

 

 

근데 사실 이 부분은 의문점이 많았다.

 

로직을 분리시키면 관리해야할 페이지도 많아지게 되는 셈인데

 

어떤 의미에서 유지보수가 높아진다는건지 잘 와닿지 않았었다.

 

 

 

그러나, 목적에 맞게 실질 데이터(model)와 보여질 화면(view), 데이터를 처리하는 역할(controller) 을 분리하면

 

해당 페이지가 처리해야하는 기능은 1개가 된다.

 

 

한 사람이 여러개의 기능을 처리하는 것보다 한사람당 한개씩 기능을 처리하는게 수월하고 관리도 용이한것처럼

 

코드도 목적에 맞게 로직을 분리하는것이 좋다는 생각이 확 와닿았다

 

 

 

어려웠던 부분

doGet 과 doPost 를 왜 굳이 나누어서 쓰는지 이해가 가지 않아서 헤맸는데,

form을 제출하기전과 제출하고 나서를 분리시켜서 생각했더니 그 뒤로는 이해가 쉽게 되었다. 

 

오늘의 중점적인 키워드는 '분리' 인듯하다 !!