본문 바로가기
Spring Tutorial

[스프링MVC 25] MVC 프레임워크 만들기: 단순하고 실용적인 컨트롤러

by 미소5 2023. 7. 31.

[스프링MVC 24] MVC 프레임워크 만들기: Model 추가 (*중요*) (tistory.com)

 

[스프링MVC 24] MVC 프레임워크 만들기: Model 추가 (*중요*)

[스프링MVC 23] MVC 프레임워크 만들기: View 분리 (tistory.com) [스프링MVC 23] MVC 프레임워크 만들기: View 분리 [스프링MVC 22] MVC 프레임워크 만들기: 프론트 컨트롤러 (FrontController) (tistory.com) [스프링MVC 22

joly156.tistory.com

항상 ModelView 객체를 직접 생성하고 반환해야 하는 부분이 조금은 번거롭다. 좋은 프레임워크는 실제 개발하는 개발자가 단순하고 편리하게 사용할 수 있어야 한다. 

 

컨트롤러가 ModelView를 반환하지 않고, ViewName만 반환

 


 

  • 편리한 인터페이스
    • 인터페이스에 ModelView가 없다. model 객체 파라미터로 전달되기 때문에 그냥 사용하면 되고, 결과로 뷰의 이름만 반환해주면 된다.
public interface ControllerV4 {
    /**
     *
     * @param paramMap
     * @param model
     * @return viewName
     */
    String process(Map<String, String> paramMap, Map<String, Object> model); //model 객체가 파라미터로 전달된다
}
  • /**+Enter 치면, 주석 자동 생성된다

 


public class MemberFormControllerV4 implements ControllerV4 {

    @Override
    public String process(Map<String, String> paramMap, Map<String, Object> model) {
        return "new-form";
    }
}
  • 정말 단순하게 new-form이라는 뷰의 논리 이름만 반환

 

public class MemberSaveControllerV4 implements ControllerV4 {
    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    public String process(Map<String, String> paramMap, Map<String, Object> model) {
        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";   //뷰의 논리이름만 반환
    }
}
  • 모델이 파라미터로 전달되기 때문에, 모델을 직접 생성하지 않아도 된다.

 

public class MemberListControllerV4 implements ControllerV4 {
    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    public String process(Map<String, String> paramMap, Map<String, Object> model) {
        List<Member> members = memberRepository.findAll();
        model.put("members", members);
        return "members";
    }
}

  • 프론트 컨트롤러
@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 req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();

        ControllerV4 controller = controllerMap.get(requestURI);
        if (controller == null) {
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        Map<String, String> paramMap = createParamMap(req);
        Map<String, Object> model =new HashMap<>();  /**모델 객체를 생성*/

        String viewName=controller.process(paramMap, model); //컨트롤러가 직접 뷰의 논리 이름을 반환

        MyView view= viewResolver(viewName);    //뷰의 실제 물리 경로

        view.render(model, req, resp);
    }


    private Map<String, String> createParamMap(HttpServletRequest req) {
        Map<String, String > paramMap=new HashMap<>();
        req.getParameterNames().asIterator()
                .forEachRemaining(paramName -> paramMap.put(paramName, req.getParameter(paramName)));
        return paramMap;
    }

    private MyView viewResolver(String viewName) {
        return new MyView("/WEB-INF/views/" + viewName + ".jsp");
    }

}
  • 모델 객체 프론트 컨트롤러에서 생성해서 넘겨준다. →컨트롤러에서 모델 객체에 값을 담으면, 여기에 값이 그대로 담겨있게 된다.

 


 

728x90
반응형