강의 내용이 있기 때문에 출처를 밝힙니다 !
출처 : 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (인프런 강의)
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1
MVC 란 ?
Model, View, Controller 의 약자로, 디자인 패턴의 한 종류
비즈니스 로직과 View 로직을 분리하기 위해 나온 패턴이고 Sevelt, JSP 이 합쳐진 파일들을 MVC 패턴을 사용해 나눠보자.
중요한 것은, Servlet 은 비즈니스 로직만 담당하도록, JSP 는 View 로직만 담당하도록 분리하는 것이다.
프로젝트 디렉토리 구조
만들어야 하는 파일
1. src/main/java/hello/servlet/web/servletmvc 아래의 자바 파일
2. src/main/webapp/WEB-INF/views 아래의 JSP파일
1. 회원 등록 폼 서블릿 만들기 (MvcMemberFormServlet.java)
단순한 Form 이기 때문에 로직 자체는 간단하다.
getRequestDispatcher() 메서드 인자로 호출하고 싶은 JSP 의 경로를 주고, 이후 forward() 메서드를 통해 JSP 를 호출한다.
눈여겨 볼 점은 viewPath 부분인데, 이렇게 WEB-INF 디렉토리 내부에 JSP 파일이 존재하면 브라우저에서 직접적으로 JSP 파일이
존재하는 디렉토리 경로를 URL 에 적어 JSP 파일을 불러올 수 없다.
즉, 무조건 컨트롤러(여기서는 Servlet) 을 통해 JSP 파일을 호출하기 위해서 넣어준 것.
@WebServlet(name = "mvcMemberFormServlet", urlPatterns = "/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
1-1) 회원 등록 폼 JSP 만들기 (new-form.jsp)
역시 단순 Form 이기 때문에 간단하게 만들 수 있다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- form action 경로를 상대경로를 사용한 이유
상대경로를 사용하면 현재 URL 의 계층 + 지정한 action 경로가 뒤에 붙게 된다. (ex - jsp/members 경로에서 + /save)
만약 /save 라고 절대경로 지정을 해줬으면, localhost:8080/save 이런 식으로 바로 경로가 지정되는데 우리는 이 save 폼을
다른 경로에서도 계속 재사용하기 위해서 상대경로를 써준 것이다.
즉, 앞에 어떤 경로가 와도 뒤에 /save 를 바로 붙여주기 위해서 쓴 거..
-->
<form action="save" method="post">
username: <input type="text" name="username" />
age : <input type="text" name="age" />
<button type="submit">전송</button>
</form>
</body>
</html>
포스트맨으로 응답 확인
2. 회원 가입 서블릿 만들기 (MvcMemberSaveServlet.java)
폼에서 작성한 username, age 를 request.getParameter() 메서드를 통해 Member 객체를 만들고, 저장소에 저장하는 로직이다.
폼에서 Post 방식으로 Body 에 데이터를 담아 보냈지만, 서버 입장에서는 GET 방식의 쿼리 스트링과 동일한 방식으로 인식하기 때문에
getParameter() 메서드를 통해 데이터를 조작할 수 있는 것이다.
그럼 Member 객체를 어떻게 View 로 보낼 수 있을까 ?
해답은 웹 브라우저에 있는 reuqest 저장소에 Member 객체를 저장하는 것이다. 간단하게 request.setAttribute() 메서드를 통해
Key, Value 형식으로 저장할 수 있다.
@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {
private final MemberRepository repository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
repository.save(member);
request.setAttribute("member", member);
String viewPath = "/WEB-INF/views/save.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
2-2) 회원 가입 JSP 만들기 (save.jsp)
request.setAttribute("member", member) 을 통해 이제 View 쪽에서 Member 객체 데이터를 사용할 수 있게 됬다.
원래는 request.getAttribute() 메서드를 통해 객체 내부 데이터를 가져와 사용해야하는데, JSP 에서 제공하는 ${} 을 사용해서
간단하게 처리할 수 있다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>회원가입 성공</p>
<ul>
<!-- JSP 에서 제공하는 $ {} 문법으로 request.setAttribute() 데이터를 쉽게 가져와서 사용할 수 있다 .-->
<li>ID=${member.id}</li>
<li>Name=${member.username}</li>
<li>Age=${member.age}</li>
</ul>
<a href="/index.html">메인으로 이동</a>
</body>
</html>
포스트맨으로 응답 확인
ID, Username, Age 를 Member 객체 내부의 데이터 값으로 잘 치환되서 응답되는 것을 확인할 수 있다.
이런걸 프로퍼티 접근법이라고도 한다.
3. 회원 리스트 서블릿 만들기 (MvcMemberListServlet.java)
저장소에서 모든 Member 를 List 에 담고 JSP 에서 사용하기 위해 setAttribute() 에 Key, Value 형식으로 담아준다.
@WebServlet(name = "mvcMemberListServlet", urlPatterns = "/servlet-mvc/views/members")
public class MvcMemberListServlet extends HttpServlet {
private final MemberRepository repository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Member> members = repository.findAll();
request.setAttribute("members", members);
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
3-3) 회원 리스트 JSP 만들기 (members.jsp)
JSP 에서 제공하는 <c:forEach> 태그를 사용해 반복문을 쉽게 활용할 수 있다.
items 로 setAttribute() 한 Key 값을 지정하고, Member 객체를 꺼내와서 하나씩 출력 !
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>Member List Server Side Rendering Test</p>
<table>
<thead>
<th>ID</th>
<th>Username</th>
<th>Age</th>
</thead>
<tbody>
<c:forEach var="member" items="${members}">
<tr>
<td>${member.id}</td>
<td>${member.username}</td>
<td>${member.age}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
포스트맨으로 응답 확인
test1, test2, test3 의 Name 을 가진 Member 객체 3개를 저장하고 응답을 확인했을 때, 차례대로 출력된 것을 확인할 수 있다.
다음에는 MVC 패턴으로 나뉜 구조에서 FrontController 를 도입해서 구조를 개선해보는 연습을 해보자 😀
'Servlet' 카테고리의 다른 글
FrontController 를 통한 MVC 패턴 구조 개선 [2] (0) | 2022.04.03 |
---|---|
FrontController 를 통한 MVC 패턴 구조 개선 [1] (0) | 2022.04.03 |
[POST] 클라이언트 요청 Body 를 서버로 전달하기 (0) | 2022.03.30 |
[GET] 클라이언트 요청 쿼리 파라미터를 서버로 전달하기 (0) | 2022.03.30 |