일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 프로그래머스
- Queue
- java
- dns
- CPU bound
- TCP/IP
- frontPattern
- port
- 십진수 이진수 전환
- green thread
- Split
- CPU
- springMVC
- 문자열
- reflection
- 2차원 배열 출력
- DICTIONARY
- 크기가 작은 부분 문자열
- http
- 동시성문제
- process
- IO bound
- URL
- stack
- 코딩테스트
- 문자열 내마음대로 정렬하기
- deque
- Spring
- annotation
- 가장 가까운 단어
- Today
- Total
아무나개발하자
프론트 컨트롤러 패턴 소개2 본문
View 분리 - v2
앞서서 소개한 프론트 컨트롤어 패턴 소개1은 모든 컨트롤러에서 뷰로 이동하는 부분에 중복이 발생한다. 또한 코드도 복잡하고 깔끔하지 않아서 밑에 코드를 수정해 보려고 한다.
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
밑에 소스코드에서 ControllerV2의 인터페이스를 상속받은 controller클래스는 위에 코드를 모두 반복하고 있다. 위에 코드는 viewPath를 String으로 지정하고 viewPath에 따른 RequestDispatcher를 호출하여 Jsp로 forward하는 코드이다.
이 부분을 깔끔하게 분리하기 위해 별도로 뷰를 처리하는 객체(MyView)를 만들자.
MyView
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;
}
//view가 렌더링되게 동작하는 함수
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
}
}
viewPath를 지정하고 viewPath에 따라 JSP를 forward하는 함수가 구현되어있다. 이 함수를 view가 랜더링되게 한다고 해서 render함수라고 칭했다.
ControllerV2
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;
}
모든 컨트롤러들이 구현해야 하는 인터페이스이다. 비즈니스 로직이 실행되는 process함수를 만들었다. process함수는 MyView객체를 반환하게 구현되어있다. 나중에 MyView객체는 frontControllerServlet 클래스에서 잘 사용하여 JSP를 랜더링 할 것이다.
frontControllerServletV2
package hello.servlet.web.frontcontroller.v2;
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 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;
//frontController가 하는 역할이 uri 정보에 따라 controller를 매핑시켜주는 역할을 한다.
@WebServlet(name = "frontControllerServletV2", urlPatterns = "/front-controller/v2/*")
public class FrontControllerServletV2 extends HttpServlet {
//key : url, value : Controller
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 {
System.out.println("FrontControllerServletV2.service");
//클라이언트로 부터 입력된 uri 정보를 받아온다.
String requestURI = request.getRequestURI();
//controllerMap으로 클라이언트로 부터 입력된 uri 정보를 통해 controller를 매핑.
ControllerV2 controller = controllerMap.get(requestURI);
//controller가 매핑되지 못했을 경우를 대비해서 만들어줌
if(controller == null){
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
//이전과 다르게 process함수를 수행하고 나면 jsp uri 주소를 반환한다.
MyView view = controller.process(request, response);
view.render(request,response);
}
}
frontControllerServletV2에서는 uri에 따른 controller를 매핑시켜주고, 해당 controller를 process함수를 통해 비즈니스 로직을 수행한다, prcess함수를 통해 반환된 MyView객체를 통해 JSP로 render한다.
MemberFormControllerV2
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return new MyView("/WEB-INF/views/new-form.jsp");
}
ControllerV2 인터베이스를 구현한것이다.
MemberListControllerV2
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ArrayList<Member> members = memberRepository.findAll();
request.setAttribute("members", members);
return new MyView("/WEB-INF/views/members.jsp");
}
ControllerV2 인터베이스를 구현한것이다.
MemberSaveControllerV2
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");
}
ControllerV2 인터베이스를 구현한것이다.
컨트롤러 클래스를 보게되면 확실히 비즈니스 로직만 수행한다고 느껴진다. 경로는 지정해서 MyView객체로 보내 frontControllerServletV2에서 JSP로 render해주게 된다.
코드 : refactor : View분리-v2
https://github.com/dlqjagml/spring/commits/master
출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1
'Spring' 카테고리의 다른 글
HTTP 메시지 컨버터2 (0) | 2022.07.16 |
---|---|
HTTP 메시지 컨버터 (0) | 2022.07.14 |
프론트 컨트롤러 패턴 소개4 (0) | 2022.07.10 |
프론트 컨트롤러 패턴 소개3 (0) | 2022.07.09 |
프론트 컨트롤러 패턴 소개1 (0) | 2022.07.07 |