스프링 MVC1편

한상우·2022년 10월 4일
0

spring

목록 보기
2/5

스프링 MVC1편

웹서버와 WAS

웹 서버 : HTTP 기반으로 동작, 정적 리소스 제공

WAS: 웹 서버 기능 포함 + 프로그램 코드를 통해 애플리케이션 로직 수행

웹서버 정적 리소스만 제공하므로 잘 죽지 않음. WAS는 애플리케이션 로직이 동작하므로 죽을 가능성이 높음

  • 오류 화면 제공을 웹 서버가 제공

서블릿

  • 동적 웹 페이지를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍
  • 개발자가 의미있는 비지니스 로직에만 집중할 수 있도록 나머지 기능을 서블릿이 해줌
  • WAS는 Request, Response 객체를 새로 만들어서 서블릿 객체 호출 개발자는 Request객체에서 HTTP 요청 정보 편리하게 꺼내고 Response 객체에 HTTP 응답 정보를 편리하게 입력 WAS는 Response 객체에 담겨 있는 내용으로 웹 브라우저에 전송

서블릿 컨테이너

  • 서블릿 객체를 호출, 종료
  • 객체는 기본적으로 싱글톤으로 관리
  • 동시 요청을 위한 멀티 스레드 처리 지원

스레드 풀

  • 단일 스레드는 동시 요청 처리 불가
  • 요청마다 스레드 생성 - 비용이 너무 많이 발생
  • 필요한 스레드를 스레드 풀에 보관하고, 미리 생성되어 있는 스레드 사용하므로 응답 시간 빠름
  • WAS의 튜닝 포인트는 MAX 스레드
  • 너무 낮게 설정하면 서버 리소스는 여유있지만, 클라이언트는 금방 응답 지연
  • 너무 높게 설정하면 서버가 다운될 수 있음

스프링 구조가 나오게 된 과정


서블릿 시기

web.xml로 요청 uri 와 서블릿 객체를 매핑

→ 서블릿 컨테이너에서 서블릿 객체들을 관리해줌

→ web.xml에 모든 서블릿을 매핑하고 작성하는 등 넘나 귀찮띠

→ 프론트 컨트롤러 패턴을 도입

프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받음

프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아 호출

JSP

서블릿으로 동적 처리를 위해 아래와 같이 문자로 작성

w.write("<html>\n" +
 "<head>\n" +
 " <meta charset=\"UTF-8\">\n" +
 "</head>\n"

에바다.. 자바 코드로 html을 만드는 것 보다 html에 변경해야 하는 부분에만 자바 코드를 넣자

해서 나온게 탬플릿 엔진 (JSP, 타임리프…)

→ JSP가 너무 무거워짐

→ HTML과 자바가 한 파일에 있어 동시 작업이 불가..

MVC 패턴

  • 로직과 뷰를 나누자
  • 컨트롤러에서 로직을 처리함 - 모델에 담아서 뷰로 넘김 - 뷰는 이를 동적으로 처리
컨트롤러: HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다. 그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.
모델: 뷰에 출력할 데이터를 담아둔다. 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 일에 집중할 수 있다.: 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다. 여기서는 HTML을 생성하는 부분을 말한다.
@WebServlet(name = "mvcMemberListServlet", urlPatterns = "/servlet-mvc/
members")
public class MvcMemberListServlet extends HttpServlet {

	@Override
	 protected void service(HttpServletRequest request, HttpServletResponse 
	response)
	 throws ServletException, IOException {

		String viewPath = "/WEB-INF/views/members.jsp"
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
		dispatcher.forward(request, response);
	}
}

→ 중복되는 코드가 너무 많고, 필요없는 코드까지 껴있다.

→ view path, 포워드 중복, 공통 처리 많음

컨트롤러 호출 전에 공통 기능을 처리하는 프론트 컨트롤러 패턴 도입

스프링 구조 V1 ~ V5

v1

  • front controller 도입 해봄

v2

  • 컨트롤러 → 뷰로 이동하는 부분에 중복이 있는데
  • 별도로 뷰를 처리하는 객체를 만들어줬음

v3

  • 컨트롤러 입장에서 서블릿의 req, res 객체가 꼭 필요할까???
  • 요청 파라미터 정보를 자바 Map으로 넘겨, 컨트롤러는 서블릿 몰라도 동작 가능
  • request객체를 모델로 넘겨주는 대신, 모델 객체를 따로 만들어 컨트롤러는 아예 서블릿 기술 사용 X (dispatcher servlet을 제외한 컨트롤러는 진짜 자바 순수 객체)
  • 컨트롤러가 서블릿 기술을 사용하지 않기에 테스트 코드 작성에도 좋음
  • 뷰 이름도 따로 중복을 제거해줌 /WEB-INF/views + .jsp

v4

  • 모델 객체로 안넘겨주고 이름만 반환

v5

  • 어댑터를 적용해 서로 다른 인터페이스를 가진 컨트롤러도 처리할 수 있게 이 때 컨트롤러를 핸들러라고 지칭할 수 있고, 핸들러 매핑을 어댑터에서 해준다

핸들러 매핑, 어댑터

  • 핸들러 매핑에서 컨트롤러를 찾을 수 있어야 함
  • 이 컨트롤러(핸들러)를 실행할 수 있는 어댑터가 필요함

핸들러 매핑의 우선순위

0 = RequestMappingHandlerMapping

핸들러 어댑터의 우선순위

0 = RequestMappingHandlerAddapter

둘 다 @RequestMapping 에서 사용함

요청 파라미터

  • @RequestParam
  • @ModelAttribute
    • 요청 파라미터를 바인딩 받을 객체 : HelloData를 미리 만들어줌

      @Data
      class HelloData {
      	private String username;
      	private int age;
      }
      public String modelAttributeV1(@ModelAttribute HelloData hellodata)

      → HelloData 객체가 생성, 요청 파라미터 값도 모두 들어가 있다

단순택스트

  • @RequestBody 를 통해 HTTP 메시지 바디 정보를 편하게 조회 가능

헤더 정보

  • @RequestHeader 를 통해 헤더 정보 조회 가능

JSON 데이터

  • @RequestBody 를 통해 JSON 데이터도 간단하게 받을 수 있다
  • @RequestBody HelloData data

HTTP 응답

  • @ResponseBody 가 있으면 뷰 리졸버를 실행하지 않고, HTTP 메시지 바디에 직접 문자가 입력
  • @ResponseBody 가 없으면 뷰 리졸버가 실행되어 뷰를 찾고 렌더링
  • @RestController 는 @Controller + @ResponseBody

메시지 컨버터

  • JSON 데이터를 HTTP 메시지 바디에서 직접 읽거나 쓰는 경우 사용
  • 메시지를 읽어들이거나 (@RequestBody) 메시지를 작성할 때 사용 (@ResponseBody)
  • ByteArray, String, MappingJackson … 다양한 메시지 컨버터가 존재, 대상 클래스 타입과 미디어 타입을 체크해 사용 여부 결정

ArgumentResolver

  • 애노테이션 기반의 컨트롤러는 다양한 파라미터를 사용할 수 있는데, 이는 ArgumentResolver 덕분이다. 이 친구가 컨트롤러가 필요로 하는 다양한 파라미터의 값(객체)를 생성하여 컨트롤러에게 값을 넘겨준다

ReturnValueHandler

  • 응답 값을 변환하고 처리한다 (ArgumentResolver와 비슷)
profile
안녕하세요 ^^

0개의 댓글