Front-Controller ํจํด
by rlaehddnd0422ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด
- ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ ์๋ธ๋ฆฟ ํ๋๋ก ํด๋ผ์ด์ธํธ๋ค์ ์์ฒญ์ ๋ฐ์ต๋๋ค.
- ๊ธฐ์กด์๋ ํ๋์ ์ค๋ ๋๊ฐ ํ๋์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ฐ์ ์ฌ์ฉํ์ง๋ง ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ๊ฐ ํ๋์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ฐ์ ์ฌ์ฉ( ๊ณตํต ์ ๋ฌด ์ฒ๋ฆฌ) ํ๋ค๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
- ์ ๊ตฌ๋ฅผ ํ๋๋ก ๋ง๋ค์๊ธฐ ๋๋ฌธ์ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ๊ณตํต ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
์คํ๋ง ์น MVC์ ํต์ฌ๋ ๋ฐ๋ก FrontController์ ๋๋ค.
DispatcherServlet์ด FrontController ํจํด์ผ๋ก ๊ตฌํ๋์ด ์๋๋ฐ, ์ฒ์๋ถํฐ ์ต์ข ์ FrontController ํจํด์ ์ค๋ช ํ๊ธฐ์ ์ด๋ ค์์ด ์์ด ๋จ๊ณ์ ์ผ๋ก ํ์ด ๋๊ฐ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ FrontController ํจํด์ ๋ฒ์ 1๋ถํฐ 3๊น์ง ๋จ๊ณ์ ์ผ๋ก ๋์ ํด๋ณด๊ณ ๋ค์ ํฌ์คํ ์์ ๋ฒ์ 4, 5๋ฅผ ๋์ ํด๋ณด๊ฒ ์ต๋๋ค.
Ver 1. ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ๋์
- Client ์์ HTTP ์์ฒญ์ด ๋ค์ด์ต๋๋ค.
- (Front Controller ์์) ์์ฒญ ๋ฉ์์ง๋ก๋ถํฐ ๋ฐ์ URI์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋งคํํฉ๋๋ค.
- (Front Controller ์์) ๋งคํ๋ ์ปจํธ๋กค๋ฌ๋ฅผ ํธ์ถํฉ๋๋ค.
- (Controller ์์) JSP๋ก Forward๋ฅผ ํฉ๋๋ค.
- JSP๋ก๋ถํฐ Client์๊ฒ HTML ์๋ต์ ํฉ๋๋ค.
๋ง๋ก ์ค๋ช ํ๋ ๊ฒ๋ณด๋ค ์ฝ๋๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค.
ControllerV1 (Interface)
public interface ControllerV1 {
void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
HTTP ์์ฒญ์ ๋ฐ๋ผ ์ฌ์ฉํ ์ปจํธ๋กค๋ฌ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ๋คํ์ฑ์ ์ด์ฉํ๊ธฐ ์ํด ์ผ๋จ ์ธํฐํ์ด์ค๋ฅผ ๋์ ํ์ต๋๋ค.
(process ๋ฉ์๋ : JSP๋ก forward)
Front-Controller
@WebServlet(name="frontControllerServletV1", urlPatterns = "/front-controller/v1/*")
public class FrontControllerServletV1 extends HttpServlet {
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());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
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);
}
}
1. ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ์์ฑ์์์ URI์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋งคํํ์ฌ ControllerMap์ ์ ์ฅ
( ๋ฑ๋ก ํผ URI ) - ( MemberFormControllerV1 )
( ์ ์ฅ URI ) - ( MemberSaveControllerV1 )
( ๋ชฉ๋ก URI ) - ( MemberListControllerV1 )
2. service์์ request๋ก ๋ถํฐ URI๋ฅผ getํ์ฌ ControllerMap์ผ๋ก ๋ถํฐ ์ปจํธ๋กค๋ฌ ์ถ์ถ
3. ๊ฐ controller์์ process ๋ฉ์๋๋ก jsp๋ก forward (๋คํ์ฑ ํ์ฉ)
๋ฑ๋ก
public class MemberFormControllerV1 implements ControllerV1 {
@Override
public void process(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. process() ๋ฉ์๋์์ viewPath : /WEB-INF/views/new-form.jsp๋ก ์ด๋
- โ๏ธ/WEB-INF/* ๊ฒฝ๋ก๋ ์ธ๋ถ ์ ๊ทผ ๋ถ๊ฐ
2. RequestDispatcher๋ฅผ ํตํด JSP๋ก ์ด๋
- dispatcher.forward() : ๋ค๋ฅธ Servlet์ด๋ JSP๋ก ์ด๋ํ ์ ์๋ ๊ธฐ๋ฅ์ผ๋ก ์๋ฒ ๋ด๋ถ์์ ํธ์ถ์ด ์ผ์ด๋๊ธฐ ๋๋ฌธ์ redirect์ ๋ฌ๋ฆฌ ํด๋ผ์ด์ธํธ๋ ์ธ์งํ ์ ์์ต๋๋ค.
์ ์ฅ
public class MemberSaveControllerV1 implements ControllerV1 {
private 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);
request.setAttribute("member",member);
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
}
}
/new-form.jsp ์์ ํ๋ผ๋ฏธํฐ๋ก ๋ฑ๋ก๋ ๊ฐ์ ์กฐํํด์ /save ์ POST ํ ์ํ์ ๋๋ค.
- ํ๋ผ๋ฏธํฐ ๋งคํ์ ํตํด ๊ฐ๋ค์ ์ถ์ถํฉ๋๋ค.
- ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด ๋ฆฌํฌ์งํ ๋ฆฌ์ ์ ์ฅํฉ๋๋ค.
- ์ด ๋ ์ด์ ๊ณผ ๋์ผํ๊ฒ request์ setAttribute๋ฅผ ํ์ฌ Model์ฒ๋ผ ์ฌ์ฉํ์ต๋๋ค.
- dispatcher๋ก forwardํ์ฌ JSP๋ก ์ด๋
๋ฆฌ์คํธ
public class MemberListControllerV1 implements ControllerV1 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
request.setAttribute("members",members);
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
}
}
- ๋ฆฌํฌ์งํ ๋ฆฌ๋ก ๋ถํฐ findAllํด์ members(List)์ ๋์
- request(Model) ์ members(List) ์ ์ฅ by setAttribute
- dispatcher๋ก forwardํ์ฌ members.jsp ๋ก ์ด๋
members.jsp
<c:forEach var="item" items="${members}">
<tr>
<td>${item.id}</td>
<td>${item.username}</td>
<td>${item.age}</td>
</tr>
</c:forEach>
member.jsp๋ iteratorํ์ฌ ๊ฐ ์ธ์คํด์ค ํ๋ ์ถ๋ ฅํฉ๋๋ค.
Ver2. View ๋ถ๋ฆฌ
์ ver1 ์์๋ ๋ค์๊ณผ ๊ฐ์ด ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ๋ทฐ๋ก ์ด๋ํ๋ ๋ถ๋ถ์ ์ค๋ณต์ด ์๊ณ ๊น๋ํ์ง ์์ต๋๋ค.
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
์ด ๋ถ๋ถ์ ๊น๋ํ๊ฒ ๋ถ๋ฆฌํ๊ธฐ ์ํด ๋ณ๋๋ก ๋ทฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ver1์ ์กฐ๊ธ ๋ฆฌํํฐ๋งํด์ ver2๋ฅผ ๋ง๋ค์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
ControllerV2 (interface)
public interface ControllerV2 {
MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
FrontControllerV2
@WebServlet(name="frontControllerServletV2",urlPatterns = "/front-controller/v2/*")
public class FrontControllerServletV2 extends HttpServlet {
private Map<String, ControllerV2> controllerMap = new HashMap<>();
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("FrontControllerServletV2.service");
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);
}
}
ver1์์ MyView๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
MyView๋ฅผ ๋จผ์ ์ดํด๋ณด๊ณ ๋ก์ง์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
MyView.java
public class MyView {
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);
}
}
- ์ธ์คํด์ค ํ๋๋ก viewPath๋ฅผ ๊ฐ์ง.
- render()๋ฅผ ํตํด viewPath JSP๋ก forwardํ๋๋ก ํจ.
FrontControllerV2์์๋ ์ด์ ๋ค์ ์์ ์ ์ํํฉ๋๋ค.
- ๊ฐ ์ปจํธ๋กค๋ฌ๊ฐ process ํ ๋ค์ (JSP forward ํ๊ธฐ ์ ์์ ๋ค ex) ํ๋ผ๋ฏธํฐ ๋งคํ, ๋ฆฌํฌ์งํ ๋ฆฌ ์ ์ฅ ๋ฑ๋ฑ.. ) viewPath๋ฅผ ๋ฆฌํด
- view์์ render()๋ฅผ ํตํด JSP forward
๋ฑ๋ก
public class MemberFormControllerV2 implements ControllerV2 {
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return new MyView("/WEB-INF/views/new-form.jsp");
}
}
์ด์ ๊ณผ ๋์ผํ๊ฒ ํผ๋ง ์ ์
์ ์ฅ
public class MemberSaveControllerV2 implements ControllerV2 {
private 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);
request.setAttribute("member",member);
return new MyView("/WEB-INF/views/save-result.jsp");
}
}
์ด์ ํ๋ผ๋ฏธํฐ ๋งคํ๋ง ์ํ ํ ๋ฆฌํฌ์งํฐ๋ฆฌ์ ์ ์ฅ๋ง ํ๊ณ ๋ทฐ๋ฅผ ๋ฆฌํดํฉ๋๋ค. ( JSP forward ๋ ์ํ x )
๋ชฉ๋ก
public class MemberListControllerV2 implements ControllerV2 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
request.setAttribute("members",members);
return new MyView("/WEB-INF/views/members.jsp");
}
}
๋ฉค๋ฒ ๋ฆฌ์คํธ๋ฅผ ํ๋ผ๋ฏธํฐ ๋งคํ๋งํ๊ณ ๋ทฐ๋ฅผ ๋ฆฌํด ( JSP forward๋ Front-Controller ์ render()๋ก ์ํ )
ver1 โท ver2
1. ์ด์ ์ปจํธ๋กค๋ฌ๊ฐ view๋ฅผ ๋ฐํํฉ๋๋ค.
2. ๊ธฐ์กด ver 1 : Controller๊ฐ process()๋ฅผ ํตํด JSP forward ์ํ
ver 2: FrontController์์ Controller(์ปจํธ๋กค๋ฌ๋ JSP ์ด์ ์์ ์ํ)์์ ๋ฆฌํด๋ view๋ฅผ ํตํด render()๋ฅผ ์ฌ์ฉํด์ JSP forward ์ํ
Ver3. Model ์ถ๊ฐ
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return new MyView("/WEB-INF/views/new-form.jsp");
}
@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");
}
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
request.setAttribute("members",members);
return new MyView("/WEB-INF/views/members.jsp");
}
์ฐ์ ver2์ ๊ฐ ์ปจํธ๋กค๋ฌ ์ ์ฅ์์ ๋ดค์ ๋, HttpServletRequest, HttpServletResponse๋ ์์ฒญ์ ๋ณด๋ฅผ Map์ผ๋ก ๋์ ๋๊ธฐ๋๋ก ์ค์ ํ๋ฉด ์ปจํธ๋กค๋ฌ๊ฐ ์๋ธ๋ฆฟ ๊ธฐ์ ์ ๋ชฐ๋ผ๋ ๋์ํ ์ ์์ต๋๋ค.
1. ๊ตฌํํ๋ ์ปจํธ๋กค๋ฌ๊ฐ ์๋ธ๋ฆฟ ๊ธฐ์ ์ ์ ํ ์ฌ์ฉํ์ง ์๋๋ก ๋ณ๊ฒฝํด๋ณด๊ฒ ์ต๋๋ค.
2. ๋ ๊ฐ ์ปจํธ๋กค๋ฌ์ ๋ทฐ ์ด๋ฆ์๋ ์ค๋ณต์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ ( /WEB-INF/views/~~~.jsp) ์ปจํธ๋กค๋ฌ๋ ๋ทฐ์ ๋ ผ๋ฆฌ ์ด๋ฆ์ ๋ฐํํ๊ณ ,
์ค์ ๋ฌผ๋ฆฌ์ ์์น์ ์ด๋ฆ์ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ์ฒ๋ฆฌํ๋๋ก ๋จ์ํํด๋ณด๊ฒ ์ต๋๋ค.
3. ๊ทธ๋ฆฌ๊ณ request ๊ฐ์ฒด๋ฅผ Model๋ก ์ฌ์ฉํ์ง ์๊ณ ๋ณ๋์ Model ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ๋๋ก ํ๊ฒ ์ต๋๋ค.
- ์ด๋ ๊ฒ ํ๋ฉด ๊ตฌํ ์ฝ๋๋ ๋จ์ํด์ง๊ณ , ํ ์คํธ ์ฝ๋ ์์ฑ๋ ์ฌ์์ง๋๋ค. ์ why -> request๋ฅผ ObjectMapper๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค์ด์ฃผ์ง ์์๋ ๋๋๊น.
์กฐ๊ธ ๋ณต์กํด์ก์ต๋๋ค.
ver2 โฃ ver3
- ๋ทฐ ์ด๋ฆ ์ค๋ณต ์ ๊ฑฐ
- ์๋ธ๋ฆฟ ์ข ์์ฑ ์ ๊ฑฐ
- request๊ฐ์ฒด๊ฐ ์๋ ์ค์ Model ๋์
ControllerV3 ( Interface )
public interface ControllerV3 {
ModelView process(Map<String, String> paramMap);
}
ControllerV2 (interface)
public interface ControllerV2 {
MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
๊ธฐ์กด Ver2์ ๋ฌ๋ฆฌ request, response๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ง ์์ต๋๋ค.
1. ๋์ Map์ Model์ฒ๋ผ ์ฌ์ฉํด request ํ๋ผ๋ฏธํฐ ์ ๋ณด๋ฅผ ์ ์ฅํ๋๋ก ํจ. process ๋ฉ์๋๋ฅผ ํตํด ํ๋ผ๋ฏธํฐ ๋งคํ์ด ๋๋๊ณ ๋ ๋ค ViewPath๋ฅผ ModelView์ ํ๋๋ก ์ฃผ์ ํด์ ๋ฆฌํดํ ์์ .
2. JSP๋ก forwardํ๋ ์์ ์ render ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ก ์์ ์ ์ฅํ ModelView๋ฅผ ๋๊ฒจ์ฃผ์ด ModelView์ ViewPath ํ๋๊ฐ์ ํตํด ์งํํ ์์ .
@Getter @Setter
public class ModelView {
private Map<String,Object> model = new HashMap<>();
private String viewName;
public ModelView(String viewName) {
this.viewName = viewName;
}
}
ModelView๋ ๋ณต์กํ๊ฒ ์๊ฐํ ๊ฒ ์์ด ๊ทธ๋ฅ Model+View๋ผ๊ณ ์๊ฐํ์๋ฉด ๋ฉ๋๋ค.
Model -> Map<String, Object> -> <jsp์ ๋๊ฒจ์ค ๊ฐ์ฒด ์ด๋ฆ, ๊ฐ์ฒด>
ex) (key,value) = ("member",member), ("members",members)
View -> ๋ทฐ ๋ ผ๋ฆฌ ์ด๋ฆ ์ ์ฅ
FrontControllerV3
@WebServlet(name="frontControllerServlet3",urlPatterns = "/front-controller/v3/*")
public class FrontControllerServletV3 extends HttpServlet {
private Map<String, ControllerV3> controllerMap = new HashMap<>();
public FrontControllerServletV3()
{
controllerMap.put("/front-controller/v2/members/new-form", new MemberFormControllerV3());
controllerMap.put("/front-controller/v2/members/save", new MemberSaveControllerV3());
controllerMap.put("/front-controller/v2/members", new MemberListControllerV3());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("FrontControllerServletV3.service");
String requestURI = request.getRequestURI();
ControllerV3 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
// paramMap
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");
}
private Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName-> paramMap.put(paramName, request.getParameter(paramName)));
return paramMap;
}
}
ํฐ ๊ทธ๋ฆผ์ ๋ณด์๋ฉด ์๋ ์์๋๋ก ๋ก์ง์ด ์คํ๋ฉ๋๋ค.
1. HTTP ์์ฒญ
2. URI - Controller ๋งคํ์ ๋ณด ControllerMap์ ์ ์ฅํฉ๋๋ค.
3. request URL์ ๋ณด๊ณ ๋งคํ๋ ์ปจํธ๋กค๋ฌ ์ถ์ถํฉ๋๋ค.
4. request์ ๋ํ ํ๋ผ๋ฏธํฐ ๋งต์ ๋ง๋ค์ด paramMap์ ์ ์ฅ ( iterator๋ก ์ ์ฅ / createParamMap ๋ฉ์๋ ์ฐธ์กฐ )
5. ์ปจํธ๋กค๋ฌ์์ paramMap์ ํตํ process(paramMap) ์ํ
( process() ๋ฉ์๋์์๋ ์ด์ request๊ฐ์ฒด๊ฐ ์๋๋ผ paramMap์ ์ฌ์ฉํด์ ํ๋ผ๋ฏธํฐ ๊ฐ ์ฐธ์กฐ) ํ๊ณ ModelView("๋ทฐ ๋ ผ๋ฆฌ์ด๋ฆ(viewName)") ๋ฆฌํดํฉ๋๋ค.
6. ๋ฆฌํด๋ ModelView์ ํ๋๊ฐ viewName์ viewResolver์๊ฒ ๋๊ฒจ์ค๋๋ค.
7. ViewResolver๋ ๋ฐ์ viewName์ ํตํด MyView("/WEB-INF/views" + viewName + ".jsp") ๋ฆฌํดํ์ฌ MyView ์ธ์คํด์ค ์์ฑ
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 void modelToRequestAttribute(Map<String, Object> model,
HttpServletRequest request) {
model.forEach((key, value) -> request.setAttribute(key, value));
}
8. ์์ฑ๋ MyView์์ ModelView์ model์ธ์คํด์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ model(key,value) -> request๋ก setAttribute(key,value) ํ์ฌ ํ๋ผ๋ฏธํฐ ๊ฐ์ ์ ์ฅํด์ค๋๋ค.
9. ์ด์ ๊ณผ ๋์ผํ๊ฒ RequestDispatcher ๊ฐ์ฒด์ ํ๋ผ๋ฏธํฐ๋ก 8๋ฒ์์ ํ๋ผ๋ฏธํฐ ๊ฐ์ด ์ ํ ๋ request ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด JSP๋ก forwardํฉ๋๋ค.
๋ฑ๋ก
public class MemberFormControllerV3 implements ControllerV3 {
@Override
public ModelView process(Map<String, String> paramMap) {
return new ModelView("new-form");
}
}
ModelView๋ฅผ ์์ฑํ ๋ "new-form"์ด๋ผ๋ view์ ๋ ผ๋ฆฌ์ ์ธ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
์ค์ ๋ฌผ๋ฆฌ์ ์ธ ์ด๋ฆ์ ๋ทฐ ๋ ผ๋ฆฌ์ด๋ฆ์ ํตํด์ ํ๋ก ํธ์ปจํธ๋กค๋ฌ์ viewResolver์์ ์ฒ๋ฆฌํ๋๋ก ํ์ต๋๋ค. (FrontController ์ฝ๋ ์ฐธ์กฐ)
์ ์ฅ
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;
}
}
ModelView
ํ๋ 1. model์๋ ๋ทฐ์์ ํ์ํ member ๊ฐ์ฒด๋ฅผ ๋ด์์ต๋๋ค.
ํ๋ 2. ViewName์๋ ๋ทฐ์ ๋ ผ๋ฆฌ์ฃผ์ ์ ์ฅํ์ต๋๋ค.
๋ชฉ๋ก
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;
}
}
ModelView
ํ๋ 1. model ์๋ ๋ทฐ์์ ํ์ํ ๊ฐ์ฒด์ธ members(List) ์ ์ฅํ์ต๋๋ค.
ํ๋ 2. ViewName ์๋ ๋ทฐ์ ๋ ผ๋ฆฌ์ด๋ฆ์ ์ ์ฅํ์ต๋๋ค.
์ญํ ๋ถ๋ด๊ณผ ๋ถ๋ฆฌ๊ฐ ์๊ธฐ๋ฉด์ ๋ง์ด ๋ณต์กํด์ก์ต๋๋ค.
ํนํ ModelView๋ฅผ ์์ฑํ๊ณ ๋ฆฌํดํ๋ ๋ถ๋ถ์ด ์กฐ๊ธ ๋ฒ๊ฑฐ๋กญ๊ธฐ๋ ํฉ๋๋ค. ๋ค์ ํฌ์คํ ์์๋ ver 4,5๋ฅผ ํตํด ์ด ๋ฒ๊ฑฐ๋ก์์ ๊ฐ์ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
Ver 4. Ver3 ๋ฆฌํํฐ๋ง
ControllerV3 (Interface)
public interface ControllerV3 {
ModelView process(Map<String, String> paramMap) throws IOException, ServletException;
}
ControllerV4 (interface)
public interface ControllerV4 {
public String process(Map<String, String> paramMap, Map<String, Object> model) throws IOException, ServletException;
}
๊ฐ ์ปจํธ๋กค๋ฌ๋ process์ดํ ModelView ๋ฆฌํด ( Model : JSP์ ์ ๋ฌ ๋ ๊ฐ์ฒด์ด๋ฆ-๊ฐ์ฒด ๋งคํ, View : ๋ทฐ ๋ ผ๋ฆฌ ์ด๋ฆ )
โฃ Ver4์์๋ ํ๋ผ๋ฏธํฐ๋ก model์ ์ถ๊ฐ์ ์ผ๋ก ๋ฐ์ ViewName์ String์ผ๋ก ๋ฆฌํดํ๋ค.
์ฆ, Front-Controller์์ ๋ฏธ๋ฆฌ ModelView๋ฅผ ๋ง๋ค์ด ๋๊ณ ModelView์ model ํ๋๋ฅผ get์ผ๋ก ๋ฐ์, ์ปจํธ๋กค๋ฌ ํธ์ถ ์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ฃผ๋๋ก ์ค์ ํ์์ต๋๋ค.
FrontControllerServletV4
package hello.servlet.web.frontcontroller.v4;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
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 hello.servlet.web.frontcontroller.v4.controller.MemberFormControllerV4;
import hello.servlet.web.frontcontroller.v4.controller.MemberListControllerV4;
import hello.servlet.web.frontcontroller.v4.controller.MemberSaveControllerV4;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet(name = "frontControllerServletV4" , urlPatterns = "/front-controller/v4/*")
public class FrontControllerServletV4 extends HttpServlet {
private Map<String, ControllerV4> controllerMap = new HashMap<>();
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 {
String requestURI = request.getRequestURI();
ControllerV4 controllerV4 = controllerMap.get(requestURI);
Map<String,String> paramMap = createParamMap(request);
ModelView mv = new ModelView();
String viewName = controllerV4.process(paramMap, mv.getModel());
MyView view = new MyView(viewResolver(viewName));
view.render(mv.getModel(),request,response);
}
private Map<String, String> createParamMap(HttpServletRequest request) {
Map<String, String> pm = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName-> pm.put(paramName,request.getParameter(paramName)));
return pm;
}
private String viewResolver(String viewName) {
return "/WEB-INF/views/" + viewName + ".jsp";
}
}
ํ๋ผ๋ฏธํฐ ๋งคํ์ ์ํ paramMap๊ณผ JSP๋ก forward ํ ๋ ์ฌ์ฉํ model์ ๋ฏธ๋ฆฌ service๋จ๊ณ์์ ์ค์ ํด์ฃผ์์ต๋๋ค.
๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ์์ ์์ฑํด์ ๋๊ฒจ์ฃผ๊ธฐ ๋๋ฌธ์, ์ปจํธ๋กค๋ฌ์์ ๋ชจ๋ธ ๊ฐ์ฒด์ ๊ฐ์ ๋ด์ผ๋ฉด ์ฌ๊ธฐ์ ๊ทธ๋๋ก ๋ด๊ฒจ์๊ฒ ๋ฉ๋๋ค.
๋ฑ๋ก
public class MemberFormControllerV4 implements ControllerV4 {
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) throws IOException, ServletException
{
return "new-form";
}
}
๋จ์ํ๊ฒ new-form ์ด๋ผ๋ ๋ทฐ์ ๋ ผ๋ฆฌ ์ด๋ฆ๋ง ๋ฐํํ๋ฉด ๋ฉ๋๋ค.
์ ์ฅ
package hello.servlet.web.frontcontroller.v4.controller;
import hello.servlet.basic.domain.member.Member;
import hello.servlet.basic.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import hello.servlet.web.frontcontroller.v4.ControllerV4;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Map;
public class MemberSaveControllerV4 implements ControllerV4 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) throws IOException, ServletException
{
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";
}
}
paramMap์ ์ ์ฅ๋ ๊ฐ์ ํตํด ๋ฉค๋ฒ ์ธ์คํด์ค ์์ฑ
-> ๋ฆฌํฌ์งํ ๋ฆฌ ์ ์ฅ
-> model์ put
-> ๋ทฐ ๋ ผ๋ฆฌ์ด๋ฆ (ViewName) ๋ฆฌํด
์กฐํ
public class MemberListControllerV4 implements ControllerV4 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) throws IOException, ServletException
{
List<Member> members = memberRepository.findAll();
model.put("members",members);
return "members";
}
}
model์ ๋ฆฌํฌ์งํ ๋ฆฌ์์ ๋ฉค๋ฒ๋ค ๊บผ๋ด์ put
-> ๋ทฐ ๋ ผ๋ฆฌ์ด๋ฆ ๋ฆฌํด
<์ฐธ๊ณ ์๋ฃ>
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
'๐ Backend > MVC Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring MVC ๊ตฌ์กฐ (0) | 2023.03.03 |
---|---|
Adapter ํจํด (0) | 2023.03.02 |
Spring / MVC ํจํด (0) | 2023.02.24 |
Spring / ์์ Servlet ํจํด, JSP ํจํด (0) | 2023.02.23 |
Spring MVC / HttpServletResponse (0) | 2023.02.22 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422