서블릿 & MVC 탄생 배경

이정원·2024년 10월 25일

1.웹 서버,WAS

  • 웹 서버는 정적 리소스(파일), WAS는 애플리케이션 로직이다.
  • 정적 리소스가 많이 사용되면 Web 서버 증설,애플리케이션 리소스가 많이 사용되면 WAS를 증설한다.
  • WAS,DB 장애시 WEB 서버가 오류 화면을 제공한다.

2.서버에서 처리해야 하는 업무

  • 서버 TCP/IP 연결 대기, 소켓 연결
  • HTTP 요청 메세지를 파싱해서 읽기
  • POST 방식,/save URL 확인
  • Content-Type 확인
  • HTTP 메세지 바디 내용 피싱(애플리케이션의 데이터로 변환)
  • 저장 프로세스 실행
  • 비지니스 로직 실행(WAS), DB에 저장 요청
  • HTTP 응답 메세지 생성 시작(HTTP 시작 라인 생성,Header 생성,바디 입력)
  • TCP/IP에 응답 전달,소켓 종료

서블릿(Servlet)자바(Java)를 기반으로 한 서버 측 프로그램으로써 HTTP 요청 정보를 편리하게 사용할수 있도록 만들어준다. 서블릿은 Spring MVC의 핵심 토대로, Java의 서블릿 기술을 기반으로 구축된 프레임워크이다. 이를 통해 서블릿의 기능을 확장하여 보다 효율적이고 구조화된 웹 애플리케이션 개발을 지원한다.

구성 방법은 구성 파일에 대한 @ServletComponentScan 등록과,

@ServletComponentScan //서블릿 자동 등록
@SpringBootApplication
	public class ServletApplication {
	public static void main(String[] args) {
		SpringApplication.run(ServletApplication.class, args);
		}
}

실행 클래스에 @WebServlet를 붙여 실행한다.

@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException {

}


웹 브라우저에서 요청을 보내면 WAS에서 요청 메세지를 기반으로 request,response 객체를 새로 만든다. 이후 만든 helloservlet의 service 메서드를 실행한다. 최종으로 response 객체를 통해 HTTP 응답 메세지를 웹 브라우저에게 전달한다.

WAS 안에 서블릿을 지원하는 서블릿 컨테이너가 존재하는데, 서블릿 객체를 서블릿 컨테이너가 생성,호출, 이런 생명주기 관리를 해준다.

모든 서블릿 객체는 싱글톤으로 관리되며 고객 요청은 동일한 서블릿 객체 인스턴스에 접근한다.

여기서 WAS의 servlet은 Thread가 요청한다. 여기서 단일 Thread일 경우 요청이 지연되면 각 요청 모두 예외가 발생할수 있다. 따라서 멀티 Thread를 운용하는데 Thread의 생성 비용은 비싸고 컨텍스트 스위칭 비용,생성의 임계점이 넘으면 서버가 죽을수 있는 단점 때문에 Thread Pool을 통한 재사용으로 문제를 해결한다. 쓰레드 풀의 적정 숫자는 성능 테스트를 통해 찾는다.

여기서 핵심은 WAS가 멀티 스레드 지원을 해준다는것이다.

서블릿 컨테이너: Java 서블릿(Servlet)을 실행하고 관리하는 역할을 하는 서버 환경(Apache,Tomcat)

HTTP 요청 데이터
클라이언트에서 서버로 다음 3가지 데이터 전송 방법이 있다.

1.GET-쿼리 파라미터

  • 메세지 바디 없이 ?username=jeongwon&age=20 으로 URL 쿼리 파라미터로 보낸다.(검색,필터,페이징)

2.POST- HTML Form

  • content-type: application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파리미터 형식으로 전달 username=hello&age=20

3.HTTP message body

  • content-type: application/json
  • HTTP API에서 주로 사용, JSON, XML, TEXT

3.Form 파라미터 형식 조회

HttpServletRequest는 Content-Type이 application/x-www-form-urlencoded 형식일 때, 폼 필드 데이터를 쉽게 가져올 수 있는 메서드를 제공한다.

HTML로 <*form method=" ">형식으로 제출하며

  • 메서드가 Post일때 HTTP 요청의 바디 부분에 key=value 형식
  • 메서드가 Get일때 URL의 쿼리 스트링으로 붙어서 전송

HttpServletRequest 해당 객체로 요청을 받아 처리한다.

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
    // 단일 파라미터 조회
    String name = request.getParameter("name");
    String age = request.getParameter("age");
}

Note: GET URL 쿼리 파라미터 형식으로 클라이언트에서 서버로 데이터를 전달할 때는 HTTP 메시지 바디를 사용하지 않기 때문에 content-type이 없다.

5.Message Body 데이터 직접 조회(HTTP API 메세지 바디)

폼 데이터가 아닌 JSON, XML,text/plain과 같은 형식을 처리할 때 사용하며 요청 바디의 데이터를 자동으로 파싱하지 않으므로 데이터를 직접 읽어야 한다.

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
    // 요청 바디의 데이터를 직접 읽기 (예: JSON 형식)
    StringBuilder jsonData = new StringBuilder();
    String line;
    
    // BufferedReader를 사용해 텍스트 데이터 읽기
    BufferedReader reader = request.getReader();
    // 이하 생략

    // 읽어들인 데이터를 출력 (예: JSON 처리)
    String requestBody = jsonData.toString();
    response.setContentType("application/json");
    response.getWriter().println("Received JSON data: " + requestBody);
}

5.MVC 패턴의 등장

MVC 패턴이 등장한 이유는 서블릿으로 개발할 때 뷰(View) 화면을 위한 HTML 코드가 자바 코드에 혼합되면서 코드가 지저분하고 복잡해지는 문제를 해결하기 위해서였다. 이를 개선하기 위해, 비즈니스 로직은 서블릿과 같은 다른 곳에서 처리하고, JSP는 화면(View)을 그리는 일에 집중하도록 설계되었다. 이렇게 하면 코드의 유지보수성과 가독성이 크게 향상된다.

Model View Controller


MVC 패턴은 지금까지 학습한 것 처럼 하나의 서블릿이나, JSP로 처리하던 것을 컨트롤러(Controller)와 뷰(View)라는 영역으로 서로 역할을 나눈 것을 말한다. 웹 애플리케이션은 보통 이 MVC 패턴을 사용한다.

request 객체에서 RequestDispatcher 파라미터에 view 경로를 넘기고 forward를 통해 서블릿에서 다른 서블릿, JSP 또는 다른 리소스로 요청을 전달하여 고객에게 UI를 동적으로 제공한다.

View 에서 참고하는 Model은 request의 setAttribute를 통해 설정한 데이터를 렌더링한다.

  • Controller: HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다. 그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.

  • Model: 뷰에 출력할 데이터를 담아둔다. 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 일에 집중할 수 있다.

  • View: 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다. 여기서는 HTML을 생성하는 부분을 말한다.

Note:컨트롤러에 비즈니스 로직을 둘 수도 있지만, 이렇게 되면 컨트롤러가 너무 많은 역할을 담당한다. 그래서 일반적으로 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다. 그리고 컨트롤러는 비즈니스 로직이 있는 서비스를 호출하는 역할을 담당한다.

서블릿마다 개별 컨트롤러를 생성하여 클라이언트의 요청을 처리하는 방식은 중복된 코드가 많아지고 유지보수가 어려워질 수 있다. 이러한 문제를 해결하기 위해 프론트 컨트롤러(Front Controller) 패턴을 도입한다. 모든 클라이언트 요청을 중앙에서 처리할 수 있어 공통 처리(인증, 로깅, 예외 처리 등)를 모든 서블릿에서 반복해야 하는 문제가 해결되고 코드 중복을 줄여 일관된 구조를 유지할 수 있다.

0개의 댓글