[Spring MVC 1] - MVC 프레임워크 - view 분리
view 분리 개요
모든 컨트롤러에서 뷰로 이동하는 부분이 중복이다.
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
해결방안
중복을 해결하기 위해 별도로 뷰를 처리하는 객체를 만든다.
Goal : 기존 코드를 최대한 유지하면서, 뷰를 분리해본다.
View 분리
v2 구조 아키텍쳐
MyView 객체
hello/servlet/web/frontcontroller/MyView.java
package hello.servlet.web.frontcontroller;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
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); //forward 하면 실제 렌더링 됨
}
}
Controller V2
hello/servlet/web/frontcontroller/v2/ControllerV2.java
package hello.servlet.web.frontcontroller.v2;
import hello.servlet.web.frontcontroller.MyView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public interface ControllerV2 {
MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
- 기존에는 void였고 controller가 알아서 forward로 이동했는데, MyView를 만들어서 넘기는 식으로 설계
- 컨트롤러가 view를 반환한다
MemberFormControllerV2 - 회원 등록 컨트롤러
hello/servlet/web/frontcontroller/v2/controller/MemberFormControllerV2.java
package hello.servlet.web.frontcontroller.v2.controller;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MemberFormControllerV2 implements ControllerV2 {
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return new MyView("/WEB-INF/views/new-form.jsp");
}
}
MemberSaveControllerV2 - 회원 저장 컨트롤러
hello/servlet/web/frontcontroller/v2/controller/MemberSaveControllerV2.java
package hello.servlet.web.frontcontroller.v2.controller;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v1.ControllerV1;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MemberSaveControllerV2 implements ControllerV2 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public MyView process(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);
request.setAttribute("member", member);
return new MyView("/WEB-INF/views/save-result.jsp");
}
}
MemberListControllerV2 - 회원 목록 조회 컨트롤러
hello/servlet/web/frontcontroller/v2/controller/MemberListControllerV2.java
package hello.servlet.web.frontcontroller.v2.controller;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v1.ControllerV1;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class MemberListControllerV2 implements ControllerV2 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Member> members = memberRepository.findAll();
request.setAttribute("members", members);
return new MyView("/WEB-INF/views/members.jsp");
}
}
- 각 컨트롤러는 복잡한 dispathcer.forward()를 직접 생성해서 호출하지 않아도 된다.
- MyView 객체를 생성하고 뷰 이름을 넣고 반환하면 된다
- ControllerV2의 반환 타입이 MyView 이므로 프론트 컨트롤러는 컨트롤러의 호출결과로 MyView를 반환 받고, view.render()를 호출하면 forward 로직을 수행하여 JSP가 실행된다
http://localhost:8080/front-controller/v2/members/new-form 등록 실행 결과
http://localhost:8080/front-controller/v2/members 목록 조회 실행 결과
view 분리 완료!! 다소 간략한 오늘의 한마디였지만, 핑계대고 오늘은 쉬고 싶었는데 한다! 복습까지 꼭꼭 씹어먹어야지.
@ 스프링 MVC 1편 - 백엔드 웹개발 by 김영한을 참조하고 있습니다.