๐ง ๋ค์ด๊ฐ๊ธฐ์ ์์
์์ผ๋ก ๋ฑ์ฅํ๋ ์ปจํธ๋กค๋ฌ(Controller)๋ MVC ํจํด์์์ Controller๋ฅผ ์๋ฏธํฉ๋๋ค.
์ด๋ Controller์ ์ญํ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- HTTP ์์ฒญ์ ๋ฐ์ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฒ์ฆํฉ๋๋ค.
- ๋น์ฆ๋์ค ๋ก์ง์ ์คํํฉ๋๋ค. (์ด๋ ๋ณดํต Service ๊ณ์ธต์ ํด๋์ค๋ฅผ ํตํด ์คํํฉ๋๋ค.)
- ๋ทฐ(View)์ ์ ๋ฌํ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ์ฌ ๋ชจ๋ธ(Model)์ ๋ณด๊ดํฉ๋๋ค.
๐ง ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ์ฌ์ฉํ์ง ์์์ ๋์ ๋ฌธ์ ์
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ๋ํด ์์๋ณด๊ธฐ ์ ์, ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ฅผ ์ ์จ์ผ ํ๋์ง, ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ด๋ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๊ฐ๋จํ ํ์ ๊ด๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํตํด ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฐ์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ํ์ ๊ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ Controller ์ ๋๋ค.
๐ ํ์ ๊ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ Controller
@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 {
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
// FORWARD, ๋ค๋ฅธ ์๋ธ๋ฆฟ์ด๋ jsp๋ก ์ด๋ํ ์ ์๋ ๊ธฐ๋ฅ, ์๋ฒ ๋ด๋ถ์์ ๋ค์ ํธ์ถ์ด ๋ฐ์
dispatcher.forward(request, response);
}
}
๐ ํ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ Controller
@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {
private final 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);
memberRepository.save(member);
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
request.setAttribute("member", member);
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/save-result.jsp";
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
๐ ์ ์ฅ๋ ํ์๋ค์ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ Controller
@WebServlet(name = "mvcMemberListServlet", urlPatterns = "/servlet-mvc/members")
public class MvcMemberListServlet extends HttpServlet {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
request.setAttribute("members", members);
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/members.jsp";
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
์ ์ฝ๋๋ค์ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฝ๋์ ์ค๋ณต์ด ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
// VIEW PATH ์ค์
String viewPath = "***";
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
๋ํ HttpServletRequest request, HttpServletResponse response๋ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ๋ ์์ผ๋ฉฐ, ์ฌ์ง์ด response๋ ํ๋ฒ๋ ์ฌ์ฉํ์ง ์์์ต๋๋ค.
์ด๋ฌํ ์ด์ ๋ก ์ธํด, ๊ธฐ๋ฅ์ด ๋ณต์กํด์ง๊ณ ํ๋ก์ ํธ์ ๊ท๋ชจ๊ฐ ์ปค์ง ์๋ก ๊ณตํต์ผ๋ก ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํ๋ ๋ถ๋ถ์ด ๊ณ์ํด์ ์ฆ๊ฐํ ๊ฒ์ ๋๋ค.
๊ฒฐ๊ตญ์ ๊ณตํต๋๋ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๊ธฐ๊ฐ ์ด๋ ค์์ง๋ค๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ๋์ ํจ์ผ๋ก์จ ํด๊ฒฐํ ์ ์์ต๋๋ค.
๐ง ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด
์ปจํธ๋กค๋ฌ ํธ์ถ ์ ์ ๊ณตํต๋๋ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฌ์ฉํ๋ ํจํด์ ์๋ฏธํฉ๋๋ค.
์ด๋ ์ฌ์ฉ๋๋ ์ปจํธ๋กค๋ฌ๋ ๋ชจ๋ ์์ฒญ์ด ์ฒ์์ผ๋ก ๋ค์ด์ค๋ ์ ๊ตฌ์ ์ญํ ์ ํ๊ฒ ๋๋ฉฐ, ์ด๋ฅผ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ผ ๋ถ๋ฆ ๋๋ค.
๊ทธ๋ฆผ์ ํตํด ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
(์ฌ์ฉ๋๋ ๊ทธ๋ฆผ์ ๊น์ํ ์ ์๋์ ์คํ๋ง MVC 1ํธ - ๋ฐฑ์๋ ์น ๊ฐ๋ฐ ํต์ฌ ๊ธฐ์ ์ ์๋ฃ์์ ๋ฐ์ทํ์์ต๋๋ค.)
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ๋์ ์ ์๋ ์๋์ ๊ฐ์ด ๊ฐ๊ฐ์ ์ปจํธ๋กค๋ฌ๋ง๋ค ๊ณตํต๋๋ ๊ธฐ๋ฅ๊ณผ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ๋ชจ๋ ์์ฑํ์ฌ์ผ ํ์ต๋๋ค.
๊ทธ๋ฌ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ๋์ ์ดํ์๋ ์๋์ ๊ฐ์ด ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ๊ณตํต ๊ธฐ๋ฅ์ ์ํํ ๋ค, ๊ฐ๊ฐ์ ์์ฒญ์ ๋์๋๋ ์ปจํธ๋กค๋ฌ๋ฅผ ํธ์ถํจ์ผ๋ก์จ ๊ณตํต ๊ธฐ๋ฅ์ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ง๋๋ค.
์ ๊ทธ๋ฆผ์ ํตํด ์ ์ ์๋ฏ์ด, ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ์๋์ ๊ฐ์ ํน์ง์ ๊ฐ์ต๋๋ค.
๐ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ํน์
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์๋ธ๋ฆฟ ํ๋๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์ ๋ชจ๋ ์์ฒญ์ ๋ฐ์ต๋๋ค.
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ ์์ฒญ(Request)์ ๋งคํ(mapping)๋๋ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์์ ํธ์ถํฉ๋๋ค.
๋ชจ๋ ์์ฒญ์ ์ ๊ตฌ๊ฐ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๊ฐ ๋ฉ๋๋ค.
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์๋ ๊ณตํต๋๋ ๋ก์ง์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๋ํ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ฅผ ์ ์ธํ ๋๋จธ์ง ์ปจํธ๋กค๋ฌ๋ ์๋ธ๋ฆฟ์ ์ฌ์ฉํ ํ์๊ฐ ์์ด์ง๋๋ค.
(ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ๋จ์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ ํตํด ๋ค๋ฅธ ์ปจํธ๋กค๋ฌ๋ค์ ํธ์ถํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.)
์คํ๋ง ์น MVC๋ Front Controller ํจํด์ ์ฌ์ฉํ๋ฉฐ,
์ด๋ DispatcherServlet ์ด Front Controller์ ์ญํ ์ ์ํํฉ๋๋ค.
๐ง ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ์ ์ฉ
์์ ์ดํด๋ณธ ์ฝ๋์ ๋ํ์ฌ, ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ์ ์ฉํ๋ฉฐ ์ฝ๋๋ฅผ ๊ฐ์ ํ๋ ๊ณผ์ ์ ํตํด ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ๋ํด ํ์ตํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฐฝ ๋ ๊ฐ๋ฅผ ๋์ด ํ, ์ด์ ๋ฒ์ ๊ณผ ๋น๊ตํด ๊ฐ๋ฉฐ ๋ณด๋ ๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค.
๐ V1: ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์์ ํธ์ถํ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ
V1์์๋ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋์ ๊ฐ์ ์ด ์ด๋ฃจ์ด์ง๋๋ค.
๋ชจ๋ ์์ฒญ์ ๋ํด์ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์๋ธ๋ฆฟ์ด ํด๋น ์์ฒญ์ ๋งคํ๋๋ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์์ ํธ์ถํ๊ฒ ๋ฉ๋๋ค.
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์ด์ธ์ ๋ค๋ฅธ ์ปจํธ๋กค๋ฌ์์๋ ์๋ธ๋ฆฟ์ ์ฌ์ฉํ์ง ์๊ฒ ๋ฉ๋๋ค.
V1์ ์ต์ข ์ ์ธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
(๊ตฌ์กฐ ์๋ฃ ์ญ์ ๊น์ํ ์ ์๋์ ์คํ๋ง MVC 1ํธ - ๋ฐฑ์๋ ์น ๊ฐ๋ฐ ํต์ฌ ๊ธฐ์ ์ ์๋ฃ์์ ๋ฐ์ทํ์์ต๋๋ค.)
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์ด์ธ์ ๋ค๋ฅธ ์ปจํธ๋กค๋ฌ์์๋ ์๋ธ๋ฆฟ์ ์ฌ์ฉํ์ง ์๋๋ก ๋ง๋ค๊ธฐ ์ํด, ์๋์ ๊ฐ์ด ์๋ธ๋ฆฟ๊ณผ ๋น์ทํ ์๊น์๋ฅผ ๊ฐ๋ Controller ์ธํฐํ์ด์ค๋ฅผ ์ ์ธํ๊ฒ ์ต๋๋ค.
public interface ControllerV1 {
void process(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException;
}
(ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ฅผ ์ ์ธํ) ๊ฐ ์ปจํธ๋กค๋ฌ๋ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค.
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์๋ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ปจํธ๋กค๋ฌ๋ค ์ค ์์ฒญ์ ๋งคํ๋๋ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์ ํธ์ถํ๋ ์ผ๊ด์ ์ธ ๋ก์ง์ ํตํด ์ฌ๋ฌ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๐ ํ์ ๊ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ Controller V1
public class MemberFormControllerV1 implements ControllerV1 {
@Override
public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
// FORWARD, ๋ค๋ฅธ ์๋ธ๋ฆฟ์ด๋ jsp๋ก ์ด๋ํ ์ ์๋ ๊ธฐ๋ฅ, ์๋ฒ ๋ด๋ถ์์ ๋ค์ ํธ์ถ์ด ๋ฐ์
dispatcher.forward(request, response);
}
}
๐ ํ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ Controller V1
public class MemberSaveControllerV1 implements ControllerV1 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public void process(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);
memberRepository.save(member);
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
request.setAttribute("member", member);
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/save-result.jsp";
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
๐ ์ ์ฅ๋ ํ์๋ค์ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ Controller V1
public class MemberListControllerV1 implements ControllerV1 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
request.setAttribute("members", members);
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/members.jsp";
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
์ ์ธ ์ฝ๋ ๋ชจ๋์์ process() ๋ฉ์๋ ๋ด๋ถ์ ๋ค์ด์๋ ๋ก์ง์ ์ด์ ๊ณผ ๋ฐ๋ ๊ฒ์ด ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด๋ค์ ์ด์ HttpServlet์ ์์๋ฐ์ง ์๊ณ ๊ตฌํ๋์๊ธฐ ๋๋ฌธ์ ๋์ด์ Servlet์ด ์๋๋๋ค.
์ด์ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ฅผ ๊ตฌํํ์ฌ, ๋ค์ด์จ ์์ฒญ์ ๋งคํ๋๋ Controller๋ฅผ ์ฐพ์ ํธ์ถํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ Front Controller V1
@WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-controller/v1/*")
public class FrontControllerServletV1 extends HttpServlet {
private Map<String, ControllerV1> controllerMap = new HashMap<>();
/**
* ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์์ฑ ์ ์์ฒญ(Request)๋ณ๋ก ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๋ฑ๋ก
*/
public FrontControllerServletV1() {
controllerMap.put("/front-controller/v1/members/new-form", new MemberFormControllerV1());
controllerMap.put("/front-controller/v1/members/save", new MemberSaveControllerV1());
controllerMap.put("/front-controller/v1/members", new MemberListControllerV1());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("---------- [FRONT CONTROLLER V1 ์คํ] ----------");
String requestURI = request.getRequestURI(); // ์์ฒญ URI ๊ฐ์ ธ์ค๊ธฐ
// ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๊ฐ์ ธ์ค๊ธฐ
ControllerV1 controller = getController(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 404 NOT FOUND
return;
}
// Controller ํธ์ถ
controller.process(request, response);
}
private ControllerV1 getController(String requestURI) {
return controllerMap.get(requestURI);
}
}
๋ชจ๋ ์์ฒญ์ ๋ํด Front Controller๊ฐ ๋์ํ๋๋ก ํ๊ธฐ ์ํด์๋ urlPatterns๋ฅผ "*"๋ก ์ค์ ํ์ฌ์ผ ํ๊ฒ ์ง๋ง, ์ด์ ๋ฒ์ ๋ค์ ์ ์ง์ํค๋ฉฐ ์ฝ๋๋ฅผ ๊ฐ์ ์์ผ ๋๊ฐ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋น๊ต๋ฅผ ์ํด /front-controller/v1 ์ ํ์ ๊ฒฝ๋ก๋ค์ ๋ํ ๋ชจ๋ ์์ฒญ์ ๋ํด์๋ง FrontControllerServletV1์ด ์์ฒญ์ ์ฒ๋ฆฌํ๋๋ก ๊ตฌํํ์์ต๋๋ค.
๐ V2 - View ๋ถ๋ฆฌ (View Path ์ค์ ๊ณผ Dispatcher.forward() ์ค๋ณต์ ๊ฐ์ )
V2 ์์๋ ๋ค์ ์ฝ๋์ ์ค๋ณต์ ๊ฐ์ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
// VIEW PATH ์ค์
String viewPath = "***";
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
ํด๋น ๋ถ๋ถ์ ๋ถ๋ฆฌ๋ฅผ ์ํด ๋ทฐ(View)์ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋๋ก ํ๊ฒ ์ต๋๋ค.
V2์ ์ต์ข ์ ์ธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ด์ ๊น์ง๋ Controller์์ JSP๋ฅผ ์ง์ ๋ฐํํ์์ต๋๋ค.
๊ทธ๋ฌ๋ V2์์๋ Controller์์๋ MyView๋ฅผ Front Controller์ ๋ฐํํ๊ฒ ํ ๋ค,
FrontContrller์์ MyView.render()๋ฅผ ํธ์ถํ์ฌ JSP๋ฅผ ๋ฐํํฉ๋๋ค.
๐ MyView
public class MyView {
private String viewPath;
public MyView(String viewPath) {
// VIEW PATH ์ค์
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
์ด์ ์ ์ค๋ณต๋์๋ ์ฝ๋๋ค์ด MyView์์ ๊ณตํต์ผ๋ก ์ฒ๋ฆฌ๋๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๐ ControllerV2
public interface ControllerV2 {
MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
V1์์๋ ๋ฐํ ํ์ ์ด ์์์ผ๋, ์ด์ ๋ MyView๋ฅผ ๋ฐํํ๋๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.
๐ ํ์ ๊ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ Controller V2
public class MemberFormControllerV2 implements ControllerV2 {
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/new-form.jsp";
return new MyView(viewPath);
}
}
RequestDispatcher.forward() ๋ฅผ ํธ์ถํ ๋ถ๋ถ์ด ์ฌ๋ผ์ง๊ณ , MyView๋ฅผ ๋ฐํํ๋ ๊ฒ์ผ๋ก ์ฝ๋๊ฐ ๊ฐ์ ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๐ ํ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ Controller V2
public class MemberSaveControllerV2 implements ControllerV2 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public MyView process(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);
memberRepository.save(member);
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
request.setAttribute("member", member);
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/save-result.jsp";
return new MyView(viewPath);
}
}
๐ ์ ์ฅ๋ ํ์๋ค์ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ Controller V2
public class MemberListControllerV2 implements ControllerV2 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
request.setAttribute("members", members);
// VIEW PATH ์ค์
String viewPath = "/WEB-INF/views/members.jsp";
return new MyView(viewPath);
}
}
๐ Front Controller V2
@WebServlet(name = "frontControllerServletV2", urlPatterns = "/front-controller/v2/*")
public class FrontControllerServletV2 extends HttpServlet {
private Map<String, ControllerV2> controllerMap = new HashMap<>();
/**
* ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์์ฑ ์ ์์ฒญ(Request)๋ณ๋ก ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๋ฑ๋ก
*/
public FrontControllerServletV2() {
controllerMap.put("/front-controller/v2/members/new-form", new MemberFormControllerV2());
controllerMap.put("/front-controller/v2/members/save", new MemberSaveControllerV2());
controllerMap.put("/front-controller/v2/members", new MemberListControllerV2());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("---------- [FRONT CONTROLLER V2 ์คํ] ----------");
String requestURI = request.getRequestURI(); // ์์ฒญ URI ๊ฐ์ ธ์ค๊ธฐ
// ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๊ฐ์ ธ์ค๊ธฐ
ControllerV2 controller = getController(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 404 NOT FOUND
return;
}
// Controller ํธ์ถ
MyView view = controller.process(request, response);
// V2 ์ถ๊ฐ
view.render(request, response);
}
private ControllerV2 getController(String requestURI) {
return controllerMap.get(requestURI);
}
}
๐ V3 - Model ์ถ๊ฐ (์ปจํธ๋กค๋ฌ์์ Sevlet ์ข ์์ฑ ์ ๊ฑฐ์ View ์ด๋ฆ์ ์ค๋ณต ์ ๊ฑฐ)
V3 ์์๋ ์ปจํธ๋กค๋ฌ์์ ์๋ธ๋ฆฟ์ผ๋ก์ ์ข ์์ฑ์ ์ ๊ฑฐํ๋ฉด์, ๋ทฐ ์ด๋ฆ์ ์ค๋ณต๋ ์ ๊ฑฐํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ Servlet ์ข ์์ฑ ์ ๊ฑฐ
์ปจํธ๋กค๋ฌ์์ HttpServletRequest์ HttpServletResponse์ ์ฌ์ฉํ๋ ๋์
์์ฒญ ํ๋ผ๋ฏธํฐ ์ ๋ณด๋ฅผ Map์ ํตํด ๋๊ธฐ๋๋ก ํ๋ฉด HttpServletRequest์ ๋ํ ์์กด์ฑ์ ์์จ ์ ์์ต๋๋ค.
๋ํ request์์ setAttribute๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ๋ ๋์ , ๋ณ๋์ Model ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ฐํํจ์ผ๋ก์จ ์์กด์ฑ์ ์์จ ์ ์์ต๋๋ค.
๋ํ ํ์ฌ ์ปจํธ๋กค๋ฌ์์๋ HttpServletResponse๋ฅผ ์ฌ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด ์ญ์ ์์กด์ฑ์ ์์จ ์ ์์ต๋๋ค.
๐ View ์ด๋ฆ์ ์ค๋ณต ์ ๊ฑฐ
ํ์ฌ ์ปจํธ๋กค๋ฌ์์ ์ง์ ํ๋ ๋ทฐ ์ด๋ฆ์๋ ์๋์ฒ๋ผ ์ค๋ณต์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
// [/WEB-INF/views/] ๊ฐ ์ค๋ณต
String viewPath = "/WEB-INF/views/members.jsp";
String viewPath = "/WEB-INF/views/new-form.jsp";
String viewPath = "/WEB-INF/views/save-result.jsp";
V3์์๋ ์ปจํธ๋กค๋ฌ๋ ๋ทฐ์ ๋ ผ๋ฆฌ์ ์ธ ์ด๋ฆ๋ง ๋ฐํํ๊ณ , ์ค์ ๋ฌผ๋ฆฌ์ ์ธ ์์น๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ์ฒ๋ฆฌํ๋๋ก ๋ณ๊ฒฝํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
- /WEB-INF/views/members.jsp -> members
- /WEB-INF/views/new-form.jsp -> new-form
- /WEB-INF/views/save-result.jsp -> save-result
V3์ ์ต์ข ์ ์ธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๐ ViewModel
/**
* View ์, View์์ ์ฌ์ฉํ Model ๋ด๋น
*/
public class ModelView {
private String viewName;
private Map<String, Object> model = new HashMap<>();
public ModelView(String viewName) {
this.viewName = viewName;
}
public String viewName() {
return viewName;
}
public Map<String, Object> model() {
return model;
}
public void setAttribute(String key, Object value) {
model.put(key, value);
}
}
๐ ControllerV3
public interface ControllerV3 {
ModelView process(Map<String, String> request);
}
ControllerV3์์๋ HttpServletRequest ๋์ Map์ ํตํด Request Parameter๋ฅผ ๋ฐ์ผ๋ฉฐ,
๋ฐํ ํ์ ์ MyView์์ ModelView๋ก ๋ณ๊ฒฝ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๐ ํ์ ๊ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ Controller V3
public class MemberFormControllerV3 implements ControllerV3 {
@Override
public ModelView process(Map<String, String> request) {
return new ModelView("new-form");
}
}
view์ ์ด๋ฆ์ด /WEB-INF/views/new-form.jsp ์์ new-form์ผ๋ก ๋ณ๊ฒฝ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๐ ํ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ Controller V3
public class MemberSaveControllerV3 implements ControllerV3 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> request) {
String username = request.get("username");
int age = Integer.parseInt(request.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
ModelView modelView = new ModelView("save-result");
modelView.setAttribute("member", member);
return modelView;
}
}
๐ ์ ์ฅ๋ ํ์๋ค์ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ Controller V3
public class MemberListControllerV3 implements ControllerV3 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> request) {
List<Member> members = memberRepository.findAll();
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
ModelView modelView = new ModelView("members");
modelView.setAttribute("members", members);
return modelView;
}
}
๐ Front Controller V3
@WebServlet(name = "frontControllerServletV3", urlPatterns = "/front-controller/v3/*")
public class FrontControllerServletV3 extends HttpServlet {
private Map<String, ControllerV3> controllerMap = new HashMap<>();
/**
* ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์์ฑ ์ ์์ฒญ(Request)๋ณ๋ก ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(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 {
System.out.println("---------- [FRONT CONTROLLER V3 ์คํ] ----------");
String requestURI = request.getRequestURI(); // ์์ฒญ URI ๊ฐ์ ธ์ค๊ธฐ
// ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๊ฐ์ ธ์ค๊ธฐ
ControllerV3 controller = getController(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 404 NOT FOUND
return;
}
// (1) HttpServletRequest -> Map ์ผ๋ก ๋ณํ
HashMap<String, String> requestParamMap = createParamMap(request);
// Controller ํธ์ถ
ModelView modelView = controller.process(requestParamMap);
// (2) View ์์ฑ
MyView view = viewResolver(modelView.viewName());
// (3) Model ์ถ๊ฐ
view.render(modelView.model(), request, response);
}
private static HashMap<String, String> createParamMap(HttpServletRequest request) {
HashMap<String, String> requestParamMap = new HashMap<>();
request.getParameterNames()
.asIterator()
.forEachRemaining(it -> requestParamMap.put(it, request.getParameter(it)));
return requestParamMap;
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
private ControllerV3 getController(String requestURI) {
return controllerMap.get(requestURI);
}
}
์ถ๊ฐ๋ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฐ์ (1)์์๋ HttpServlerRequest๋ฅผ Map์ผ๋ก ๋ณํํ์ฌ Controller๋ฅผ ํธ์ถํฉ๋๋ค.
์ดํ (2)์์ ๋ฐํ๋ ModelView์์ ViewName์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ MyView๋ฅผ ์์ฑํฉ๋๋ค.
(3)์์๋ view.render() ์ ModelView์ ๋ด๊ธด Model์ ์ ๋ณด๋ฅผ ํจ๊ป ์ ๋ฌํฉ๋๋ค.
MyView๋ ์๋์ ๊ฐ์ด ๋ฉ์๋๊ฐ ์ถ๊ฐ๋ฉ๋๋ค.
๐ MyView
public class MyView {
private String viewPath;
public MyView(String viewPath) {
// VIEW PATH ์ค์
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
public void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Model -> Attribute
modelToRequestAttribute(model, request);
// FORWARD
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
private static void modelToRequestAttribute(Map<String, Object> model, HttpServletRequest request) {
model.forEach(request::setAttribute);
}
}
๐ V4 - ์ฌ์ฉํ๊ธฐ ์ฌ์ด ์ค์ฉ์ ์ธ ์ปจํธ๋กค๋ฌ
V3์์ ๋๋ถ๋ถ์ ๊ฐ์ ์ด ์ด๋ฃจ์ด์ก์ผ๋, ํญ์ ModelView ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐํํ๋ ์ฝ๋๋ฅผ ์ปจํธ๋กค๋ฌ๋ง๋ค ์์ฑํด ์ฃผ์ด์ผ ํ์ต๋๋ค.
V4์์๋ ์ด๋ฌํ ์ค๋ณต ์์ ์ ๊ท์ฐฎ์์ ๊ฐ์ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
V4 ์์๋ ModelView ๋์ View์ ์ด๋ฆ๋ง ๋ฐํํ๋๋ก ๊ฐ์ ๋ฉ๋๋ค.
V4์ ์ต์ข ์ ์ธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๐ ControllerV4
public interface ControllerV4 {
String process(Map<String, String> request, Map<String, Object> model);
}
๐ ํ์ ๊ฐ์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ Controller V4
public class MemberFormControllerV4 implements ControllerV4 {
@Override
public String process(Map<String, String> request, Map<String, Object> model) {
return "new-form";
}
}
๐ ํ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ Controller V4
public class MemberSaveControllerV4 implements ControllerV4 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> request, Map<String, Object> model) {
String username = request.get("username");
int age = Integer.parseInt(request.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
model.put("member", member);
return "save-result";
}
}
๐ ์ ์ฅ๋ ํ์๋ค์ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ Controller V4
public class MemberListControllerV4 implements ControllerV4 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> request, Map<String, Object> model) {
List<Member> members = memberRepository.findAll();
// Model ์ ๋ฐ์ดํฐ ๋ณด๊ด
model.put("members", members);
return "members";
}
}
๐ Front Controller V4
@WebServlet(name = "frontControllerServletV4", urlPatterns = "/front-controller/v4/*")
public class FrontControllerServletV4 extends HttpServlet {
private Map<String, ControllerV4> controllerMap = new HashMap<>();
/**
* ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์์ฑ ์ ์์ฒญ(Request)๋ณ๋ก ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๋ฑ๋ก
*/
public FrontControllerServletV4() {
controllerMap.put("/front-controller/v4/members/new-form", new MemberFormControllerV4());
controllerMap.put("/front-controller/v4/members/save", new MemberSaveControllerV4());
controllerMap.put("/front-controller/v4/members", new MemberListControllerV4());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("---------- [FRONT CONTROLLER V4 ์คํ] ----------");
String requestURI = request.getRequestURI(); // ์์ฒญ URI ๊ฐ์ ธ์ค๊ธฐ
// ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ์ปจํธ๋กค๋ฌ(Controller) ๊ฐ์ ธ์ค๊ธฐ
ControllerV4 controller = getController(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 404 NOT FOUND
return;
}
// HttpServletRequest -> Map ์ผ๋ก ๋ณํ
Map<String, String> requestParamMap = createParamMap(request);
// Model ์์ฑ - V4 ์ถ๊ฐ
HashMap<String, Object> model = new HashMap<>();
// Controller ํธ์ถ
String viewName = controller.process(requestParamMap, model);
// View ์์ฑ
MyView view = viewResolver(viewName);
view.render(model, request, response);
}
private static HashMap<String, String> createParamMap(HttpServletRequest request) {
HashMap<String, String> requestParamMap = new HashMap<>();
request.getParameterNames()
.asIterator()
.forEachRemaining(it -> requestParamMap.put(it, request.getParameter(it)));
return requestParamMap;
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
private ControllerV4 getController(String requestURI) {
return controllerMap.get(requestURI);
}
}
๐ V5: ์ด๋ํฐ ํจํด์ ์ ์ฉํ ์ ์ฐํ ์ปจํธ๋กค๋ฌ
์ง๊ธ๊น์ง ControllerV1 ๋ถํฐ ControllerV4๊น์ง ์ธํฐํ์ด์ค๋ฅผ ์ด 4๊ฐ๋ฅผ ๋ง๋ค์์ต๋๋ค.
์ฌ๋๋ง๋ค ControllerV3์ด ์ข์ ์๋, ControllerV4๊ฐ ์ข์ ์๋ ์๊ธฐ ๋๋ฌธ์, ์ด๋ ํ ์ปจํธ๋กค๋ฌ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ์ง ์๊ด ์์ด ๋ชจ๋ ์ง์ํ๊ธฐ ์ํด์ ์ด๋ํฐ ํจํด์ ๋์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ์ง์๋์ง ์๋ ์ปจํธ๋กค๋ฌ ํ์์ ์ง์ํ๊ธฐ ์ํด, ์ค๊ฐ์ ์ด๋ํฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
์ฆ ์ด๋ํฐ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ์ง์๋์ง ์๋ ํ์ ์ ์ปจํธ๋กค๋ฌ ์ฌ์ด์์ ์ด๋ค์ ๋ง์ถฐ์ฃผ๋ ์ญํ ์ ์ํํฉ๋๋ค.
V5์์๋ ์ด๋ํฐ๋ฅผ ํตํด ์ปจํธ๋กค๋ฌ(Controller)๊ฐ ์๋๋๋ผ๋ ํด๋นํ๋ ์ข ๋ฅ์ ์ด๋ํฐ๋ง ์์ผ๋ฉด ์ด๋ค์ ๋ค ์ฒ๋ฆฌ(handle)ํ ์ ์๊ธฐ ๋๋ฌธ์, ์ปจํธ๋กค๋ฌ ๋์ ํธ๋ค๋ฌ(Handler)๋ผ๋ ์ฉ์ด๋ฅผ ์ฌ์ฉํ๋๋ก ํ๊ฒ ์ต๋๋ค.
V5์ ์ต์ข ์ ์ธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ํธ๋ค๋ฌ ๋งคํ ์ ๋ณด๋ ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ํธ๋ค๋ฌ(Hanlder = Controller)์ ๋ํ ์ ๋ณด๋ฅผ ์๋ฏธํฉ๋๋ค.
ํธ๋ค๋ฌ ์ด๋ํฐ๋ ํธ๋ค๋ฌ(= ์ปจํธ๋กค๋ฌ)๋ฅผ ์ฒ๋ฆฌ(๋ด๋ถ์์ ํธ๋ค๋ฌ์ ๋ฉ์๋๋ฅผ ํธ์ถ)ํฉ๋๋ค.
๐ MyHandlerAdapter
public interface MyHandlerAdapter {
/**
* ์ฃผ์ด์ง handler(Controller)๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค๋ฉด true๋ฅผ ๋ฐํํ๋ค.
*/
boolean supports(Object handler);
/**
* ์ด๋ํฐ๋ HttpServletRequest ์ HttpServletResponse ๋ฅผ ๊ฐ์ง๊ณ
* ์ต์ข
์ ์ผ๋ก ์ค์ handler(Controller)์ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์์ฒญ์ ์๋ตํฉ๋๋ค.
* -
* ex) handler.process(request, response);
*/
ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException, IOException;
}
๐ ControllerV3๋ฅผ ์ง์ํ๋ ControllerV3HandlerAdapter
public class ControllerV3HandlerAdapter implements MyHandlerAdapter {
@Override
public boolean supports(Object handler) {
// ControllerV3 ํ์
์ด๋ฉด ์ง์ ๊ฐ๋ฅํ๋ค.
return (handler instanceof ControllerV3);
}
@Override
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
ControllerV3 controller = (ControllerV3) handler;
// Request Param ์ธํ
Map<String, String> params = createParamMap(request);
return controller.process(params);
}
private static Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> params = new HashMap<>();
request.getParameterNames()
.asIterator()
.forEachRemaining(it -> params.put(it, request.getParameter(it)));
return params;
}
}
๐ ControllerV4๋ฅผ ์ง์ํ๋ ControllerV4HandlerAdapter
public class ControllerV4HandlerAdapter implements MyHandlerAdapter {
@Override
public boolean supports(Object handler) {
// ControllerV3 ํ์
์ด๋ฉด ์ง์ ๊ฐ๋ฅํ๋ค.
return (handler instanceof ControllerV4);
}
@Override
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
ControllerV4 controller = (ControllerV4) handler;
// Request Param ์ธํ
Map<String, String> params = createParamMap(request);
Map<String, Object> model = new HashMap<>();
String viewName = controller.process(params, model);
ModelView modelView = new ModelView(viewName);
modelView.setModel(model);
return modelView;
}
private static Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> params = new HashMap<>();
request.getParameterNames()
.asIterator()
.forEachRemaining(it -> params.put(it, request.getParameter(it)));
return params;
}
}
๐ Front Controller V5
@WebServlet(name = "frontControllerServletV5", urlPatterns = "/front-controller/v5/*")
public class FrontControllerServletV5 extends HttpServlet {
// ํธ๋ค๋ฌ ๋งคํ ์ ๋ณด - ์์ฒญ(Request) URI์ ๋์๋๋ ํธ๋ค๋ฌ(= Controller)๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
private final Map<String, Object> handlerMappingMap = new HashMap<>();
// ํธ๋ค๋ฌ๋ค์ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ํธ๋ค๋ฌ ์ด๋ํฐ์ ๋ชฉ๋ก์ด๋ค.
private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();
public FrontControllerServletV5() {
initHandlerMappingMap();
initHandlerAdapters();
}
/**
* ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์์ฑ ์ ์์ฒญ(Request)๋ณ๋ก ๋งคํ(Mapping)๋๋ ํธ๋ค๋ฌ(= Controller) ๋ฑ๋ก
*/
private void initHandlerMappingMap() {
handlerMappingMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3());
handlerMappingMap.put("/front-controller/v5/v3/members/save", new MemberSaveControllerV3());
handlerMappingMap.put("/front-controller/v5/v3/members", new MemberListControllerV3());
handlerMappingMap.put("/front-controller/v5/v4/members/new-form", new MemberFormControllerV4());
handlerMappingMap.put("/front-controller/v5/v4/members/save", new MemberSaveControllerV4());
handlerMappingMap.put("/front-controller/v5/v4/members", new MemberListControllerV4());
}
/**
* ํธ๋ค๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ HandlerAdapter ๋ฑ๋ก
*/
private void initHandlerAdapters() {
handlerAdapters.add(new ControllerV3HandlerAdapter());
handlerAdapters.add(new ControllerV4HandlerAdapter());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("---------- [FRONT CONTROLLER V5 ์คํ] ----------");
// ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ํธ๋ค๋ฌ(= Controller) ๊ฐ์ ธ์ค๊ธฐ
Object handler = getHandler(request);
if (handler == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 404 NOT FOUND
return;
}
// ์กฐํ๋ Handler๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ HandlerAdapter ์กฐํ
MyHandlerAdapter adapter = getHandlerAdapter(handler);
// handler ์ฒ๋ฆฌ Adapter์ ์์
ModelView modelView = adapter.handle(request, response, handler);
// View ์์ฑ
MyView view = viewResolver(modelView.viewName());
view.render(modelView.model(), request, response);
}
/**
* ์์ฒญ(Request)์ ๋งคํ(Mapping)๋๋ ํธ๋ค๋ฌ(=Controller) ๊ฐ์ ธ์ค๊ธฐ
*/
private Object getHandler(HttpServletRequest request) {
return handlerMappingMap.get(request.getRequestURI());
}
/**
* Handler๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ HandlerAdapter ์กฐํ
*/
private MyHandlerAdapter getHandlerAdapter(Object handler) {
return handlerAdapters.stream()
.filter(it -> it.supports(handler))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("Handler Adapter๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. handler=%s".formatted(handler)));
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
}
V2, V1์ ์กฐ๊ธ ๊ท์ฐฎ์์ง๊ธฐ ๋๋ฌธ์ ์๋ตํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ Reference
'๐๏ธ Spring > Web MVC' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[MVC] ์์ฒญ ๋งคํ (@RequestMapping, PathVariable) (0) | 2021.12.29 |
---|---|
[MVC] HandlerMapping๊ณผ HandlerAdapter (0) | 2021.12.29 |
[MVC] ์คํ๋ง ์น MVC ๊ตฌ์กฐ (0) | 2021.12.26 |
[MVC] ์๋ธ๋ฆฟ - HttpServletResponse (0) | 2021.12.25 |
[MVC] ์๋ธ๋ฆฟ - HttpServletRequest (0) | 2021.12.25 |