MVC 프레임워크 4

Jan 27, 2023

5 mins read

1. 프론트 컨트롤러 Version 4 - 단순, 실용적으로

  • v3(모델 추가 버전)을 조금만 수정하여 좀더 편하게 개발할 수 있게 해본다.
  • ModelView를 사용하지 않고 뷰 논리 이름과 모델 Map 객체만 사용하여 Model개념은 사용하되 더 단순하게 만든다.
  • (인프런 수업 듣는중)

  • hello.servlet.web.frontcontroller.v4에 패키지에 컨트롤러 ControllerV4 인터페이스를 만든다.
  • 컨트롤러에서는 파라메터 Map과 모델 Map만 사용한다.
  • return 되는 String이 뷰 이름이 된다.
package hello.servlet.web.frontcontroller.v4;

import java.util.Map;

public interface ControllerV4 {
	
	/**
	 * @param paramMap
	 * @param model
	 * @return viewName
	 */
	String process(Map<String, String> paramMap, Map<String, Object> model);

}
  • hello.servlet.web.frontcontroller.v4.controller 패키지에 회원 등록 컨트롤러 MemberFormControllerV4 생성한다.
  • 단순하게 뷰 논리 이름만 리턴해주면 된다.
package hello.servlet.web.frontcontroller.v4.controller;

import java.util.Map;
import hello.servlet.web.frontcontroller.v4.ControllerV4;

public class MemberFormControllerV4 implements ControllerV4{
	
	@Override
	public String process(Map<String, String> paramMap, Map<String, Object> model) {
		return "new-form"; //모델뷰를 사용하지 않는다.
	}

}
  • hello.servlet.web.frontcontroller.v4.controller 패키지에 회원 저장 컨트롤러 MemberSaveControllerV4를 생성한다.
  • 파라메터로 전달 받은 member 를 model에 저장해주면 된다.
package hello.servlet.web.frontcontroller.v4.controller;

import java.util.Map;

import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.v4.ControllerV4;

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

}
  • hello.servlet.web.frontcontroller.v4.controller 패키지에 회원 목록 컨트롤러 MemberListControllerV4를 생성한다.
package hello.servlet.web.frontcontroller.v4.controller;

import java.util.List;
import java.util.Map;

import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.v4.ControllerV4;

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";
	}
}
  • hello.servlet.web.frontcontroller.v4 패키지에 프론트 컨트롤러 FrontControllerServletV4를 생성한다.
  • Map<String, Object> model = new HashMap<>(); 이 부분이 추가되었다.
package hello.servlet.web.frontcontroller.v4;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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 jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

//front-controller/v4/으로 들어오는 모든 요청을 컨트롤 한다.
@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;
		}	

		//pramMap
		Map<String, String> paramMap = createParamMap(request);
		Map<String, Object> model = new HashMap<>(); //v4에서 추가
		String viewName = controller.process(paramMap, model);
		
		MyView view =  viewResolver(viewName);
		view.render(model, request, response);
		
	}
	
	public 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 MyView viewResolver(String viewName) {
		return new MyView("/WEB-INF/views/" +viewName+ ".jsp");
	}
	
}
  • v3 구조에서 모델을 파라미터로 넘기고, 뷰의 논리 이름을 반환하게 수정하여 더욱 단순해졌다.

  • http://localhost:8080/front-controller/v4/members/new-form
    http://localhost:8080/front-controller/v4/members
    접속해보면 잘 동작을 하는걸 확인할 수 있다.