본문 바로가기
Develop/Java

[MVC패턴] 회원 관리 웹 애플리케이션

by 연로그 2021. 5. 10.
반응형

예제에 들어가기 앞서 MVC 패턴에 대해 간단히 설명하겠다.

MVC 패턴

  • 프로젝트 구성 요소를 Model, View, Controller 3가지로 나눈 패턴
  • Model: View에 출력할 데이터 담아두기
  • View: Model에 담긴 데이터를 사용해 화면 그려내기
  • Controller: HTTP 요청을 받아 파라미터 검증 및 비즈니스 로직 실행. View에 전달할 결과 데이터를 Model에 담기

기본적으로 나는 일단 코딩하고 개념을 찾아보는 편이라... 자세한 설명은 생략한다.

이후에 MVC 패턴에 대해 따로 공부하는 것을 추천한다.

 

회원 관리 웹 애플리케이션의 요구사항

  • 회원 저장
  • 회원 목록 조회

 

회원 관리 웹 애플리케이션 코드 비교

  1. Servlet: yeonyeon.tistory.com/100
  2. JSP: yeonyeon.tistory.com/101

 

아래 코드들은 Servlet과 JSP를 이용해 MVC 패턴을 적용해보았다.

(본격적인 MVC 프레임워크 사용이나 스프링 MVC는 이후 적용할 예정)

 

main/.../servletmvc 폴더를 생성하고 이 안에 서블릿 파일들을 넣는다.

webapp/WEB-INF/view 폴더를 생성하고 이 안에 jsp 파일들을 넣는다.

 

WEB-INF 폴더에 관해 ▼

더보기

WEB-INF는 외부에서 직접 호출이 불가능하게 하기 위한 일종의 약속이다.

 

예를 들어, localhost:8080/파일.jsp 는 직접 링크를 입력해서 접근할 수 있다.

하지만 파일.jsp를 WEB-INF 안에 넣는다면?

localhost:8080/WEB-INF/파일.jsp 링크를 입력해도 접근이 불가능하다.

 

Controller를 이용해 WEB-INF/파일.jsp에는 접근이 가능하지만, 직접 도메인을 입력하면 접근이 불가능하다.

 

MvcMemberFormServlet.java

@WebServlet(name = "mvcMemberFormSerlvet", urlPatterns = "/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet{
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		String viewPath = "/WEB-INF/views/new-form.jsp";
		RequestDispatcher dispatcher = req.getRequestDispatcher(viewPath);
		dispatcher.forward(req, res);
	}
}
  • /servlet-mvc/members/new-form을 통해 접근 가능
  • /WEB-INF/views/new-form.jsp으로 접근
  • req.getRequestDispatcher(): 다른 servlet 또는 JSP로 이동 가능
  • dispatcher.redirect(): 클라이언트에 응답이 갔다가 redirect 경로로 다시 요청
  • dispatcher.forward(): 서버 내부에서 호출하고 끝. 클라이언트가 인지할 수 X

 

new-form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
 	<title>Title</title>
</head>
<body>
<!-- 	<form action="/servlet-mvc/members/save" method="post"> -->
	<form action="save" method="post">
		username: <input type="text" name="username" />
		age: <input type="text" name="age" />
	 	<button type="submit">전송</button>
	</form>
</body>
</html>
  • 이후 예시에서 재사용을 위해 save라는 상대 경로를 썼지만 주석처럼 절대 경로를 쓰는 것이 좋다

 

멤버 저장과 멤버 목록 출력도 위와 같은 양식으로 생성한다.

똑같은 방식으로 코드를 복붙하는 꼴이 되니 자세한 설명은 생략한다.

 

MvcMemberSaveServlet.java

@WebServlet(name = "mvcMemberSaveSerlvet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet{
	
	MemberRepository memberRepository = MemberRepository.getInstance();
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		String username = req.getParameter("username");
		int age = Integer.parseInt(req.getParameter("age"));
		
		Member member = new Member(username, age);
		memberRepository.save(member);
		
		// Model에 데이터 보관
		req.setAttribute("member", member);
		
		String viewPath = "/WEB-INF/views/save-result.jsp";	// WEB-INF 이하의 자원들은 외부의 직접 호출 X. 컨트롤러 통해서 호출 O. 
		RequestDispatcher dispatcher = req.getRequestDispatcher(viewPath); // 다른 servlet이나 JSP로 이동 가능
		dispatcher.forward(req, res);	// redirect: 클라이언트가 다시 요청. forward: 서버에서 호출하고 끝. 클라이언트가 인지 x.
	}
}

 

save-result.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
	<meta charset="UTF-8">
</head>
<body>
	성공
	<ul>
		 <li>id=${member.id}</li> <%-- <%=((Member)request.getAttribute("member")).getId()%> --%>
		 <li>username=${member.username}</li>
		 <li>age=${member.age}</li>
	</ul>
	<a href="/index.html">메인</a>
</body>
</html>

 

MvcMemberListServlet.java

@WebServlet(name = "mvcMemberListSerlvet", urlPatterns = "/servlet-mvc/members")
public class MvcMemberListServlet extends HttpServlet{
	
	MemberRepository memberRepository = MemberRepository.getInstance();
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		
		List<Member> members = memberRepository.findAll();
		req.setAttribute("members", members);
		
		String viewPath = "/WEB-INF/views/members.jsp";	
		RequestDispatcher dispatcher = req.getRequestDispatcher(viewPath); 
		dispatcher.forward(req, res);	
	}
}

 

members.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
	<a href="/index.html">메인</a>
	<table>
		 <thead>
			 <th>id</th>
			 <th>username</th>
			 <th>age</th>
		 </thead>
		 <tbody>
			 <c:forEach var="item" items="${members}"> <!-- 반복문 -->
				 <tr>
					 <td>${item.id}</td>
					 <td>${item.username}</td>
					 <td>${item.age}</td>
				 </tr>
			 </c:forEach>
		 </tbody>
	</table>
</body>
</html>

 

Servlet 또는 JSP만 사용했을 때보다는 코드가 깔끔하고 직관적이게 됐다.

 

다만, 위 작업을 따라하다 보면 비슷한 행위가 반복된다는 것이 느껴질 것이다.

특히 Controller마다 RequestDispatcher를 호출하고 보내주는 작업이 반복된다.

이후에 비슷한 기능을 하는 Controller를 공통으로 처리하기 어렵다.

 

여기서 등장한 것이 프론트 컨트롤러 패턴이다.

스프링 MVC의 핵심도 이 프론트 컨트롤러 패턴에 있는데,

Controller 호출 전에 공통 기능을 처리할 수 있게 한다.


본 게시글은 김영한 님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의를 구매 후 정리하기 위한 포스팅입니다.

내용을 임의로 추가, 수정, 삭제한 부분이 많으며 정확한 이해를 위해서 강의를 구매하시는 것을 추천 드립니다.

 

inf.run/B756

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com

 

반응형

'Develop > Java' 카테고리의 다른 글

[MVC] View 분리  (0) 2021.05.10
[MVC] 프론트 컨트롤러 패턴  (2) 2021.05.10
[JSP] 회원 관리 웹 애플리케이션  (0) 2021.05.07
[Servlet] 회원 관리 웹 애플리케이션  (0) 2021.05.06
[Servlet] HttpServletResponse  (0) 2021.04.30