MVC 프레임워크 2

Jan 17, 2023

4 mins read

1. 프론트 컨트롤러 Version 2 - View 분리

  • 뷰로 이동하는 부분이 중복되기 때문에 따로 분리하여 객체를 만든다.
  • 뷰 객체는 이후 다른 버전에서도 계속 사용할거기 때문에 frontcontroller 패키지에 MyView로 만든다.
  • (인프런 수업 듣는중)
package hello.servlet.web.frontcontroller;

import java.io.IOException;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

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);
	}
}
  • hello.servlet.web.frontcontroller.v2 패키지에 컨트롤러 MemControllerV2 인터페이스를 만든다.
  • 이 컨트롤러는 MyView를 반환한다.
package hello.servlet.web.frontcontroller.v2;

import java.io.IOException;

import hello.servlet.web.frontcontroller.MyView;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public interface ControllerV2 {
	
	 MyView porcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
	 
}
  • hello.servlet.web.frontcontroller.v2.controller 패키지에 회원 등록 컨트롤러 MemberFormControllerV2 생성한다.
  • 이제 dispatcher.forward() 를 직접 생성해서 호출하지 않고 MyView 객체를 생성하고 거기에 뷰 이름만 넣고 반환하면 된다.
package hello.servlet.web.frontcontroller.v2.controller;

import java.io.IOException;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class MemberFormControllerV2 implements ControllerV2 {

	@Override
	public MyView porcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		return new MyView("/WEB-INF/views/new-form.jsp");
	}
	
}
  • hello.servlet.web.frontcontroller.v2.controller 패키지에 회원 저장 컨트롤러 MemberSaveControllerV2 생성한다.
package hello.servlet.web.frontcontroller.v2.controller;

import java.io.IOException;

import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class MemberSaveControllerV2 implements ControllerV2{

	private MemberRepository memberRepository = MemberRepository.getInstance();
	
	@Override
	public MyView porcess(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");
	}
}
  • hello.servlet.web.frontcontroller.v2.controller 패키지에 회원 목록 컨트롤러 MemberListControllerV2 생성한다.
package hello.servlet.web.frontcontroller.v2.controller;

import java.io.IOException;
import java.util.List;

import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class MemberListControllerV2 implements ControllerV2{
	
	private MemberRepository memberRepository = MemberRepository.getInstance();

	@Override
	public MyView porcess(HttpServletRequest request, HttpServletResponse response)	throws ServletException, IOException {
		
		List<Member> members = memberRepository.findAll();
		
		request.setAttribute("members", members);
		
		return new MyView("/WEB-INF/views/members.jsp");
	}
}
  • hello.servlet.web.frontcontroller.v2 패키지에 프론트 컨트롤러 FrontControllerServletV2를 생성한다.
  • 프론트 컨트롤러의 도입으로 MyView 객체의 render() 를 호출하는 부분을 모두 일관되게 처리할 수 있다.
package hello.servlet.web.frontcontroller.v2;

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

import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.controller.MemberFormControllerV2;
import hello.servlet.web.frontcontroller.v2.controller.MemberListControllerV2;
import hello.servlet.web.frontcontroller.v2.controller.MemberSaveControllerV2;
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/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를 가지고 render를 수행하여 JSP를 실행한다. 
		MyView view =  controller.porcess(request, response);
		view.render(request, response);
	}
	
}
  • JSP는 이전에 만들어 두었던 것을 그대로 사용한다.
  • http://localhost:8080/front-controller/v2/members
    http://localhost:8080/front-controller/v2/members/new-form
    접속해보면 잘 동작을 하는걸 확인할 수 있다.