๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT/Spring

[์ธํ”„๋Ÿฐ - ์Šคํ”„๋ง MVC 1ํŽธ] ์œ ์—ฐํ•œ ์ปจํŠธ๋กค๋Ÿฌ - v5

by YeonBu 2024. 8. 7.
728x90

 

 

/* ์ด ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ์ •๋ฆฌํ•˜๋ ค๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

   ๊ฐœ์ธ์ ์ธ ๊ณต๋ถ€๋ฅผ ์œ„ํ•ด ์˜ฌ๋ฆฌ๋Š” ๊ธ€์ด๋ฏ€๋กœ ์ค‘๊ฐ„ ์ค‘๊ฐ„ ์ฝ”๋“œ๋Š” ์ƒ๋žต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. */

 

 

 

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

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

www.inflearn.com

 

 

 

 

1. V5 ๊ตฌ์กฐ

 

- ๋งŒ์•ฝ ์–ด๋–ค ๊ฐœ๋ฐœ์ž๋Š” V3 ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ์‹ถ๊ณ , ์–ด๋–ค ๊ฐœ๋ฐœ์ž๋Š” V4 ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ๋ ๊นŒ?

 ์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐœ๋ฐœํ•œ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ํ•œ๊ฐ€์ง€ ๋ฐฉ์‹์˜ ์ปจํŠธ๋กค๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

private Map<String, ControllerV4> controllerMap = new HashMap<>();

 

 (์ด๋Ÿฐ์‹์œผ๋กœ Map์— Controller๋ฅผ ์ •ํ•ด์„œ ๋„ฃ์–ด๋†จ๊ธฐ ๋•Œ๋ฌธ)

 ControllerV3๊ณผ V4๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ๋”ฐ๋ผ์„œ ํ˜ธํ™˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

 ๋งˆ์น˜ V3์€ 110V์ด๊ณ , V4๋Š” 220V ์ „๊ธฐ ์ฝ˜์„ผํŠธ ๊ฐ™์€ ๊ฒƒ์ด๋‹ค.

 ์ด๋Ÿด๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์–ด๋Œ‘ํ„ฐ์ด๋‹ค.

 ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด์„œ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝํ•ด๋ณด์ž.

 

 

- ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ : ์ค‘๊ฐ„์— ์–ด๋Œ‘ํ„ฐ ์—ญํ• ์„ ํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์–ด๋Œ‘ํ„ฐ ์—ญํ• ์„ ํ•ด์ฃผ๋Š” ๋•๋ถ„์— ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

- ํ•ธ๋“ค๋Ÿฌ : ์ปจํŠธ๋กค๋Ÿฌ์˜ ์ด๋ฆ„์„ ๋” ๋„“์€ ๋ฒ”์œ„์ธ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ์ด์ œ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ ์ปจํŠธ๋กค๋Ÿฌ์˜ ๊ฐœ๋… ๋ฟ ์•„๋‹ˆ๋ผ ์–ด๋– ํ•œ ๊ฒƒ์ด๋“  ํ•ด๋‹นํ•˜๋Š” ์ข…๋ฅ˜์˜ ์–ด๋Œ‘ํ„ฐ๋งŒ ์žˆ์œผ๋ฉด ๋‹ค ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

2. ๊ตฌํ˜„

 

MyHandlerAdapter

public interface MyHandlerAdapter {

    boolean supports(Object handler);

    ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException;

}

 

[ boolean supports(Object handler) ]

- handler๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งํ•œ๋‹ค.

- ์–ด๋Œ‘ํ„ฐ๊ฐ€ ํ•ด๋‹น ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

 

[ ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) ]

- ์–ด๋Œ‘ํ„ฐ๋Š” ์‹ค์ œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋กœ ModelView๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

- ์‹ค์ œ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ModleView๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ๋ชปํ•˜๋ฉด, ์–ด๋Œ‘ํ„ฐ๊ฐ€ ModelView๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ด์„œ๋ผ๋„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

- ์ด์ „์—๋Š” ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์‹ค์ œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ–ˆ์ง€๋งŒ, ์ด์ œ๋Š” ์ด ์–ด๋Œ‘ํ„ฐ๋ฅผ ํ†ตํ•ด ์‹ค์ œ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

 

 

 

ControllerV3HandlerAdapter, ControllerV4HandlerAdapter

public class ControllerV3HandlerAdapter implements MyHandlerAdapter {
    
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof ControllerV3);
    }

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

    private static 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;

    }
    
}

 

public class ControllerV4HandlerAdapter implements MyHandlerAdapter {
    
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof ControllerV4);
    }

    @Override
    public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        ControllerV4 controller = (ControllerV4) handler;

        Map<String, String> paramMap = createParamMap(request);
        HashMap<String, Object> model = new HashMap<>();
        String viewName = controller.process(paramMap, model);

        ModelView mv = new ModelView(viewName);
        mv.setModel(model);

        return mv;
    }

    private static 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;

    }
    
}

 

- supports( )๋ฅผ ํ†ตํ•ด ControllerV3, ConrollerV4๋งŒ ์ง€์›ํ•˜๊ธฐ๋•Œ๋ฌธ์—

ControllerV3 controller = (ControllerV3) handler;
ControllerV4 controller = (ControllerV4) handler;

 

 ์ด๋ถ€๋ถ„์˜ ํƒ€์ž… ๋ณ€ํ™˜์€ ๊ฑฑ์ •์—†์ด ์‹คํ–‰ํ•ด๋„ ๋œ๋‹ค.

- ControllerV3์€ ModelView๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™”ํ•˜๋ฉด ๋˜๊ณ , V4๋Š” ์›๋ž˜ ๋ทฐ์˜ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋‚˜ ์–ด๋Œ‘ํ„ฐ๋Š” ์ด๊ฒƒ์„ ModelView๋กœ ๋งŒ๋“ค์–ด์„œ ํ˜•์‹์„ ๋งž์ถ”์–ด ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งˆ์น˜ 110v ์ „๊ธฐ ์ฝ˜์„ผํŠธ๋ฅผ 220v ์ „๊ธฐ ์ฝ˜์„ผํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋“ฏ์ด

 

 

FrontControllerServletV5

@WebServlet(name="frontControllerServletV5", urlPatterns = "/front-controller/v5/*")
public class FrontControllerServletV5 extends HttpServlet {

    private final Map<String, Object> handlerMappingMap = new HashMap<>();
    private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();

    public FrontControllerServletV5() {
        initHandlerMappingMap(); //ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ ์ดˆ๊ธฐํ™”
        initHandlerAdapters(); //์–ด๋Œ‘ํ„ฐ ๋งคํ•‘ ์ดˆ๊ธฐํ™”
    }
    
    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());
    }

    private void initHandlerAdapters() {
        handlerAdapters.add(new ControllerV3HandlerAdapter());
        handlerAdapters.add(new ControllerV4HandlerAdapter());
    }

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

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

    }

    private MyHandlerAdapter getHandlerAdapter(Object handler) {
        for (MyHandlerAdapter adapter : handlerAdapters) {
            if(adapter.supports(handler)){
                return adapter;
            }

        }
        throw new IllegalArgumentException("handler adapter not found. handler = " + handler);
    }

    private Object getHandler(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        return handlerMappingMap.get(requestURI);
    }

    private static MyView viewResolver(String viewName) {

        return new MyView("/WEB-INF/views/" + viewName + ".jsp");

    }
}

 

- FrontControllerServletV5() ์ƒ์„ฑ์ž๋Š” ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘๊ณผ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ดˆ๊ธฐํ™”(๋“ฑ๋ก)ํ•œ๋‹ค.

- ๋งคํ•‘ ์ •๋ณด

// ์ด์ „ ๋ฒ„์ „
private Map<String, ControllerV4> controllerMap = new HashMap<>();
// V5๋ฒ„์ „
private final Map<String, Object> handlerMappingMap = new HashMap<>();

 

 ๋งคํ•‘์ •๋ณด์˜ ๊ฐ’์ด ControllerV3, ControllerV4๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์•„๋ฌด๊ฐ’์ด๋‚˜ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” Object๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค.

- getHandler( )๋ฅผ ํ†ตํ•ด ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ ์ •๋ณด์ธ handlerMappingMap์—์„œ URL์— ๋งคํ•‘๋œ ํ•ธ๋“ค๋Ÿฌ(์ปจํŠธ๋กค๋Ÿฌ) ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

- getHandlerAdapter( )๋ฅผ ํ†ตํ•ด handler๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ฐพ๊ณ , handler๊ฐ€ V3, V4 ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค๋ฉด ControllerV3HandlerAdapter , V4๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.
- ์–ด๋Œ‘ํ„ฐ์˜ handle(request, response, handler) ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์‹ค์ œ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. 

 

 

 

3. ์ •๋ฆฌ

 

์ง€๊ธˆ๊นŒ์ง€ V1 ~ V5๋กœ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋ฐœ์ „์‹œ์ผœ์™”๋‹ค.

- V1 : ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ๋„์ž…

(๊ธฐ์กด ๊ตฌ์กฐ๋ฅผ ์ตœ๋Œ€ํ•œ ์œ ์ง€ํ•˜๋ฉด์„œ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋„์ž…)

- V2 : View ๋ถ„๋ฅ˜

 (๋‹จ์ˆœ ๋ฐ˜๋ณต๋˜๋Š” ๋ทฐ ๋กœ์ง ๋ถ„๋ฆฌ)

- V3 : Model ์ถ”๊ฐ€

 (์„œ๋ธ”๋ฆฟ ์ข…์†์„ฑ ์ œ๊ฑฐ, ๋ทฐ ์ด๋ฆ„ ์ค‘๋ณต ์ œ๊ฑฐ)

-V4 : ๋‹จ์ˆœํ•˜๊ณ  ์‹ค์šฉ์ ์ธ ์ปจํŠธ๋กค๋Ÿฌ

 (V3๊ณผ ๊ฑฐ์˜ ๋น„์Šทํ•˜์ง€๋งŒ ๊ตฌํ˜„ ์ž…์žฅ์—์„œ ModelView๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋„๋ก ํŽธ๋ฆฌํ•œ ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณต)

- V5 : ์œ ์—ฐํ•œ ์ปจํŠธ๋กค๋Ÿฌ

 (์–ด๋Œ‘ํ„ฐ๋ฅผ ๋„์ž…ํ•˜์—ฌ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์œ ์—ฐํ•˜๊ณ  ํ™•์žฅ์„ฑ ์žˆ๊ฒŒ ์„ค๊ณ„)

 

์—ฌ๊ธฐ์„œ ๋” ๋ฐœ์ „์‹œํ‚ค๋ฉด ์ข‹๊ฒ ์ง€๋งŒ ์Šคํ”„๋ง MVC์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ๋ชจ๋‘ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์Šคํ”„๋ง MVC ํ”„๋ ˆ์ž„์›Œํฌ์˜ ํ•ต์‹ฌ ์ฝ”๋“œ์˜ ์ถ•์•ฝ๋ฒ„์ „์ด๊ณ  ๊ตฌ์กฐ๋„ ๊ฑฐ์˜ ๊ฐ™๋‹ค.

๋‹ค์Œ ์‹œ๊ฐ„์—๋Š” ์Šคํ”„๋ง MVC์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด ๋ณด์ž!

 

 

 

๋ฐ˜์‘ํ˜•