The Debugging Chronicles : "코드의 미학"
[Spring] DispatcherServlet(이전 FrontController) 본문
FrontController
일반적으로 view라고하는데 사용자에게 제공한다는 의미이다.
기본 내용에서 주석을 지우면
예전에는 FrontController라고 불렀는데
스프링에서는 DispatcherServlet 라고 불른다.
일반 POJO가 new하지 않는다.
서블릿에서는 컨테이너가 주관하는데 바로 톰캣이다.
톰캣이 주관하는 web.xml 에 가보면
xml 태그에 과도한 설정이을 피하기 위해서 어노테이션을 쓴다.
우리는 요청이 get인지 post인지 알지 못하기 때문에 DoAction을 만들어서 요청을 처리한다.
doAction에서 들어오면 해야할 3가지 단계가 있다.
1. 사용자(클라이언트, 브라우저)가 무슨 요청을 했는지 추출 및 확인
2. 요청 수행 = 요청에 해당하는 controller 기능을 수행
3. 응답(페이지 이동)
1.
파랑색까지만 한다면 getContextPath();이다 근데 우리가 궁금한 건 detail~이라서
uri.lastIndexOf("/")로 잘라서 command에 넣어준다
2.
이렇게 쓴다면 계속 new가 되어서 싱글톤 패턴 유지가 되지 않기 때문에
Handler mapping을 해준다.
handlerMapping은 알맞은 결과를 리턴하는데
팩토리 패턴을 활용해서 handlermapping을 하는 것이다.
자바에서는 어떻게 갈지와 어디로 갈지를 담아서 ActionForward 객체로 반환한다.
하지만 스프링에서는 무겁기 때문에 viewResolver를 쓴다.
viewResolver는 어떻게 갈지 알아서 판단해준다.
어디로 갈지, 즉 스트링 값만 반환이 된다.
3.
페이지 이동은 viewResolver를 활용해 수행을 할 예정
조금 복잡하기 때문에 추후에 배울 예정
dispatcherServler의 멤버 변수를 조금더 살펴보자.
handlerMapping과 viewResolver는 의존성을 갖는다
둘은 DI방식이 독특한데 initializer함수를 사용한다.
생성자 함수를 통해 멤버 변수를 셋팅, 의존 주입한다.
자 이제 handlerMapping과 viewResolver파일을 만들러 가보자
세가지 파일을 만든다.
viewResolver는 POJO이다
Controller를 인터페이스로 만들었다 (메서드 오버라이딩 강제 == 메서드 시그니쳐 강제)
기존 에서 Action으로 썼는데 스프링에서는 Controller로 쓴다.
만약에 로그인 기능을 만든다고 하자
overriding 강제가 된다.
1. 사용자 (클라이언트 ,브라우저) 가 보낸 파라미터에서 값을 추출한다.
2. DB 연동을 시킨다.
3.페이지이동 == 네비게이션을 한다.
스프링에서는 .jsp를 알아서 붙여준다
하지만 다른 액션을 한다면 .do을 붙여준다.
의존성 주입이 필요
HandlerMapping.java
Controller.java
package com.koreait.app.view.controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public interface Controller {
String execute(HttpServletRequest request, HttpServletResponse response);
}
// 메서드 오버라이딩 강제
// == 메서드 시그니쳐 강제
DispatcherServlet.java
package com.koreait.app.view.controller;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private HandlerMapping handlerMapping;
private ViewResolver viewResolver;
public DispatcherServlet() {
super();
}
public void init() {
this.handlerMapping = new HandlerMapping();
this.viewResolver = new ViewResolver();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 사용자(클라이언트,브라우저)의 요청 추출
String uri=request.getRequestURI();
String command=uri.substring(uri.lastIndexOf("/"));
// 2. 요청에 해당하는 Controller 기능을 수행
Controller controller=this.handlerMapping.getController(command);
// 팩토리 패턴을 활용하는 handlerMapping
String path=controller.execute(request, response);
// 3. 응답(페이지 이동)
}
}
LoginController.java
package com.koreait.app.view.member;
import org.springframework.beans.factory.annotation.Autowired;
import com.koreait.app.biz.member.MemberDAO;
import com.koreait.app.biz.member.MemberDTO;
import com.koreait.app.view.controller.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
public class LoginController implements Controller {
@Autowired
private MemberDAO memberDAO;
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) {
// 1. 사용자(클라이언트,브라우저)가 보낸 파라미터에서 값 추출
String mid=request.getParameter("mid");
String password=request.getParameter("password");
// 2. DB 연동
MemberDTO memberDTO=new MemberDTO();
memberDTO.setMid(mid);
memberDTO.setPassword(password);
memberDTO = memberDAO.selectOne(memberDTO);
// 3. 페이지 이동 == 네비게이션
String path="login";
if(memberDTO != null) {
HttpSession session=request.getSession();
session.setAttribute("userName", memberDTO.getName());
path="main.do";
}
return path;
}
}
HandlerMapping.java
package com.koreait.app.view.controller;
import java.util.HashMap;
import java.util.Map;
import com.koreait.app.view.member.LoginController;
import com.koreait.app.view.member.MainController;
public class HandlerMapping {
private Map<String, Controller> mappings;
public HandlerMapping() {
this.mappings=new HashMap<String, Controller>();
this.mappings.put("/login.do", new LoginController());
this.mappings.put("/main.do", new MainController());
}
public Controller getController(String command) {
return mappings.get(command);
}
}
'Spring' 카테고리의 다른 글
[Spring] doAction - 응답(페이지 이동) (0) | 2024.10.07 |
---|---|
[Spring] ViewResolver (0) | 2024.10.07 |
[Spring] 1주차 과제 - MemberDAO (0) | 2024.10.07 |
[Spring] 기본 구조 (0) | 2024.10.04 |
[Spring] 어노테이션(annotation) 의존성 주입 (0) | 2024.10.04 |