Spring/Spring MVC

단순하고 실용적인 컨트롤러

민철킹 2021. 4. 21. 15:34

앞서 만든 컨트롤러는 서블릿 종속성을 제거하고 뷰 경로의 중복을 제거하여 컨트롤러를 설계했다.

하지만 컨트롤러 인터페이스를 구현해야하는 입장에서 보면 항상 ModelView객체를 생성하여 반환해야하는 부분은 번거롭다.

 

이를 실용성을 가지도록 변경해보자

 

새로운 구조

  • 컨트롤러가 ModelView를 반환하는 것이 아니라 ViewName만 반환한다.

 

 

 컨트롤러 Interface

 

회원 Form 컨트롤러

  • viewName만 반환해준다. 

 

회원 Save 컨트롤러

  • 모델을 parameter로 제공받기 때문에 새로운 회원객체를 만들어 model에 put해주면 된다.
  • 역시 마찬가지로 viewName만 반환

 

회원 List 컨트롤러

 

모델을 처리하는 과정은 FrontController에서, 각 구현 컨트롤러는 모델에 put만 해주고 viewName만 반환하면 된다.

 

 

FrontController

package hello.servlet.web.frontcontroller.v4;

import hello.servlet.web.frontcontroller.MyView;
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 controller = controllerMap.get(requestURI);
        if (controller == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        //paramMap을 넘겨줘야함

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

    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;
    }
}
  • FrontController에서 Map으로 된 model을 생성하여 넘겨주고, 구현체에서 모델에 값을 담아 사용한다.
  • 이를 통해 넘겨 받은 viewName을 통해 render를 하여 View를 클라이언트에게 제공한다.

 

프레임워크나 공통 기능이 많은 일을 처리해야 사용하는 사용자(각 구현체)가 편리해진다.

반응형

'Spring > Spring MVC' 카테고리의 다른 글

Spring MVC 전체 구조  (0) 2021.04.30
유연한 컨트롤러  (0) 2021.04.28
Model 추가  (0) 2021.04.18
View 분리  (0) 2021.04.14
프론트 컨트롤러 패턴  (0) 2021.04.13