📙

[스프링 입문] 2. 스프링 웹 개발 기초

작성일자
Oct 1, 2022
태그
SUB PAGE
프로젝트
스프링 입문
책 종류
본 게시글은 하단 강의를 듣고 학습한 내용을 제 생각으로 요약, 정리한 글입니다.

1. 정적 컨텐츠

1) 웹 개발 3가지 방식(정적 컨텐츠/MVC,템플릿/API 방식)

  • 정적 컨텐츠: 서버에서 하는 것 없이 파일을 웹브라우저에 그대로 내려줌
  • MVC와 템플릿 엔진
    • 템플릿 엔진: JSP, PHP와 같은 것들. 서버에서 변형해서 해서 html을 동적으로 바꿔서 내려줌.
    • 이를 위해 사용하는 컨트롤러, 모델, 템플릿 엔진 화면, 이 세 가지가 model view controller이라 해서 MVC라고 함.
  • API 방식
    • 안드, ios 클라와 개발한다면, 서버 입장에서 (과거엔 xml과 같은 포멧 썼지만) 요즘은 json이란 데이터 구조 포멧으로 html이 아니라 데이터를 클라에게 전달해주는 방식이 API 방식임.
    • view, react같은 거 쓸 때도 api로 데이터만 내려주면 화면은 클라가 알아서 그리게 됨.
    • 서버끼리 통신할 땐 html 내릴 필요가 없기에 데이터 왔다갔다 하는걸 API방식이라 함.
 

2) 정적 컨텐츠 방식

 

3) hello-static.html → 정적 컨텐츠 방식

resources/static/hello-static.html
 

4) 정적 컨텐츠 제공 기능의 원리

notion image
  1. 내장 톰캣 서버가 요청을 받아 hello-static.html 왔다고 스프링한테 넘김
  1. 스프링은 컨트롤러에서 hello-static이란게 있는지 먼저 찾아봄 (매핑된 컨트럴로 없으면 다음으로)
  1. 내부 resources안에 있는 static에 hello-static.html 찾아봄
  1. 있으면 얘를 넘겨줌
 

2. MVC와 템플릿 엔진

1) MVC: Model, View, Controller

  • 과거: Model-One 방식
    • Controller와 View가 구분되어 있지 않고 View에서 모든 것을 다함.
    • JSP 파일 하나가 수천 라인이 넘어감. View안에서 db도 접근하고, 컨트롤러 로직도 다 있고, 비즈니스 로직도 화면에 다 있음. 모든 View 파일 하나 안에.
  • 현재: MVC 방식
    • 관심사, 역할과 책임을 분리함.
    • View: 화면을 그리는데에 모든 역량을 집중해야함.
    • Controller와 Model: 비즈니스 로직과 관련있거나, 내부적인걸 처리하는데 집중해야함.
    • MVC 패턴 가지고 Model, View, Controller 쪼개고 비즈니스 로직 쪼개고 그럼.
      • 비즈니스 로직과 관련 있거나 서버 뒷단 관련된 거는 Controller나 뒷단 비즈니스 로직에서 다 처리하고,
      • Model에다가 관련된 화면에서 필요한 것들을 담아서 화면 쪽에 넘겨주는 패턴
       

2) /hello-mvc & hello-template.html → parameter 있는 MVC, 템플릿 엔진 방식(동적 컨텐츠 방식)

src/main/java/hello.hellospring.controller/HelloController.java
src/main/resources/templates/hello-template.html
  • 타임리프의 장점
    • copy path - absolute path하면 (C:\리포지토리\GDSC-1st-Backend-Study\ChooSeoyeon\스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술\src\main\resources\templates\hello-template.html)
    • notion image
    • 파일을 열었는데 뭔가 나옴. → 장점: html을 그대로 쓰고 파일을 서버 없이 열어봐도 껍데기를 볼 수 있음.
    • 그러다 템플릿 엔진으로 동작하게 되면 hello! empty가 치환됨.
    • hello! empty 내용 넣어 놓는 건 서버 없이 html만 만들어 보는 분들이 볼 때 값을 적어 놓고 볼 수 있게 하기 위함임.
    •  
localhost:8080/hello-mvc 로 실행 → 에러 남
notion image
  • 에러 내용: 필요한 인자 ‘name’이 없음
  • 해결 1) required 값을 false로 변경하기(default가 true임)
    • parameter 정보 옵션 넣기(ctrl+p)
    • @RequestParam("name") String name@RequestParam(value = "name", required = false) String name 로 바꿔주기
    • notion image
  • 해결 2) 값을 넘기기(기본)
    • required값 안 바꾸고 그냥 url에 parameter넘겨주기!
    • localhost:8080/hello-mvc?name=seoyeon
    • notion image
       
localhost:8080/hello-mvc?name=seoyeon 로 실행 → 성공
  • 동작 방식
    • name=seoyeon이면 스프링에서 model 안에 name이 seoyeon이 담기고, template으로 넘어가면 그게 ${name}에 들어감
    • ${name}은 모델의 key값이 name인 것에서 값을 꺼내서 치환해주는 것임.

3) MVC, 템플릿 엔진 이미지

notion image
  1. 웹 브라우저에서 localhost:8080/hello-mvc 넘기면 스프링부트가 띄울 때 같이 띄우는 내장 캣 서버를 먼저 거침
  1. 내장톰캣서버가 hello-mvc란게 왔다고 스프링한테 던짐
  1. 스프링은 hello-mvc가 helloController의 method에 매핑이 되어 있는걸 확인하고서 그 method를 호출해줌
  1. 리턴할 때 이름을 hello-template이라 해주고, model에는 key는 name이고 값은 seoyeon이라고 넣어줌. 이들을 스프링한테 넘겨줌
  1. 스프링의 viewResolver(화면과 관련된 해결자)가 동작함. view찾아주고 템플릿 엔진 연결시켜주는 애임. viewResolver가 templates/hello-template.html찾아서 타임리프 템플릿 엔진한테 처리해달라고 넘김
  1. 템플릿엔진이 렌더링해서 변환한 html을 웹 브라우저에 반환함(동적)
 

3. API

1) 지금까지 배운 3가지 방식 (정적 컨텐츠/MVC,템플릿/API 방식)

  • 정적 컨텐츠 방식 (Controller 사용x)
    • 파일을 그대로 내려주는 방식
    • index.html
    • hello-static.html
  • MVC, 템플릿 방식 (Controller 사용o) (html을 내림 → View 사용o)
    • MVC 방식에서 view 찾아서 템플릿 엔진 통해서, 화면 렌더링해서 html을 웹브라우저에 넘겨주는 방식
    • /hello & hello.html → url parameter x
    • /hello-mvc & hello-template.html → url parameter o
  • API 방식 (Controller 사용o) (데이터를 바로 내림 → View 사용x)
    • 데이터를 그대로 내려주는 방식.
    • 객체를 JSON으로 변환해서 반환함. View 없이 HTTP Response에 값을 넣어서 반환.
    • ResponseBody 사용
    • /hello-string
 

2) /hello-string→ API 방식 (단순 문자 전달: 문자 반환)

src/main/java/hello.hellospring.controller/HelloController.java
  • ResponseBody
    • html에 나오는 body 태그 x
    • http에서 header부와 body부가 있음(http 통신 프로토콜).
    • 그 응답 body부에 데이터(”hello “ + name)를 직접 넣어주겠단 뜻.
  • src/main/resources/templates/~~ → 없음! View가 없다했잖아.
http://localhost:8080/hello-string?name=choochoo로 실행
  • 실행 결과
    • notion image
  • 페이지 소스 → html 태그 같은 거 없고 내가 넣은 문자 뿐
    • notion image
  • 결론
    • @ResponseBody를 사용하면 viewResolver를 사용하지 않음.
    • 대신에 HTTP의 BODY에 문자 내용을 직접 반환
 

3) /hello-api → API 방식 (데이터 전달: 객체 반환. JSON 방식)

src/main/java/hello.hellospring.controller.HelloController.java
  • Hello를 static 클래스로 만들면 HelloController 클래스 안에서 Hello클래스를 쓸 수 있음.
    • HelloControler.Hello 라고.
http://localhost:8080/hello-api?name=choochoo로 실행
  • 실행 결과 → 이전과 다름 (JSON)
    • notion image
    • json 방식: key, value로 이루어진 구조
    • 과거: XML 방식
      • html 태그 <HTML> </HTML>
      • 무겁고, 열고 닫고 두 번 써야 함
    • 현재: JSON 방식
      • name은 value 바로 나와서 간단함
      • default값임.
      • 객체 반환하고 @Responsebody라고 해놓으면 스프링이 알아서 보고, 객체를 json으로 변환해서 반환하는게 default로 세팅되어 있음!
  • 페이지 소스
    • notion image
       
 

4) ResponseBody 동작과정

notion image
  1. 웹 브라우저에서 localhost:8080/hello-api 보내면 톰캣 내장 서버가 이를 인지하고 스프링에 던짐
  1. 스프링은 Controller에 보니 hello-api가 존재함. 근데, ResponseBody라는 annotation이 붙어있음.
      • 그러면 이전에 template에서 viewResolver에서 던졌던 것과 달리, Http에 데이터를 그대로 넘겨야 되겠다고 생각함.
      • 그런데, 얘가 문자가 아니라 객체임. 이전에 문자인 경우 http 응답에 넣어 바로 줬음. 이와 달리, 객체는 생각을 한 번 해야 함.
      • 그래서 정한 객체가 왔을 때 기본 default가 json방식으로 데이터 변환해서 http 응답에 반환하는 것임.
  1. ResponseBody가 있으면 viewResolver가 아니라 HttpMessageConverter가 동작함.
  1. HttpMessageConverter에서 단순 문자면 StringConverter가 동작하고, 객체면 JsonConverter가 동작함. Hello 객체 보니 name이 있고 값이 있네. 객체를 json 스타일로 바꿈
  1. 요청한 웹 브라우저나 서버한테 바꾼 걸 보내줌. 응답해줌.
정리
  • Http의 body에 문자 내용을 직접 반환
  • viewResolver 대신에 HttpMessageCoverter가 동작
  • 기본 문자 처리: StringHttpMessageConverter
  • 기본 객체 처리: MappingJackson2HttpMessageConverter
    • Jackson: 객체를 JSON으로 바꿔주는 라이브러리. 스프링은 이걸 채택함.
      • 이거 말고 구글에서 만든 Gson이란 것도 있음
  • byte 처리 등등 기타 여러 HttpMessageConverter가 스프링에 기본으로 등록되어 있음
    • → 실무에서도 거의 그대로 씀. 손대지 않고.
참고 → 스프링 MVC 강의 내용
  • HTTP 보면 요청할 때 특정 포멧으로 받고 싶어하는 Accept 라는 헤더가 있음. 거기서 json이란 요청 오면 json으로 받고, 아무것도 안 보내면 스프링이 알아서 있는 거로 보냄. 그런데, 꼭 xml 혹은 무언가로 받을거란 요청 오면 이때 해당하는 MessageConverter가 동작함.
 
[스프링 입문] 2. 스프링 웹 개발 기초