오봉이와 함께하는 개발 블로그
스프링 MVC 1 - MVC 패턴 적용 본문
MVC 패턴 - 적용
서블릿을 컨트롤러로 사용하고 JSP를 뷰로 사용해서 MVC 패턴을 적용해보자.
Model은 HttpServletRequest 객체를 사용한다.
request는 내부에 데이터 저장소를 가지고 있는데, request.setAttribute()
, request.getAttribute()
를 사용하면 데이터를 보관하고 조회할 수 있다.
회원 등록
회원 등록 폼 - 컨트롤러
@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);
}
}
dispatcher.forward()
: 다른 서블릿이나 JSP로 이동할 수 있는 기능이다. 서버 내부에서 다시 호출이 발생한다.
/WEB-INF
: 이 경로안에 JSP가 있으면 외부에서 직접 JSP를 호출할 수 없다. 우리가 기대하는 것은 항상 컨트롤러를 통해 JSP를 호출하는 것이다.
redirect vs forward
리다이렉트는 실제 클라이언트에서 응답이 나갔다가 클라이언트가 redirect 경로로 다시 요청한다.
따라서 클라이언트가 인지할 수 있고 URL경로도 실제로 변경된다.
반면 포워드는 서버 내부에서 일어나기 때문에 클라이언트가 인지할 수 없다.
회원 등록 폼 - 뷰
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 상대경로 사용, [현재 URL이 속한 계층 경로 + /save] -->
<!-- /servlet-mvc/members/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>
여기서 form의 action을 보면 절대 경로( / 로 시작)
가 아니라 상대경로( / 로 시작X)
인 것을 확인할 수 있다.
이렇게 상대경로를 사용하면 폼 전송시 현재 URL이 속한 계층 경로 + save가 호출된다.
회원 저장
회원 저장 - 컨트롤러
@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {
private MemberRepository memberRepository = 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);
System.out.println("member = " + member);
memberRepository.save(member);
// Model에 데이터 보관
request.setAttribute("member", member);
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
HttpServletRequest
를 Model로 사용한다.
request가 제공하는 setAttribute()
를 사용하면 request 객체에 데이터를 보관해서 뷰에 전달할 수 있다.
뷰에서 request.getAttribute()
를 사용해서 데이터를 꺼내자.
회원 저장 - 뷰
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body> 성공
<ul>
<li>id=${member.id}</li>
<li>username=${member.username}</li>
<li>age=${member.age}</li>
</ul>
<a href="/index.html">메인</a>
</body>
</html>
<%= request.getAttribute("member")%>
로 model에 있는 member 객체를 꺼낼 수 있지만 복잡하다.
예 : <li>id=<%=((Member)request.getAttribute("member")).getId()%>
그래서 JSP는 ${}
문법을 제공한다.
이 문법을 사용하면 request의 attribute에 담긴 데이터를 편리하게 조회할 수 있다.
- 실행
- http://localhost:8080/servlet-mvc/members/new-form
- Form에 데이터를 입력하고 전송을 누르면 저장 결과를 확인할 수 있다.
- http://localhost:8080/servlet-mvc/members/new-form
회원 목록 조회
회원 목록 조회 - 컨트롤러
@WebServlet(name = "mvcMemberListServlet", urlPatterns = "/servlet-mvc/members")
public class MvcMemberListServlet extends HttpServlet {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("MvcMemberListServlet.service");
List<Member> members = memberRepository.findAll();
request.setAttribute("members", members);
String viewPath = "/WEB-INF/views/member.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
request 객체를 사용해서 List<Member> members
를 모델에 보관했다.
회원 목록 조회 - 뷰
<%@ 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>
<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>
모델에 담긴 members 객체를 JSP에서 제공하는 taglib기능을 사용해서 반복 출력했다.<c:forEach>
기능을 사용하려면 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
를 선언해야 한다.
taglib기능을 사용하지 않아도 되지만 코드가 매우 지저분하기 때문에 가급적 사용하자.
출처 : 인프런 김영한 지식 공유자님 강의 - 스프링 MVC 1편 백엔드 웹 개발 핵심 기술
'BE > JSP' 카테고리의 다른 글
스프링 MVC 1 - JSP MVC 패턴의 한계 (0) | 2022.08.11 |
---|---|
스프링 MVC 1 - JSP로 회원 관리 웹 애플리케이션 만들기 (0) | 2022.08.11 |
JSP - JSTL (0) | 2021.12.31 |
JSP - EL (0) | 2021.12.31 |
JSP - 액션 태그(useBean, setProperty, getProperty) (0) | 2021.12.30 |