인생을 코딩하다.

[Spring] Dispatcher Servlet이란?, Servlet & Spring Web MVC 본문

Spring

[Spring] Dispatcher Servlet이란?, Servlet & Spring Web MVC

Hyung1 2021. 2. 17. 19:54
728x90
반응형

Servlet

웹 애플리케이션을 만들 때 필요한 인터페이스

Spring web MVC

spring : Spring Framework에 있는 모듈

web : Web Service를 만들때 필요

MVC : MVC 패턴을 사용해서 (Model View Controller)

 

그리고 이 Spring web MVC가 Servlet를 사용하게 된다.

Servlet은 왜 생겼을까?

정적 데이터만 전달하는 Web Server

처음에 웹 프로그래밍인 정적 데이터만 전달할 수 있었다. 어떤 사용자가 들어와도 Hello.html만 줄 수 있었다.

 

그래서 사용자(요청)에 따라 다른 처리를 해줄 수 없었다. 동적인 처리를 해주는 웹 애플리케이션이 없었다.

 

그래서 나온게 CGI다.

 

동적인 데이터를 처리하는 CGI, Web Server와 프로그램 사이의 규약

 

CGI는 동적 데이터를 처리하는 인터페이스이다. 인터페이스라는 것은 규약이다. 이 규약이 왜 필요할까?

 

 (Apache)            (C, PHP)

WebServer   <->  CGI 구현채

 

WebServer는 Apache이고 CGI를 구현할때는 C, PHP 이런 다양한 언어를 사용하니깐 서로 규악을 만들기 위해 CGI를 사용하게 되었다.

 

그래서 예전과 달리 누가 들어왔는지, 리뷰 요청, 자기 팀이 들어왔는지 등을 사용할 수 있었다.

 

하지만 CGI는 문제가 있었다.

 

출처 : 테크톡

요청이 들어올때마다 프로세스를 만든다.

 

프로세스는 메모리를 통으로 가지는 반면에 쓰레드는 메모리를 공유하고 만드는데도 시간이 상대적으로 적게 걸린다.

 

그래서 이 문제를 해결하기 위해,

이것을 프로세스에서 쓰레드로 바꿨다.

 

그리고 또 하나의 문제점은 쓰레드가 다르다면 하나씩 구현체가 생기는 것이였다. 

 

그래서 이것을 싱글톤으로 바꿨다.

 

이것이 바로 Servlet이다.

 

 

리퀘스트가 들어올때마다 쓰레드가 생기고, 싱글톤 패턴으로 바꼈다.

웹 컨테이너가 요청이 들어오면 쓰레드를 생성하고, 서블릿을 실행시킨다. 서블릿 인터페이스에 따라 서블릿을 관리한다. 서블릿 인터페이스에 메서드가 구현되어있을때, 그 메서드를 호출해준다.

 

* 프로새스 : 메모리에 적재된 프로그램, 실행중인 프로그램 인스턴스

* 쓰레드 : 한 프로세스 내의 동작 흐름

 

서블릿 인터페이스에 정의되어 있는 매서드에는

 

intit : Servlet Instance 생성 (initalize)

 

Service : 실제 기능이 수행되는 곳  

 

ex) abstract class HttpServlet extends Servlet

                HTTP Method (GET, POST, PUT, DELETE)에 따라 웹컨테이너가

                doGet(), doPost(), doPut, doDelete() 메서드를 호출한다.

                doXXX() : 개발자가 구현

 

Destory : Servlet Instance가 사라진다.

  • 보통 container가 종료되는 시점에 destory() 호출
  • 특정 servlet 로드/언로드 시에도 사용

리퀘스트가 쓰레드 하나이고, 이 쓰레드가 서블릿을 찾을때 서블릿이 없다면 init으로 서블릿을 생성하구 실제 기능을 수행한다. 그리고 마지막으로 Destory로 서블릿을 없애준다. 

각 메서드는 Servlet Container(Tomcat)이 호출해준다.

 

코드로 보면,

<web-app>
 
  <servlet>
  	<servlet-name>member</servlet-name> //servlet 이름 명시
  	<servlet-class>servlet.MemberServlet</servlet-class> //패키지.클래스 이름을 등록 해줌
  </servlet>
 
  <servlet-mapping>
  	<servlet-name>Member</servlet-name> //servlet의 name을 매핑
  	<url-pattern>/Member</url-pattern>  / 가 반드시 필요!! (주소 뒤에 값이라서)
  </servlet-mapping>
</web-app>

Web,xml (설정 파일) Servlet Mapping 

WAS에게 Servlet 객체 - URL mapping 정보를 알려준다.

 

"Member라는 서블릿 이름을 짓고, 이 URL 요청이 들어왔을때 이 서블릿으로 보내라" 이다.

 

위에서 mapping 된것을 보고

 

public MemberServlet extends HttpServlet {
	protected void doPost(HttpServletRequest req, 
    		HttpServletResponse res) throws ServletException, IOException {
    
    
      String username = request.getParameter("username");
      Strung password = reqyest.getParameter("password");
      
      String result = doSomething(username, password);
      
      String gtmlReponse = "<html>";
      htmlResponse += "<h2>Result : " + result + </h2>;
      htmlResponse += "</html>";
      
      printWriter writer = response.getWriter();
      writer.println(htmlRespinse);
    }
}
      

 

서비스, 즉 doPost로 오면

  1. Request에 Parameter을 받고, 
  2. 비즈니스 로직을 처리 후,
  3. 결과 data를 담은 View를 만든다.
  4. 그리고 Client에게 전송한다.

전체적으로 살펴보면,

 

 

URL마다 Servlet가 생기고, 그 Servlet을 웹 컨테이너에게 알려주기 위해서 Web.xml과 서블릿을 mapping 시켜주고,

/line라는 request가 오면 LineServlet로 보내야 겠다 해서 각각 HTTP 메서드에 맞는 메서드를 호출하게 된다.

 

그렇다면

Spring Web MVC에서는 Servlet를 어떻게 사용할까?

Dispatcher Servlet로 사용한다.

 

이런 구조를 가지고 있다.

 

1. 처음에 Request가 들어오면, Dispatcher Servlet으로 간다.

 

2. 아까 서블릿을 Web.xml에 등록을 해야한다고 했다. Dispatcher Servlet도 Servlet이기 때문에 web.xml에 등록을 하게 된다. 위의 사진을 보면 모든 요청이 오면 Dispatcher Servlet로 가라고 하고 등록을 시켜 놓는다.

 

3. 그러면 그에 맞는 요청에 따라 적절한 Controller를 찾는다. 핸들러는 컨트롤러보다 더 큰 개념인데,

핸들러 매핑을 통해서 요청에 맞는 컨트롤러를 찾아준다. 찾는 방법은 Spring Framework에서 제공해준다.

 

Spring Framework에서 제공하는 HandlerMapping에는

  • BeanNameHandlerMapping -> Bean 이름과 Url을 Mapping하는 방식 ex) /employee로 접근하면 위 Class(controller)로 mapping해준다. 하지만 이 방법은 Default 설정이라 별도로 HandlerMapping 방식을 지정할 필요는 없다.
<beans ...>
...
	<! --<bean class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
    Mbean name = "/employee" calss = "com.hyungil.controller.EmployeeController">
    	...
    </bean>
..
</bean>
  • ControllerClassNameHandlerMapping 
  • SimpleUrlHandlerMapping
  • DefaultAnnotationHandlerMapping -> Annotation으로 Url과 Mapping하는 방식 /Employee로 접근하면 위 메서드로 mapping 해준다.
@Controller
public class EmployeeController {
	
    @RequestMapping("/Employee")
    public String do() {
    	// do something
    }
}

가 있는데 어떤 방식의 HandlerMapping을 사용할지 설정파일에 지정한다. 자주 쓰이는 방식 2가지에만 예제 코드를 작성했다.

 

Servlet을 등록하면 그 Servlet이 사용할 설정파일이 자동으로 등록된다

ex ) /WEB_INF/servlet이름 - servlet.xml , 추가적으로 설정 파일을 들촉 할 수도 있다.

 

이제 적절한 컨트롤러를 찾았으면, 그 컨트롤러를 찾아야한다.

 

4. HandlerMapping에서 찾은 Handler(Controller)의 메서드를 호출한다. ModelAndView 형태로 바꿔준다. 

  (Data에 해당하는 Mdel, Data를 넘길 Page에 해당하는 View, 보통 View의 논리적인 이름만 return 해준다.)

 

* 모델은 컨트롤러가 처리한 결과, 뷰는 그 결과를 담는 페이지 라고 할 수있다.

 

컨트롤러가 그 뷰를 String Type로 주기 떄문에, 

Vuew Resolver이 이름을 가지고 실제 View를 찾아준다. 그럼 아까 Controller에서 만든 Model을 View에 심어준다.

그 후에 클라이언트에게 보내준다.

 

Spring Web MVC가 없을때와 있을때의 차이점

Spring Web MVC가 없을때,

예전에는 Url마다 Servlet를 생성하고 Web,xml로 Servlet로 관리했다.

 

/member -< Member Servlet

/line -> Line Servlet

/station -> Station Servlet

 

예전에는 URL 마다 서블릿이 하나씩 필요했다. get에 해당하는 member하나만 만들고 싶어도 위 처럼 서블릿 인스턴스를 만들어야 했다. Servlet를 만들때마다 web.xml을 하나씩 mapping 해줬어야 했는데

 

있을 때 (이렇게  Dispatcher Servlet가 생기니깐)

 

/member, /line, /station -> Dispatcher Servlet-> MemverController, LineController, StationController

 

관리가 줄어들게 되었다.

 

또 Spring Web MVC가 없을때는

 

Servlet가 View로 보내주는 것 까지 직접 다 만들었다.

String htmlResponse = "<html>";
htmlResponse += "<h2>Your username is : " + username + "<br/>";
htmlResponse += "Ypur password is : " + password + "</h2>";
htmlResponse += "</html>";

뭐 jsp가 view로 뿌려 줄 순 있었지만 강제할 수는 없었다.

 

하지만 Dispatcher Servlet를 도입하면서

 

View를 강제로 분리시키는 효과를 볼 수 있엇다.

 

 

참고 자료 :

medium.com/@kimddub/web-java-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-9fb1d35924bd

mangkyu.tistory.com/13

www.youtube.com/watch?v=2pBsXI01J6M&t=257s

728x90
반응형
Comments