Servlet과 Spring MVC 1편 - Servlet의 불편함

Servlet과 Spring MVC 1편 - Servlet의 불편함

·

3 min read

(배경) 서버는 클라이언트의 요청을 받고 그에 상응하는 html 페이지를 클라이언트에게 응답해야한다. 그러면 ‘어떻게’ 응답할꺼야? 에 대한 기술의 발전에 대한 내용이다.

1. Servlet

  • (정의) WAS 내에서 동적 컨텐츠를 만드는데 사용되는 자바기반 웹 앱 프로그래밍 기술

  • (배경) 순수 자바 코드로 클라이언트의 요청을 응답하다보니, 발전해나가며 다양해지는 웹 서비스를 정적 컨텐츠로만 제공하기엔 한계가 있었기 때문이다.

  • 초기 웹 서비스의 경우, 비교적 단순했기 때문에 아래와 같은 단순한 구조로도 커버(?)가 가능했다.

  • 근데 웹 서비스가 발전하면서 정적 컨텐츠를 단순히 응답하는 것에는 한계가 존재했다.

  • 그러므로 서블릿이란 것을 활용하여 데이터를 동적으로 넣어주고자 했다.

  • 물론 좋아졌지만, 문제점이 있다.

  • 코드 레벨로 보면 서블릿의 불편한 점이 보인다. (아래는 HttpServlet을 구현 예시)

  • (문제1) html 코드를 전부 자바 코드 내에 작성해야 하므로,,어려워,,,복잡해,,,html 생성 어려워,,징글징글해

  • (문제2) 웹 서버 요청 응답 처리도 서블릿이 하는데, 화면도 얘가 그려? 과로사하겠네?

  • 즉, 유지보수가 어렵다!

2. JSP

  • (배경) 서블릿의 징그러움을 해결하기 위해 JSP가 그 짬처리를 시작. 그러나,여전히 문제는 있었다.

  • (개선점) 그래도 서블릿보다는 HTML로 구성된 뷰 영역을 명확하게 가져가고, 동적인 부분만 자바코드로 그때그때 작성함으로써 나름 깔끔해진 것을 확인할 수 있다.

  • (문제1) 그 모든 코드가 JSP 파일 하나에 몰빵한게 문제다…(가독성 실화?)

  • (문제2) JSP가 너무 많은 역할을 가져간다. 화면도 그려, 로직도 실행해,,, 과로사의 지옥에서 벗어나지 못함

3. MVC 패턴

  • (배경) UI 변경의 사이클과 비즈니스 로직의 변경 사이클이 서로 다르며 서로에게 영향을 주지 않는데, 기존 Servlet이나 JSP를 활용할 때는 작은 부분 하나 바꾸더라도 전체를 변경해야하기 때문에 유지보수에 좋지 않음

  • (정의) 하나의 서블릿,JSP로 처리하던 것을 컨트롤러와 뷰라는 영역으로 구분한 패턴

  • 기존에 하나로 묶여있던 비즈니스 로직과 뷰 로직을 분리

  • 서로의 의존관계를 줄이기 위해 가운데 모델을 두고, 필요한 데이터는 모두 모델에서 찾도록 함 이게 좋은 이유는, 뷰 로직이 특정 데이터를 찾기 위해 비즈니스 로직을 뒤질 필요가 없다는 것(의존관계 줄임)

    • 모델에 데이터 넣기 : request.setAttribute()

    • 모델에서 데이터 꺼내기 : request.getAttribute()

스프링에서 적용은 어떻게 해?

  1. JSP 파일은 WEB-INF라는 폴더 안에 따로 만들어 준다. 왜냐하면, 웹서버 설정 상 이 폴더 안에 JSP가 있으면 직접 JSP를 호출할 수 없고, 컨트롤러를 통해서 JSP를 호출해야하기 때문이다.
    (이건 그냥 설정이 그렇게 되있음)

  • 보면, JSP 코드가 순수 HTML로 이루어져 훨씬 깔끔해진 것을 확인할 수 있다.
  1. 서블릿 코드에서 JSP를 부르는 코드를 작성한다.(WEB-INF 내에 있는 JSP 파일 부르기)

  • 단, 보면 컨트롤러에서 다루는 패턴은 위와 같다. → 스프링부트에서 쉽게 다루도록 바꿀 예정

3-1. Front-Controller 패턴

  • (배경) MVC 패턴의 컨트롤러를 보면, 지속적으로 반복해서 작성된 코드들이 있다. 또한 특정 상황에서 사용하지 않는 코드도 있다(response 등) 쳐낼껀 쳐내고, 이런 공통 기능을 빠뜨리지 않고 실행할 수 있는 수문장 역할이 필요하다.

    • dispatcher.forword 중복

    • viewPath 중복 (WEB_INF/views ~~~)

    • 메서드로 묶어서 호출하는 방법도 있으나, 결국은 메서드를 호출해야하기 때문에 빠뜨릴 위험이 사라지지 않음

  • (정의) 클라이언트의 요청을 가장 먼저 받아 공통처리를 진행하는 컨트롤러

  • 위 그럼처럼, 컨트롤러에서 공통적으로 사용하는 파트를 묶어서 처리하는 컨트롤러를 프론트 컨트롤러 라고 한다.

스프링에서는 어떻게 써?

  • 기존 구조에서 조금 바뀌어야한다.

    • 컨트롤러들은 Controller 인터페이스를 구현

    • 프론트 컨트롤러는 클라이언트의 요청을 받아 각각 해당하는 컨트롤러에 요청 뿌리기