# Front-Controller ํŒจํ„ด
Study Repository

Front-Controller ํŒจํ„ด

by rlaehddnd0422

ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด 

  • ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์„œ๋ธ”๋ฆฟ ํ•˜๋‚˜๋กœ ํด๋ผ์ด์–ธํŠธ๋“ค์˜ ์š”์ฒญ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ์ปจํŠธ๋กค๋Ÿฌ

  • ๊ธฐ์กด์—๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉ( ๊ณตํ†ต ์—…๋ฌด ์ฒ˜๋ฆฌ) ํ•œ๋‹ค๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ

  • ์ž…๊ตฌ๋ฅผ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๊ณตํ†ต ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์›น MVC์˜ ํ•ต์‹ฌ๋„ ๋ฐ”๋กœ FrontController์ž…๋‹ˆ๋‹ค.

 

DispatcherServlet์ด FrontController ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š”๋ฐ, ์ฒ˜์Œ๋ถ€ํ„ฐ ์ตœ์ข…์  FrontController ํŒจํ„ด์„ ์„ค๋ช…ํ•˜๊ธฐ์—” ์–ด๋ ค์›€์ด ์žˆ์–ด ๋‹จ๊ณ„์ ์œผ๋กœ ํ’€์–ด ๋‚˜๊ฐ€๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” FrontController ํŒจํ„ด์„ ๋ฒ„์ „ 1๋ถ€ํ„ฐ 3๊นŒ์ง€ ๋‹จ๊ณ„์ ์œผ๋กœ ๋„์ž…ํ•ด๋ณด๊ณ  ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋ฒ„์ „ 4, 5๋ฅผ ๋„์ž…ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


Ver 1. ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ๋„์ž…

Front Controller Version 1

  1. Client ์—์„œ HTTP ์š”์ฒญ์ด ๋“ค์–ด์˜ต๋‹ˆ๋‹ค.
  2. (Front Controller ์—์„œ) ์š”์ฒญ ๋ฉ”์‹œ์ง€๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ URI์™€ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  3. (Front Controller ์—์„œ) ๋งคํ•‘๋œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  4. (Controller ์—์„œ) JSP๋กœ  Forward๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
  5. 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 ํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

 

  1. ํŒŒ๋ผ๋ฏธํ„ฐ ๋งคํ•‘์„ ํ†ตํ•ด ๊ฐ’๋“ค์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
  2. ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  3. ์ด ๋•Œ ์ด์ „๊ณผ ๋™์ผํ•˜๊ฒŒ request์— setAttribute๋ฅผ ํ•˜์—ฌ Model์ฒ˜๋Ÿผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
  4. 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);
    }
}
  1. ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋กœ ๋ถ€ํ„ฐ findAllํ•ด์„œ members(List)์— ๋Œ€์ž…
  2. request(Model) ์— members(List) ์ €์žฅ by setAttribute
  3. 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๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Front Controller Ver 2

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);
    }

}
  1. ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋กœ viewPath๋ฅผ ๊ฐ€์ง.
  2. 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

 

์Šคํ”„๋ง MVC 1ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ•ต์‹ฌ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์ดํ•ดํ•˜๊ณ , ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”„๋ง MVC์˜ ํ•ต์‹ฌ ์›๋ฆฌ์™€ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ , ๋” ๊นŠ์ด์žˆ๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., -

www.inflearn.com

 

 

'๐Ÿ“• Java&Spring > MVC' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

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

ํ™œ๋™ํ•˜๊ธฐ