Web/Spring

스프링 웹 개발 기초(정적 컨텐츠, MVC와 템플릿 엔진, API)

느낌표 공장장 2021. 7. 24. 23:43

웹 개발에는 세 가지 방식이 있다. 

  1. 정적 컨텐츠 : 서버에서 하는 거 없이 html 파일 그대로 웹브라우저로 내려준다. 
  2. mvc & 템플릿 엔진 : JSP, PHP와 같이 html을 그냥 주는 것이 아니라, 서버에서 프로그래밍한 후 html을 동적으로 바꿔서 내려준다.
  3. API : 요즘은 json이라는 데이터 구조 포맷으로 클라이언트한테 데이터를 전달해준다. 

 


 

1. 정적 컨텐츠

  • 스프링 부트는 정적 컨텐츠 기능을 제공한다(링크)
  • 원하는 파일(html)을 넣으면 정적 파일 그대로 반환이 된다. 그 대신 이 파일을 프로그래밍할 수 없다. 

  1. 웹브라우저에서 localhost:8080/hello-static.html을 치면 내장 톰켓 서버가 요청을 받고 
    1. 이런 요청이 왔대 하고 스프링에게 넘긴다. 근데 스프링은 먼저 hello-static 관련 컨트롤러가 있는지 찾아본다(컨트롤러가 우선순위에 있다는 의미) (현재는 없다.)
    2. 스프링부트는 resources 안에서 static/hello-static.html을 찾는다. 여기서 있으니까
  2. 웹 브라우저에게 넘겨준다.

 


 

2. MVC와 템플릿 엔진

  • MVC : Model, View, Controller
  • 왜 이런 스타일로 많이 할까?
    • 역할 분리를 위해 !!
    • 요즘은 Controller와 View를 쪼개는 것이 기본이다.
    • View는 화면과 관련된 일만. 비즈니스 로직과 서버 뒷단, 내부적인 로직에 관련된 건 Controller에서 처리하고 Model에 화면에서 필요한 것들을 담아서 넘겨주는 패턴을 많이 사용한다. 

 

타임리프 템플릿의 장점 : html을 그대로 쓰고 그 파일을 서버 없이 그대로 열어봐도 껍데기를 볼 수 있다. 

<p th:text="'hello ' + ${name}">hello! empty</p>

템플릿으로 동작을 하면 hello! emptyth:text="'hello ' + ${name}"으로 치환이 된다.

hello! empty처럼 넣어놓는 이유는 서버 없이 그냥 html을 볼 때 (html을 markup 해주시는 분들) 값을 적어놓고 볼 수 있으려고!  

  1. 웹브라우저에서 localhost:8080/hello-mvc를 넘기면 스프링 부트 띄울 때 같이 띄우는 내장 톰켓 서버로 넘어간다. 
  2. 내장 톰켓 서버는 스프링한테 hello-mvc을 넘긴다. 
  3. 그럼 스프링은 helloController에 어떤 메서드가 매핑이 되어있네 하고 해당 메서드를 호출해준다. hello-template을 반환해주고 model에 키는 name, 값은 spring을 스프링에 넘긴다.
  4. viewResolver(화면과 관련된 해결자. 뷰를 찾아주고 템플릿 엔진과 연결시켜줌) 동작한다.  templates 폴더에서 return 값과 똑같은 애(hello-template)를 찾아서 타임리프 템플릿 엔진에게 처리해달라고 넘긴다.
  5. 템플릿 엔진이 렌더링을 해서 변환을 한 html을 웹브라우저에 넘겨준다.

 


 

3. API

  • 위의 MVC & 템플릿 엔진은 html로 데이터를 내리지만(View 템플릿 조작), API 방식은 뷰가 없다. 데이터(문자 자체)를 바로 내린다.
    • 따라서 소스보기 하면 html태그 없이 문자만 나온다. 
  • 객체를 반환하면 객체가 JSON으로 변환된다. (이것 때문에 api방식 많이 쓴다.)
    • XML 방식은 무겁고 html을 열고 닫고 두 번 써야 하는데, JSON은 키:값 바로 나오니 심플하다.
    • 스프링도 JSON으로 반환하는 것을 기본으로 되어있다. (XML 하고 싶으면 할 수 있음)
  •  

  1. localhost:8080/hello-api를 치면 내장 톰켓 서버에서 hello-api이 왔다고 스프링에 넘겨준다.
  2. 스프링은 hello-api가 있네 ? 그런데 @ResponseBody라는 어노테이션이 붙어있으니 http응답에 그대로 이 데이터를 넘겨야겠구나 라고 동작한다. (안 붙어있으면 위 템플릿처럼 viewResolver에게 넘긴다.)
  3. return 값이 (여기에선) 객체이다. 객체가 오면 스프링은 (기본 디폴트 방식) JSON 방식으로 데이터를 만들어서 http 응답에 반환한다.
  4. 이 객체를 보고 몇 가지 조건을 보는데, 먼저 HttpMessageConverter가 동작한다.
    • 들어온 게 단순 문자열이면 StringConverter가 동작하고
    • 객체이면 JsonConverter가 동작하는데 JSON스타일로 바꾼다. 
  5. JSON을 요청한 웹브라우저(또는 서버)에게 보내준다. 

 

  • @ResponseBody 
    • HTTP의 BODY에 문자 내용을 직접 반환
      • HTTP에서 BODY부분에 이 데이터를 직접 넣겠다는 의미. (응답 바디 부분에 return내용 직접 넣어주겠다는 의미이다.) (html body tag 아님)
    • viewResolver 대신에 HttpMessageConverter 가 동작
      • 기본 문자처리: StringHttpMessageConverter
      • 기본 객체 처리: MappingJackson2HttpMessageConverter
      • byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음
      • * 깊이 있게 공부하면 이걸 바꿀 수 있는데,, 실무에서 그냥 쓴다 거의 손 안 댄다.

 

  • 참고: 클라이언트의 HTTP Accept 해더와 서버의 컨트롤러 반환 타입 정보 둘을 조합해서 HttpMessageConverter 가 선택된다. 
    • http 스펙에 보면 이런 포맷으로 받고 싶어 ~ 하는 http accpet 헤더가 있다. 여기서 json이라고 요청 오면 json으로 받고, 아무것도 안보내면(다 받을 수 있어) 스프링이 알아서 있는 걸로 보낸다. 근데 어떤 방식으로 받아야 해!라고 요청하면 해당 MessageConverter가 동작한다. 

 

 

* getter & setter

static class Hello {
  private String name;

  public String getName() {
  	return name;
  }

  public void setName(String name) {
  	this.name = name;
  }
    }
  • getter setter을 사용하면 name은 private이라서 외부에서 바로 못 꺼낸다. 그래서 라이브러리에서 쓰거나 우리가 쓸 때도 get set 메서드를 통해 접근을 하게 된다.(getName, setName은 public으로 연다.)
  • 이것을 자바 빈 표준 방식이라고 한다. 또는 property접근 방식이라고도 한다.

 

 

 


참조

이 게시물은 인프런 > 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술의 강의를 토대로 작성한 게시물입니다.

 

 

'Web > Spring' 카테고리의 다른 글

스프링 빈과 의존관계 / 웹 MVC 개발  (0) 2021.07.25
회원 관리 예제 - 백엔드 개발  (0) 2021.07.25
스프링 프로젝트 환경설정  (0) 2021.07.20
Application Scope  (0) 2021.06.24
Session Scope  (0) 2021.06.24