์น์ 5๋ ํ์ฌ์ Spring MVC๊น์ง ์ค๊ฒ๋ ๊ณผ์ ์ ์ฐจ๊ทผ์ฐจ๊ทผ ์ดํด๋ดค๋ค. ์์ ๋ฐฐ์ด ์ ์์ ๊ฐ์ฅ ํฐ ๋ณํ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๊ฐ ์ถ๊ฐ๋์๋ค๋ ๊ฒ์ด๋ค. ์์ฒญ๊ณผ ์๋ต์ ์ปจํธ๋กค๋ฌ์์ ์ฒ๋ฆฌํ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์ ์ญํ ์ ์ ๊ฐํด ๊ฐ๋ฐ์๋ ์ ์ ํธ๋ฆฌํ๊ฒ ์ปจํธ๋กค๋ฌ๋ฅผ ์์ฑํ ์ ์๊ฒ ๋์๋ค. ๊ทธ๋ฆฌ๊ณ ์ค๋ณต๋๋ ์ฝ๋๋ฅผ ์ต๋ํ ์ค์ด๋ฉฐ ์ ์ง์ ์ธ ๊ตฌ์กฐ์ ๋ณํ๋ฅผ ์ฃผ์๋ค.
โ๏ธ
์๋ชป๋ ์ ๋ณด๊ฐ ์์ ์ ์์ต๋๋ค
โ๏ธ V1_ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ฅผ ๋์ ํ์.
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ก ์์ฒญ์ ๋ฐ์ ์๋ง๋ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์ ํธ์ถํ๋ค.
- ๋๋จธ์ง ์ปจํธ๋กค๋ฌ๋ ์๋ธ๋ฆฟ์ ์ฌ์ฉํ์ง ์๋๋ค.
โบ ControllerV1.interface
public interface ControllerV1 {
void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
๋ก์ง์ ์ผ๊ด์ฑ์ ์ํด ์ธํฐํ์ด์ค๋ฅผ ์ถ๊ฐํ์ฌ ์๋ธ๋ฆฟ๊ณผ ๋น์ทํ ๋ชจ์์ ์ฝ๋๋ฅผ ๊ตฌํํ๋ค.
โบ MemberSaveControllerV1.class
- ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ ๊ทธ ๊ฒฝ๋ก๋ก ์์ฒญ๊ณผ ์๋ต์ ๋๊ธด๋ค.
- RequestDispatcher์ ์ฌ์ฉํ๋ค.
@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);
request.setAttribute("member", member);
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
๋ค์ด์จ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ์ปจํธ๋กค๋ฌ์ด๋ค. ํด๋น ์ปจํธ๋กค๋ฌ๋ ๊ฒฝ๋ก๋ฅผ ์ ์ํ๊ณ ์๊ณ , ์ ์๋ ๊ฒฝ๋ก๋ฅผ viewPath ๋ด์ ํ request.getRequestDispatcher๋ก ์ด ๊ฒฝ๋ก๋ก ๊ฐ ์ ์๋ dispatcher์ ๋ง๋ค์ด ์์ฒญ๊ณผ ์๋ต์ ๋๊ธด๋ค. ์ด๋ request์ member๋ฅผ ๋ด์ ๋ฃ๊ธฐ๋ ์ด์ ๋ ์ด๋ค ์์ฒญ์ธ์ง ์๊ธฐ ์ํจ์ด๋ค.
Q. ์ ์ ๋ณด๋ฅผ request์ ๋ด์๊น? response์ ๋ด์์ ํ๋ฉด์ ์ถ๋ ฅํด์ผํ๋๊ฒ ์๋๊น?
A. reponse๋ ๋ธ๋ผ์ฐ์ ์ ์ค์ ๋ก ๋ณด๋ด๋ ๋ฐ์ดํฐ๋ง ๋ด๋๋ค. request๋ JSP(JavaServer Page, ์๋ฐ ์ฝ๋๋ก HTML ํ์ผ์ ๋ง๋๋ ์๋ฒ์ฉ ํ์ผ)์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ฃผ๊ธฐ ์ํ ์์ ๋ฐ๊ตฌ๋ ๊ฐ์ ์ฉ๋์ด๋ค. ๊ทธ๋์ ๋ณด๋ด๋ ์ฉ๋๋ก ์ ๊น๋ง ์ ์ฅํ๊ธฐ ์ํด setAttribute๋ฅผ ์ฌ์ฉํ๋ค. JSP๋ ์๋ง๋ ์ด๋ฆ ๋ฐ์ดํฐ์ ๋์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด JSP๋ ํ๋ฉด์ ๋ณด๋ด๊ธฐ ์ํ HTML์ ๋ง๋ ํ, response์ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๋๋ก ํ๋ค.
โบ FrontControllerServletV1.class
private Map<String, ControllerV1> controllerMap = new HashMap<>();
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());
}
์น์ด ์ฒ์ ์ผ์ง๋ฉด ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ controllerMap์ ์ ์ฅํ๋ค. URL์ด ํค๊ฐ ๋๊ณ ์ปจํธ๋กค๋ฌ ๊ฐ์ฒด๊ฐ ๊ฐ์ด ๋๋ค.
System.out.println("FrontControllerServletV1.service");
String requestURI = request.getRequestURI();
ControllerV1 controller = controllerMap.get(requestURI);
if(controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
controller.process(request,response);
์ค์ ์์ฒญ์ด /front-controller/v1/members/save ๊ฒฝ๋ก๋ก ๋ค์ด์ค๋ฉด requestURI์ ๋ฃ์ด์ง๋ค. ๊ทธ๋ฆฌ๊ณ requestURI๋ฅผ ๊ฐ์ง๊ณ controllerMap์์ ๋ฏธ๋ฆฌ ์ ์ฅํด๋๋ MemberSaveControllerV1 ๊ฐ์ฒด๋ฅผ ๊บผ๋ด์ process( ) ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋MemberSaveControllerV1.class์ process ๋ฉ์๋๊ฐ ์งํ๋๋ค.
์๊น ์์ ์ ์๋ฏ์ด MemberSaveControllerV1.class์์ dispatcher๋ฅผ ํตํด ๋ธ๋ผ์ฐ์ ์ ์๋ต์ ๋ณด๋ธ๋ค.
โถ ์์ (MemberSaveController)
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ(FrontControllerServletV1)๋ก ์์ฒญ์ด ๋ค์ด์จ๋ค
- ๋ค์ด์จ ๊ฒฝ๋ก๋ก ์ ์ฅํด๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ธ๋ค.
- ๊บผ๋ธ ๊ฐ์ฒด์ process ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
- process ๋ฉ์๋์์ ์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ์ฅํ๋ค.
- dispatcher๋ก HTML์ ๋ง๋ค์ด ๋ธ๋ผ์ฐ์ ๋ก ๋ณด๋ธ๋ค.
โ๏ธ V2_ View๋ฅผ ๋ถ๋ฆฌํ์.
- ๋ธ๋ผ์ฐ์ ์ ์ถ๋ ฅํ๊ธฐ ์ํ(view ๋ถ๋ถ) ์ฝ๋๋ฅผ ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ์ค๋ณตํด์ ์ฝ๋๋ฅผ ์ ์ด์ผํ๋ค.
- ์ค๋ณต๋ ์ฝ๋๋ฅผ ์์ ๊ณ view๋ฅผ ๋ถ๋ฆฌํ๋ค.
โบ MyView.class
private String viewPath;
public MyView(String viewPath) {
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
V1์์๋ Controller๊ฐ dispatcher.forward๊น์ง ์ฒ๋ฆฌํ๋ค. V2์์๋ MyView ํด๋์ค๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด View๋ฅผ ์ฒ๋ฆฌํ๋๋ก ํ๋ค. ์๋ง๋ ์ปจํธ๋กค๋ฌ์์ ํ๋ฉด์ ํ์๋ ๊ฒฝ๋ก๋ฅผ MyView๋ก ๋ฐํํ ๊ฒ์ด๋ค. ๊ทธ๋ผ ๊ทธ ๊ฒฝ๋ก๋ฅผ ๋ฐ์ render ๋ฉ์๋์์ ์ฒ๋ฆฌํด ์ฌ์ฉ์ ํ๋ฉด์ ์ถ๋ ฅ๋๋ค.
โบ MemberSaveControllerV2.class
@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);
request.setAttribute("member", member);
return new MyView("/WEB-INF/views/save-result.jsp");
}
ํด๋น ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง๊ณ MyView ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ์ด๋ค ๋ทฐ๋ก ๋ณด์ฌ์ค์ง ์ ๋ณด๋ง ๋๊ธด ํ, ์ค์ ํ๋ฉด์ MyView ๊ฐ์ฒด๊ฐ ๋ด๋นํ ๊ฒ์ด๋ค.
โบ FrontControllerServletV2.class
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestURI = request.getRequestURI();
ControllerV2 controller = controllerMap.get(requestURI);
if(controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
MyView view = controller.process(request, response);
view.render(request, response);
}
V1์ controller.process()๋ง ํธ์ถ๋๋ค. V2๋ controller.process()์์ view์ ๋๊ธธ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํด์ request์ ๋ด๊ณ , ์ด๋ค JSP๋ก ๊ฐ์ง MyView๋ฅผ ๋ฐํํ๋ค. ๊ทธ ๋ค์ view.render๋ฅผ ํตํด ์ง์ ๋ JSP๋ก forwardํด์ ๋ธ๋ผ์ฐ์ ์ ํ๋ฉด์ด ๋ณด์ด๋๋ก ํ๋ค.
โถ ์์ (MemberSaveController)
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ(FrontControllerServletV1)๋ก ์์ฒญ์ด ๋ค์ด์จ๋ค
- ๋ค์ด์จ ๊ฒฝ๋ก๋ก ์ ์ฅํด๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ธ๋ค.
- ๊บผ๋ธ ๊ฐ์ฒด์ process ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
- process ๋ฉ์๋์์ ์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ์ฅํ๋ค.
- process ๋ฉ์๋์์ ๊ฒฝ๋ก๋ฅผ ๋ฐํํ๋ค.
- ๋ฐํ๋ ๊ฒฝ๋ก๋ก ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ MyView ํด๋์ค์ render ๋ฉ์๋์ ๊ฐ๋ค.
- render์์ ํ๋ฉด์ ๋ง๋ ๋ค.
โ๏ธ V3_ ์๋ธ๋ฆฟ ์ข ์์ฑ์ ์ ๊ฑฐํ์.
- HttpServletRequest, HttpServletResponse์ด ๊ผญ ํ์ํ์ง ์์ ๊ฒ ๊ฐ๋ค.
- request ๊ฐ์ฒด๋ฅผ Model๋ก ๋์ ํด ์ฌ์ฉํด๋ณธ๋ค.
- ๋ทฐ ์ด๋ฆ์ ์ค๋ณต์ ์ง์๋ณธ๋ค.
โบ MemberSaveControllerV3.class
@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;
}
mv์๋ "save-result"์ member ์ ๋ณด๊ฐ ๋ด๊ธด model์ ๋ฐํํ๋ค.
โบFrontControllerServeltV3.class
Map<String, String> paramMap = createParamMap(request);
ModelView mv = controller.process(paramMap);
String viewName = mv.getViewName();
MyView view = viewResolver(viewName);
view.render(mv.getModel(), request, response);
private MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
service( ) ๋ฉ์๋์์ ์ฌ์ฉ์๊ฐ ์ ์ด ๋ฃ์ ๋ฐ์ดํฐ๋ฅผ createParamMap( ) ๋ฉ์๋๋ก ๊บผ๋ธ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ ๋ณด๋ฅผ ์ปจํธ๋กค๋ฌ์ ์๋ process( ) ๋ฉ์๋๋ก ๋ณด๋ธ๋ค. process( ) ๋ฉ์๋์์ ๊ฒฐ๊ณผ์ ์ผ๋ก "save-result"๋ผ๋ view ์ด๋ฆ๊ณผ ("member", member)๋ฅผ mv์ ๋ด์๊ณ , ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ mv๋ฅผ ๋ฐ๋๋ค. ๊ทธ๋ฌ๋ฉด mv.getViewName( )์ ํตํด ๋ทฐ ์ด๋ฆ์ ๊บผ๋ด๊ณ , ๋ทฐ ์ด๋ฆ์ viewResolver( ) ๋ฉ์๋๋ก ๋ณด๋ด ์ค์ ๋ฌผ๋ฆฌ ๋ทฐ ๊ฒฝ๋ก๋ก ๋ณ๊ฒฝํ๋ค.
V1๊ณผ V2๋ ์ปจํธ๋กค๋ฌ๊ฐ ์ง์ request์ ์ ๋ณด๋ฅผ ๋ฃ์๋ค. ๊ทธ๋ฐ๋ฐ V3์์๋ ์ปจํธ๋กค๋ฌ๊ฐ Model์ ๋ฐ์ดํฐ๋ง ๋ฃ๊ณ , ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๊ฐ view.render( )๋ก ์ ๋ฌํด ๊ทธ ์์์ setAttribute๊ฐ ์ด๋ค์ง๋ค.
โบ MyView.class
public void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
modelToRequestAttribute(model, request);
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
private static void modelToRequestAttribute(Map<String, Object> model, HttpServletRequest request) {
model.forEach((key, value) -> request.setAttribute(key, value));
}
render ๋ฉ์๋๋ฅผ ์๋กญ๊ฒ ์ค๋ฒ๋ก๋ฉ(๊ฐ์ ์ด๋ฆ์ ๋ฉ์๋, ๋ค๋ฅธ ์๊ทธ๋์ฒ)ํ๋ค. ๊ทธ ์ด์ ๋ view.render์ mv.getModel์ด ์ถ๊ฐ๋์ด ๊ทธ๊ฑธ ๋ฐ์ ์ ์๋ model์ ๋งค๊ฐ๋ณ์๋ก ๋ฃ์ด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
render( ) ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด modelToRequestAttribute( ) ๋ฉ์๋์์ model์ ๋ฃ์ด๋ ์ ๋ณด๋ฅผ forEach๋ก ๊บผ๋ด setAttribute๋ก request์ ์ ์ ์ ์ฅํ๊ณ , dispatcher.forward( ) ๋ฉ์๋๋ก ์ฌ์ฉ์ ๋ธ๋ผ์ฐ์ ์ ํ๋ฉด์ด ์ก์ถ๋ ์ ์๊ฒ ๋๋ค.
โถ ์์ (MemberSaveController)
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ(FrontControllerServletV1)๋ก ์์ฒญ์ด ๋ค์ด์จ๋ค
- ๋ค์ด์จ ๊ฒฝ๋ก๋ก ์ ์ฅํด๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ธ๋ค.
- ๊บผ๋ธ ๊ฐ์ฒด์ process ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
- process ๋ฉ์๋์์ ์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ์ฅํ๋ค.
- process ๋ฉ์๋์์ ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๋ค.
- mv์ ์ ๋ณด์ ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ ๊ฐ์ง๊ณ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์ ์จ๋ค.
- ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ viewResolver ๋ฉ์๋๋ก ๋ฌผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝ๋๋ค.
- ๊ทธ ๊ฒฝ๋ก๋ก render ๋ฉ์๋๊ฐ ์คํ๋๋ค.
- MyView ํด๋์ค์์ model์ request.setAttribute๋ก ๋ณ๊ฒฝํ๊ณ
- ๊ทธ ํ ๋ธ๋ผ์ฐ์ ์ ์ก์ถํ๋ค.
โ๏ธ V4_ ์ข ๋ ์ค์ฉ์ ์ด๊ฒ ์ฝ๋๋ฅผ ๋ฐ๊ฟ๋ณด์.
-
ModelView ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐํํด์ผ ํ๋ ๋ถ๋ถ์ด ์กฐ๊ธ์ ๋ฒ๊ฑฐ๋กญ๋ค.
โบ MemberSaveControllerV4.class
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
model.put("member", member);
return "save-result";
}
V3๋ model ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ๋ง๋ค์๋ค. ๊ทธ๋ฐ๋ฐ V4๋ model.put์ผ๋ก ์ ๋ณด๋ฅผ ๋ฃ๊ณ , reuturn์ ํตํด ๊ฐ๋จํ๊ฒ ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๋ค. ๊ทธ์ ์ปจํธ๋กค๋ฌ๋ map์ ๊ฐ์ ๋ฃ๊ณ view ์ด๋ฆ๋ง ๋ฐํํ ๊ฒ์ด๋ค. ๊ทธ๋์ V3์ ์๋ mv๊ฐ V4์ ์๋ค.
โบFrontControllerServletV4.class
Map<String, String> paramMap = createParamMap(request);
Map<String, Object> model = new HashMap<>();
String viewName = controller.process(paramMap, model);
MyView view = viewResolver(viewName);
view.render(model, request, response);
Map์ผ๋ก ๋ฐ๋ model ์ฝ๋๊ฐ ์ถ๊ฐ๋์๋ค. V3์ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์๋ model ๊ฐ์ฒด๋ฅผ ๊ณ์ํด์ ๋ง๋ค์ด์ค์ผํ๋ค. ๊ทธ๋ฐ ๋ฒ๊ฑฐ๋ก์์ V4๊ฐ Map์ผ๋ก model์ ์ง์ ๋ง๋ค์ด ๋๊ฒจ์ฃผ๋ ์ปจํธ๋กค๋ฌ๋ ๊ทธ๋ฅ model.put๋ง ํ๋ฉด ๋๋ ๊น๋ํ ์ฝ๋๊ฐ ์์ฑ๋๋ค.
โถ ์์ (MemberSaveController)
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ(FrontControllerServletV1)๋ก ์์ฒญ์ด ๋ค์ด์จ๋ค
- ๋ค์ด์จ ๊ฒฝ๋ก๋ก ์ ์ฅํด๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ธ๋ค.
- ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ Map์ผ๋ก ๋ง๋ ๋ค.
- ๋น์ด์๋ model(Map)์ ๋ฏธ๋ฆฌ ์์ฑํ๋ค.
- ๊บผ๋ธ ๊ฐ์ฒด์ process ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
- process ๋ฉ์๋์์ ์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ์ฅํ๋ค.
- process ๋ฉ์๋์์ ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๋ค.
- model์ ์ด๋ฏธ ํ๋ก ํฐ ์ปจํธ๋กค๋ฌ์์ map์ผ๋ก ๊ตฌํํด๋จ๊ธฐ์ ํธ๋ฆฌํ๊ฒ
model.put์ผ๋ก ์ ๋ณด๋ฅผ ๋ฃ๋๋ค. (model์ ๊ฐ์ฒด ์์ฑ์ด ํ์ ์์ด์ง) - ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ viewResolver ๋ฉ์๋๋ก ๋ฌผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝ๋๋ค.
- ๊ทธ ๊ฒฝ๋ก๋ก render ๋ฉ์๋๊ฐ ์คํ๋๋ค.
- MyView ํด๋์ค์์ model์ request.setAttribute๋ก ๋ณ๊ฒฝํ๊ณ
- ๊ทธ ํ ๋ธ๋ผ์ฐ์ ์ ์ก์ถํ๋ค.
โ๏ธ V5 (1)_ ํธ๋ค๋ฌ ์ด๋ํฐ ๋ง๋ค๊ธฐ
-
ModelView ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐํํด์ผ ํ๋ ๋ถ๋ถ์ด ์กฐ๊ธ์ ๋ฒ๊ฑฐ๋กญ๋ค.
โบ FrontControllerServletV5.class
private final Map<String, Object> handlerMappingMap = new HashMap<>();
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());
}
hanlderMappingMap์ด๋ ์ ์ฅ์๋ฅผ ๋ง๋ค์๋ค. ์ด ์ ์ฅ์์ V3์ ๊ด๋ จ๋ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ด์ ๊ฒ์ด๋ค. key๋ ์์ฒญ์ด ๋ค์ด์จ ์ฃผ์๊ฐ ๋ ๊ฒ์ด๊ณ , ์ฃผ์๋ก ์์ฒญ์ด ๋ค์ด์ค๋ฉด ๊ทธ์ ๋ง๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ผ ๊ฒ์ด๋ค.
private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();
private void initHandlerAdapters() {
handlerAdapters.add(new ControllerV3HandlerAdapter());
}
V3๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ์ด๋ํฐ๋ฅผ handlerAdapters์ ์ถ๊ฐํ๋ค. ํ์ฌ ์ฝ๋์์๋ V3๋ง ๋ฃ์ด๋จ์ง๋ง, V4๋ ์ถ๊ฐํ ์ ์๋ค. ๊ทธ๋์ List ํํ๋ก ์ ์ฅํ๋ค.
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object handler = getHandler(request);
if (handler == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
private Object getHandler(HttpServletRequest request) {
String requestURI = request.getRequestURI();
return handlerMappingMap.get(requestURI);
}
request๋ก ๊ฒฝ๋ก๊ฐ ๋ค์ด์ค๋ฉด handlerMappingMap์ ๊ฐ์ ๊ฒฝ๋ก์ ๋ง์ถฐ ๋ฏธ๋ฆฌ ์ ์ฅํด๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ธ๋ค. ๊บผ๋ธ ๊ฐ์ฒด๋ handler์ ๋ฃ์ด๋๋ค.
MyHandlerAdapter adapter = getHandlerAdapter(handler);
private MyHandlerAdapter getHandlerAdapter(Object handler) {
for (MyHandlerAdapter adapter : handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
throw new IllegalArgumentException("handler adapter๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. handler=" + handler);
}
handler์๋ ๊ฐ์ฒด๊ฐ ๋ค์ด์๋ค. ๋ง์ฝ ์ฌ์ฉ์๊ฐ ์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ์ฅํ๋ ํ์ด์ง๋ฅผ ๋์ ๋ค๋ฉด, MemberSaveControllerV3() ๊ฐ์ฒด๊ฐ ๋ค์ด์์ ๊ฒ์ด๋ค. ๊ทธ๊ฑธ getHandlerAdapter๊ฐ ์ธ์๋ก ๋ฐ์๋ค.
handlerAdapter์๋ new ControllerV3HandlerAdapter()๋ฅผ ๋ฃ์ด๋จ๋ค. ๊ทธ๋ฌ๋ฉด adapter ์ค MemberSaveControllerV3()๊ฐ ControllerV3HandlerAdapter()๊ฐ ๊ฐ์ ์ธ์คํด์ค๊ฐ ๋ง๋์ง supports ๋ฉ์๋๋ก ํ์ธํ ๊ฒ์ด๋ค.
โบ ControllerV3HandlerAdapter.class
@Override
public boolean supports(Object handler) {
return (handler instanceof ControllerV3);
}
๊ฐ์ ์ธ์คํฐ์ค๊ฐ ๋ง๋์ง instanceof๋ฅผ ํตํด ํ์ธํ๋ค. ๊ฐ์ ์ธ์คํด์ค๋ผ๋ฉด true๋ฅผ ๋ฐํํ๋ค.
Q. handler๋ ControllerV3์ ์ธ์คํด์ค์ธ์ง ์ด๋ป๊ฒ ์๋๊ฑธ๊น?
A. MemberSaveControllerV3๊ฐ ControllerV3๋ฅผ implementsํ๊ณ ์๋ค.public class MemberSaveControllerV3 implements ControllerV3โ
์๋ฐ ํ์ ๊ฒ์ฌ๋ก ์ฒดํฌํ์ฌ true๊ฐ ๋์จ๋ค.
@Override
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
ControllerV3 controller = (ControllerV3) handler;
Map<String, String> paramMap = createParamMap(request);
ModelView mv = controller.process(paramMap);
return mv;
}
handle ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ก Object handler๋ฅผ ์ถ๊ฐํ๋ค. supports ๋ฉ์๋๋ฅผ ํตํด handler(MemberSaveControllerV3 ๋ผ๊ณ ๊ฐ์ )๊ฐ ControllerV3์ ๊ฐ์ ์ธ์คํด์ค์ธ์ง ํ์ธ์ ํ๊ณ ์ฐธ์ด ๋์๋ค. ๊ทธ๋ฌ๋ฉด request๋ก ๋ฐ์์จ ๋์ด์ ์ด๋ฆ ์ ๋ณด๋ฅผ paramMap์ ๋ค๊ณ MemberSaveControllerV3์ process ๋ฉ์๋๋ฅผ ํธ์ถ์ํจ๋ค.
process ๋ฉ์๋๋ ๋ชจ๋ธ๋ทฐ ํ์ ์ผ๋ก mv๋ฅผ ๋ฐํํ๋ค. ๋ฐํ๋ mv๋ handle ๋ฉ์๋๋ก ์ ๋ค์ return mv๊ฐ ๋๋ค. ๊ทธ ํ ์ด mv๋ ํ๋ก ํธ์ปจํธ๋กค๋ฌ์ service ๋ฉ์๋๋ก ์ ๋ฌ๋๋ค.
โบ FrontControllerServletV5.class
MyHandlerAdapter adapter = getHandlerAdapter(handler);
ModelView mv = adapter.handle(request, response, handler);
String viewName = mv.getViewName();
MyView view = viewResolver(viewName);
view.render(mv.getModel(), request, response);
handler์๋ MemberSaveControllerV3๊ฐ ์๋ค๊ณ ๊ฐ์ ํ์. ๊ทธ๋ฌ๋ฉด ๊ทธ์ ๋ง๋ ์ด๋ํฐ๋ฅผ getHandAdatper๋ฅผ ํตํด ๊บผ๋ด์ฌ ๊ฒ์ด๋ค. ๊ทธ๋ ๊ฒ ๊บผ๋ด์จ ์ด๋ํฐ๋ ControllerV3HandlerAdapter๊ฐ ๋๋ค.
๊ทธ๋ฆฌ๊ณ adapter.handle์ ControllerV3HandlerAdapter์ handle ๋ฉ์๋๊ฐ ๋๊ณ ์ด๋ถ๋ถ์ ๋ํ ๋ด์ฉ์ด ๋ฐ๋ก ์์ ์๋ ๊ฒ์ด๋ค. handle ๋ฉ์๋๋ ์ต์ข ์ ์ผ๋ก mv๋ฅผ ๋ฆฌํดํ๋ค. ๊ทธ๋ผ ModelView mv = adapter.handle(request, response, handler);์ ๋ฆฌํด๋ mv๊ฐ ๋ค์ด์ค๊ฒ ๋๊ณ , ๋ธ๋ผ์ฐ์ ์ ๊ฒฐ๊ณผ๊ฐ ๋ณด์ด๊ฒ ๋๋ค.
โถ ์์ (MemberSaveController)
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ(FrontControllerServletV1)๋ก ์์ฒญ์ด ๋ค์ด์จ๋ค
- ๋ค์ด์จ ๊ฒฝ๋ก๋ก ์ ์ฅํด๋ ๊ฐ์ฒด๋ฅผ ๊บผ๋ธ๋ค.
- ๊ฐ์ฒด์ ์ด๋ํฐ๊ฐ ๋ง๋์ง supports ๋ฉ์๋๋ก ํ์ธ ํ ๋ง์ผ๋ฉด ์ฐธ์ ๋ณด๋ธ๋ค.
- true๊ฐ ๋์ค๋ฉด ํด๋น ์ปจํธ๋กค๋ฌ ํด๋์ค ๋ด๋ถ์ ์๋ process ๋ฉ์๋๋ฅผ ์คํํ๋ค.
- ์ปจํธ๋กค๋ฌ์์ ๊ฐ์ ๋ฐํํ๋ฉด ์ด๋ํฐ๊ฐ ๋ฐ๊ณ ์ด๋ํฐ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ก ๋ฐํํ๋ค.
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ๋ฐํ๋ ๊ฐ์ ๊ฐ์ง๊ณ ๋ทฐ๋ก ๋ณด๋ธ๋ค.