Spring MVC-1 TIL (5)

YulHee Kimยท2021๋…„ 9์›” 9์ผ
0

Spring MVC

๋ชฉ๋ก ๋ณด๊ธฐ
5/11
post-thumbnail

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

๐Ÿ’ก MVC ํ”„๋ ˆ์ž„์›Œํฌ ๋งŒ๋“ค๊ธฐ

โœ๏ธ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด ์†Œ๊ฐœ

ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜๋ฉด ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋œ๋‹ค.

FrontController ํŒจํ„ด ํŠน์ง•

  • ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ์„œ๋ธ”๋ฆฟ ํ•˜๋‚˜๋กœ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์Œ
  • ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์š”์ฒญ์— ๋งž๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ์•„์„œ ํ˜ธ์ถœ
  • ์ž…๊ตฌ๋ฅผ ํ•˜๋‚˜๋กœ ๐Ÿ˜Š
  • ๊ณตํ†ต ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์„œ๋ธ”๋ฆฟ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋จ

์Šคํ”„๋ง ์›น MVC์˜ DispatcherServlet์ด FrontControllerํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์Œ.

โœ๏ธ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ๋„์ž… - v1

ControllerV1

package hello.servlet.web.frontcontroller.v1;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
 
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public interface ControllerV1 {
      void process(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException;
}

์„œ๋ธ”๋ฆฟ๊ณผ ๋น„์Šทํ•œ ๋ชจ์–‘์˜ ์ปจํŠธ๋กค๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋„์ž…ํ•œ๋‹ค. ๊ฐ ์ปจํŠธ๋กค๋Ÿฌ๋“ค์€ ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.
ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ตฌํ˜„๊ณผ ๊ด€๊ณ„์—†์ด ๋กœ์ง์˜ ์ผ๊ด€์„ฑ์„ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

ํšŒ์› ๋“ฑ๋ก ์ปจํŠธ๋กค๋Ÿฌ, ํšŒ์› ์ €์žฅ ์ปจํŠธ๋กค๋Ÿฌ, ํšŒ์› ๋ชฉ๋ก ์ปจํŠธ๋กค๋Ÿฌ ๋ชจ๋‘ ๊ธฐ์กด ์„œ๋ธ”๋ฆฟ๊ณผ ๊ฑฐ์˜ ๊ฐ™์œผ๋ฉฐ process๋ฅผ override ํ•˜๋Š” ์ฐจ์ด๋ฐ–์— ์—†๋‹ค

์ด์ œ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ๋‹ค. ๐Ÿ˜Ž

FrontControllerServletV1

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

    }
}

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

urlPatterns

  • urlPatterns = "/front-controller/v1/*" : /front-controller/v1๋ฅผ ํฌํ•จํ•œ ํ•˜์œ„ ๋ชจ๋“  ์š”์ฒญ์€ ์ด ์„œ๋ธ”๋ฆฟ์—์„œ ๋ฐ›์•„๋“ค์ธ๋‹ค.

controllerMap

  • key : ๋งคํ•‘ URL
  • value : ํ˜ธ์ถœ๋  ์ปจํŠธ๋กค๋Ÿฌ

service()

๋จผ์ € requestURI๋ฅผ ์กฐํšŒํ•ด์„œ ์‹ค์ œ ํ˜ธ์ถœํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ controllerMap์—์„œ ์ฐพ๋Š”๋‹ค. ๋งŒ์•ฝ ์—†์œผ๋ฉด 404 ์ฝ”๋“œ ๋ฐ˜ํ™˜.
์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ๊ณ  controller.process(request, response);์„ ํ˜ธ์ถœํ•ด์„œ ํ•ด๋‹น ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

โœ๏ธ View ๋ถ„๋ฆฌ - v2

๋ชจ๋“  ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ทฐ๋กœ ์ด๋™ํ•˜๋Š” ๋ถ€๋ถ„์— ์ค‘๋ณต์ด ์žˆ๊ณ , ๊น”๋”ํ•˜์ง€ ์•Š๋‹ค.

String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

MyView

๋ทฐ ๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ๋ฒ„์ „์—์„œ๋„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ. frontcontroller ๋ฐ”๋กœ ๋ฐ‘์— ๋‘์—ˆ๋‹ค.

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

ControllerV2

public interface ControllerV2 {

      MyView process(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException;
  }
 

ํšŒ์› ๋“ฑ๋ก ํผ

public class MemberFormControllerV2 implements ControllerV2 {

    @Override
    public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

        MyView myView = new MyView("/WEB-INF/views/new-form.jsp");
        return myView;
    }
}

๊ฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋ณต์žกํ•œ dispatcher.forward()๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ด์„œ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋‹จ์ˆœํžˆ MyView ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฑฐ๊ธฐ์— ๋ทฐ ์ด๋ฆ„๋งŒ ๋„ฃ๊ณ  ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.
ํ™•์‹คํžˆ ์ค‘๋ณต ์ œ๊ฑฐ๊ฐ€ ๋˜์—ˆ๋‹ค! ๐Ÿ˜Ž

ํšŒ์› ์ €์žฅ

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

        //Model์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€
        request.setAttribute("member", member);

        return new MyView("/WEB-INF/views/save-result.jsp");
    }
}

ํšŒ์› ๋ชฉ๋ก

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

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

@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 {

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

    }
}

ControllerV2์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์ด MyView์ด๋ฏ€๋กœ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์ปจํŠธ๋กค๋Ÿฌ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋กœ MyView๋ฅผ ๋ฐ˜ํ™˜ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  view.render()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด forward ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•ด์„œ JSP๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

MyView.render()

 public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }

ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋„์ž…์œผ๋กœ MyView ๊ฐ์ฒด์˜ render()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์„ ๋ชจ๋‘ ์ผ๊ด€๋˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ๊ฐ์˜ ์ปจํŠธ๋กค๋Ÿฌ๋Š” MyView ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ๋งŒ ํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.

๋‹ค์Œ์€ Model์ถ”๊ฐ€๋ฅผ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค ~~~!

profile
๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž

0๊ฐœ์˜ ๋Œ“๊ธ€