코딩항해기
[Spring] springframework.DispatcherServlet 구조 본문
org.springframework.web.servlet.DispatcherServlet
DispatcherServlet은 이름에도 쓰여있듯이 Servlet 파일이다. Spring에서는 페이지 이동 구분을 ViewResolver가 해주기 때문에 ViewResolver에 대한 의존성을 가지고 있으며, 객체관리를 위해 HandlerMapping을 사용하기 때문에 HandlerMapping에 대한 의존성도 가지고 있다.
그 외의 형태는 JSP기반 FrontController와 유사한 형태를 가지고 있다.
1. 사용자의 요청을 추출
2. 요청에 해당하는 기능을 수행 (HandlerMapping사용)
3. 응답 (ViewResolver사용)
Servlet으로 구조를 보면 이러한 형태를 가지고 있다고 볼 수 있다.
@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();
//세터주입
this.viewResolver.setPrefic("./");
this.viewResolver.setSuffix(".jsp");
}
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 기능을 수행
// 팩토리 패턴을 활용하는 handlerMapping
String path=this.handlerMapping.getController(command).execute(request, response);
// 3. 응답(페이지 이동)
//viewResolver를 사용하여 응답
if(!path.contains(".do")){
this.viewResolver.getView(path); //뷰로 갈 수 있게 요청완성
}
response.sendRedirect(path);
}
}
DispatcherServlet은 오래된 코드이므로 생성자가 아닌 init을 통해 초기화하고 있다.
DispatcherServlet은 springframework에서 제공하고 있는데, web.xml(톰캣)에서 태그로 생성해줄 수 있다.
일반 @WebServlet이 대체한 태그와 동일한데, 클래스를 불러오는 곳이 springframework이다.
<servlet>
<servlet-name>ds</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--스프링에서 제공하는 Servlet 사용-->
</servlet>
<servlet-mapping>
<servlet-name>ds</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
ds라는 이름으로 DispacherServlet을 불러오고 있으며, 이 ds는 .do로 끝나는 모든 요청을 처리한다.
ds는 ds(설정한 서블릿명)-servlet.xml라는 설정 파일을 필요로 하므로 web-inf 하위에 생성해야한다.
ds-servlet.xml에는 DispacherServlet이 의존성을 가지고 있는 HandlerMapping과 ViewResolve가 등록되어 있어야한다.
(1007 아직 ViewResolve 진도가 덜 나가 여기까지 정리했다.)
(1008 VeiwResolver 진도 후 추가)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--HandlerMapping과 ViewResolver에 대한 의존성을 가지고 있으므로 추가-->
<!--ds의 HandlerMapping은 한 개라 id 생략가능-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!--SI 주입-->
<property name="mappings">
<props>
<!--<prop key="키 값 ">밸류 값</prop>-->
<prop key="/login.do">login</prop>
<prop key="/boardWrite.do">boardWrite</prop>
</props>
</property>
</bean>
<!--Bean 등록-->
<bean class="com.koreait.app.view.member.LoginController" id="login"/>
<bean class="com.koreait.app.view.board.BoardWriteController" id="boardWrite"/>
<!--어노테이션 스캔-->
<!--컨트롤러 Autowired 스캔 이후 Repository도 필요하므로 같이 스캔-->
<context:component-scan base-package="com.koreait.app.view"/>
<context:component-scan base-package="com.koreait.app.biz"/>
<!--ViewResolver는 여러 개 될 수 있으므로 id를 반드시 기입-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
<!--SI 주입-->
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
HandlerMapping을 등록하기 위해서는 생성할 객체에 대한 Bean이 필요하고 해당 Controller 객체와 Controller 객체가 의존하는 객체가 어노테이션으로 설정되어 있기 때문에 해당 어노테이션을 인지할 수 있도록 context:compent-scan 태그를 사용해 스캔 범위를 지정한다.
ViewResolver에서는 SI주입(setter 주입)을 통해 String 값에 대한 의존성을 주입할 수 있으며, 웹 페이지 구동 시 데이터가 필요한 페이지는 사용자가 함부러 접근할 수 없는 WEB-INF 하위에 있으므로 필요한 경로를 작성한다.
다시 말해 ViewResolver는 WEB-INF 하위에 있는 페이지에 접근할 때만 사용된다. 사용하지 않을 때는 path앞에 redirect:를 붙여 해당 요청이 리다이렉트이고 ViewResolver를 사용하지 않을 것임을 설정할 수 있다.
'Spring' 카테고리의 다른 글
[Spring] springframework.ViewResolver 구조 (0) | 2024.10.08 |
---|---|
[Spring] 인텔리제이 intellij 로컬 서버 등록 (0) | 2024.10.08 |
[Spring] springframework.Controller interface 구조 (0) | 2024.10.07 |
[Spring] springframework.HandlerMapping 구조 (0) | 2024.10.07 |
[리뷰/우아한테크] Spring vs Spring Boot (0) | 2024.10.06 |