목차
MVC 프레임워크 만들기
- V3, V4에 대한 설명
- 이후 V3,V4에 접근할 어댑터를 생성한 V5 버전에 대한 이해를 풀어내겠습니다.
V3

package hello.servlet.web.frontcontroller.v3;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.controller.MemberFormControllerV3;
import hello.servlet.web.frontcontroller.v3.controller.MemberListControllerV3;
import hello.servlet.web.frontcontroller.v3.controller.MemberSaveControllerV3;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet(name = "frontControllerServletV3", urlPatterns = "/front-controller/v3/*") // * -> v1 하위 모든 요청
public class FrontControllerServletV3 extends HttpServlet {
private Map<String, ControllerV3> controllerMap = new HashMap<>(); // 요청 URI에 해당하는 controller를 찾기 위한 맵
public FrontControllerServletV3() {
controllerMap.put("/front-controller/v3/members/new-form", new MemberFormControllerV3());
controllerMap.put("/front-controller/v3/members/save", new MemberSaveControllerV3());
controllerMap.put("/front-controller/v3/members", new MemberListControllerV3());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestURI(); // 요청 URI -> new-form
// get으로 해당하는 controller 찾기
ControllerV3 controller = controllerMap.get(request.getRequestURI()); // 요청 URI에 해당하는 controller 찾기 -> new form 된다.
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);// 404 처리
return;
}
// request.getParameterNames().asIterator()
// .forEachRemaining(paramName -> System.out.println(paramName + "=" + request.getParameter(paramName)));
//paramMap
// form 에 값을 넣었을때.
Map<String, String> paramMap = createParamMap(request); // 파라미터 값을 다 넣음
ModelView mv = controller.process(paramMap); // controller 호출 -> model view 반환
String viewName = mv.getViewName(); // 논리이름 new-form
MyView view = viewResolver(viewName);// 물리이름 new-form.jsp
view.render(mv.getModel(), request,response); // view 호출 jsp 호출
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
private static Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> paramMap.put(paramName, request.getParameter(paramName))); // 파라미터에 있는 값을 다 꺼내서 paramMap에 저장
return paramMap;
}
}
new-form → save → list 순서로 넘어갑니다.
- Frontcontroller에서 v3의 하위 모든 요청을 받아들인다.
- 이후 요청 URI에 해당하는 controller를 찾아줄때 사용할 맵을 생성한다.
- CollectionMap에 생성자로 각 URI에 알맞은 controller 를 넣어준다.
공통
request.getRequestURI
로 요청 URI 를 가져온다.- controllerMap 에서 어떠한 controller 를 사용할지 가져온다.
- 여기서 맞는 controller 가 없다면 404 처리를 해준다.
new-form
- param값이 없기 때문에 아무것도 없는 map 이 넘어간다.
controller들이 구현할 interface
package hello.servlet.web.frontcontroller.v3;
import hello.servlet.web.frontcontroller.ModelView;
import java.util.Map;
public interface ControllerV3 {
ModelView process(Map<String, String> paramMap);
}
MemberFormController
package hello.servlet.web.frontcontroller.v3.controller;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import java.util.Map;
public class MemberFormControllerV3 implements ControllerV3 {
@Override
public ModelView process(Map<String, String> paramMap) {
return new ModelView("new-form");
}
}
package hello.servlet.web.frontcontroller;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
@Getter @Setter
public class ModelView {
private String viewName;
private Map<String, Object> model = new HashMap<>();
public ModelView(String viewName) {
this.viewName = viewName;
}
}
- viewname으로 new-form 이 제공된다.
- 이후
mv.getViewName
에서 new-form을 가져와 모델과 함께 렌더링한다.- 여기서 model은 현재 null 이다.
save
앞의 new-form 의 창이 떴다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 상대경로 사용, [현재 URL이 속한 계층 경로 + /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>
- save action 에 의해서 controller 에서 saveController 를 가져온다.
- request에 username과 age를 담아서 준다.
- controller 에 필요한 paramMap 을 만들어 준다.
- 각 파라미터에서 이름과 값을 iterator 로 가져와서 map으로 만들어준다.
- ex) username : jason, age: 20
package hello.servlet.web.frontcontroller.v3.controller;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import java.util.Map;
public class MemberSaveControllerV3 implements ControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> paramMap) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelView mv = new ModelView("save-result");
mv.getModel().put("member", member);
return mv;
}
}
- 여기서 memberRepository는 멤버를 담을 수 있는 저장소
- 앞에서 paramMap에서 username과 age를 담아서 제공해주었다.
- 해당 paramMap에서 username과 age를 가져와서 Member 객체로 만들어준 후 저장소에 저장한다.
- 이후 modelview로
save-result
라는 값을 준다. - 또한 modelView에 member 값을 넣어서 return 해준다.
- view.render에서 모델의 값을 가지고 렌더링 한다.
<%--
Created by IntelliJ IDEA.
User: kimjimin
Date: 4/19/24
Time: 11:47 AM
To change this template use File | Settings | File Templates.
--%>
<%@ 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">Main</a>
</body>
</html>
list
package hello.servlet.web.frontcontroller.v3.controller;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import java.util.List;
import java.util.Map;
public class MemberListControllerV3 implements ControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> paramMap) {
List<Member> members = memberRepository.findAll();
ModelView mv = new ModelView("members");
mv.getModel().put("members", members);
return mv;
}
}
- memberRepository에서 모든 값을 찾아서 List로 만든다.
- ModelView에 members라는 viewname을 넣어서 생성한다.
- model이란 Map에 members라는 key에 members 라는 리스트를 넣는다.
- mv에서
String viewName = mv.getViewName();
으로 뷰의 이름을 가져오고, 똑같이 렌더링 한다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: kimjimin
Date: 4/19/24
Time: 11:52 AM
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<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 list를 반복문을 돌리면서 id, username, age를 가져와서 출력한다.
'Spring' 카테고리의 다른 글
Spring MVC -김영한 백엔드 (1) (0) | 2024.04.22 |
---|---|
인프런 워밍업클럽 4일차 과제 (0) | 2024.02.22 |
인프런 워밍업클럽 3일차 과제 (0) | 2024.02.22 |
인프런 워밍업클럽 2일차 과제 (0) | 2024.02.21 |
인프런 워밍업클럽 1일차 과제 (0) | 2024.02.19 |
MVC 프레임워크 만들기
- V3, V4에 대한 설명
- 이후 V3,V4에 접근할 어댑터를 생성한 V5 버전에 대한 이해를 풀어내겠습니다.
V3

package hello.servlet.web.frontcontroller.v3;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.controller.MemberFormControllerV3;
import hello.servlet.web.frontcontroller.v3.controller.MemberListControllerV3;
import hello.servlet.web.frontcontroller.v3.controller.MemberSaveControllerV3;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet(name = "frontControllerServletV3", urlPatterns = "/front-controller/v3/*") // * -> v1 하위 모든 요청
public class FrontControllerServletV3 extends HttpServlet {
private Map<String, ControllerV3> controllerMap = new HashMap<>(); // 요청 URI에 해당하는 controller를 찾기 위한 맵
public FrontControllerServletV3() {
controllerMap.put("/front-controller/v3/members/new-form", new MemberFormControllerV3());
controllerMap.put("/front-controller/v3/members/save", new MemberSaveControllerV3());
controllerMap.put("/front-controller/v3/members", new MemberListControllerV3());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestURI(); // 요청 URI -> new-form
// get으로 해당하는 controller 찾기
ControllerV3 controller = controllerMap.get(request.getRequestURI()); // 요청 URI에 해당하는 controller 찾기 -> new form 된다.
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);// 404 처리
return;
}
// request.getParameterNames().asIterator()
// .forEachRemaining(paramName -> System.out.println(paramName + "=" + request.getParameter(paramName)));
//paramMap
// form 에 값을 넣었을때.
Map<String, String> paramMap = createParamMap(request); // 파라미터 값을 다 넣음
ModelView mv = controller.process(paramMap); // controller 호출 -> model view 반환
String viewName = mv.getViewName(); // 논리이름 new-form
MyView view = viewResolver(viewName);// 물리이름 new-form.jsp
view.render(mv.getModel(), request,response); // view 호출 jsp 호출
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
private static Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> paramMap.put(paramName, request.getParameter(paramName))); // 파라미터에 있는 값을 다 꺼내서 paramMap에 저장
return paramMap;
}
}
new-form → save → list 순서로 넘어갑니다.
- Frontcontroller에서 v3의 하위 모든 요청을 받아들인다.
- 이후 요청 URI에 해당하는 controller를 찾아줄때 사용할 맵을 생성한다.
- CollectionMap에 생성자로 각 URI에 알맞은 controller 를 넣어준다.
공통
request.getRequestURI
로 요청 URI 를 가져온다.- controllerMap 에서 어떠한 controller 를 사용할지 가져온다.
- 여기서 맞는 controller 가 없다면 404 처리를 해준다.
new-form
- param값이 없기 때문에 아무것도 없는 map 이 넘어간다.
controller들이 구현할 interface
package hello.servlet.web.frontcontroller.v3;
import hello.servlet.web.frontcontroller.ModelView;
import java.util.Map;
public interface ControllerV3 {
ModelView process(Map<String, String> paramMap);
}
MemberFormController
package hello.servlet.web.frontcontroller.v3.controller;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import java.util.Map;
public class MemberFormControllerV3 implements ControllerV3 {
@Override
public ModelView process(Map<String, String> paramMap) {
return new ModelView("new-form");
}
}
package hello.servlet.web.frontcontroller;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
@Getter @Setter
public class ModelView {
private String viewName;
private Map<String, Object> model = new HashMap<>();
public ModelView(String viewName) {
this.viewName = viewName;
}
}
- viewname으로 new-form 이 제공된다.
- 이후
mv.getViewName
에서 new-form을 가져와 모델과 함께 렌더링한다.- 여기서 model은 현재 null 이다.
save
앞의 new-form 의 창이 떴다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 상대경로 사용, [현재 URL이 속한 계층 경로 + /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>
- save action 에 의해서 controller 에서 saveController 를 가져온다.
- request에 username과 age를 담아서 준다.
- controller 에 필요한 paramMap 을 만들어 준다.
- 각 파라미터에서 이름과 값을 iterator 로 가져와서 map으로 만들어준다.
- ex) username : jason, age: 20
package hello.servlet.web.frontcontroller.v3.controller;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import java.util.Map;
public class MemberSaveControllerV3 implements ControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> paramMap) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelView mv = new ModelView("save-result");
mv.getModel().put("member", member);
return mv;
}
}
- 여기서 memberRepository는 멤버를 담을 수 있는 저장소
- 앞에서 paramMap에서 username과 age를 담아서 제공해주었다.
- 해당 paramMap에서 username과 age를 가져와서 Member 객체로 만들어준 후 저장소에 저장한다.
- 이후 modelview로
save-result
라는 값을 준다. - 또한 modelView에 member 값을 넣어서 return 해준다.
- view.render에서 모델의 값을 가지고 렌더링 한다.
<%--
Created by IntelliJ IDEA.
User: kimjimin
Date: 4/19/24
Time: 11:47 AM
To change this template use File | Settings | File Templates.
--%>
<%@ 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">Main</a>
</body>
</html>
list
package hello.servlet.web.frontcontroller.v3.controller;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import java.util.List;
import java.util.Map;
public class MemberListControllerV3 implements ControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> paramMap) {
List<Member> members = memberRepository.findAll();
ModelView mv = new ModelView("members");
mv.getModel().put("members", members);
return mv;
}
}
- memberRepository에서 모든 값을 찾아서 List로 만든다.
- ModelView에 members라는 viewname을 넣어서 생성한다.
- model이란 Map에 members라는 key에 members 라는 리스트를 넣는다.
- mv에서
String viewName = mv.getViewName();
으로 뷰의 이름을 가져오고, 똑같이 렌더링 한다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: kimjimin
Date: 4/19/24
Time: 11:52 AM
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<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 list를 반복문을 돌리면서 id, username, age를 가져와서 출력한다.
'Spring' 카테고리의 다른 글
Spring MVC -김영한 백엔드 (1) (0) | 2024.04.22 |
---|---|
인프런 워밍업클럽 4일차 과제 (0) | 2024.02.22 |
인프런 워밍업클럽 3일차 과제 (0) | 2024.02.22 |
인프런 워밍업클럽 2일차 과제 (0) | 2024.02.21 |
인프런 워밍업클럽 1일차 과제 (0) | 2024.02.19 |