개발 새발/Spring

[Spring] 스프링 웹 개발 기초 - 정적 컨텐츠/동적 컨텐츠

recordari 2024. 7. 31. 18:36

*인프런 김영한의 스프링 입문 강의를 기반으로 작성되었습니다.

 

웹 개발을 하는 3가지 방식은 다음과 같다.

정적 컨텐츠 - 서버에서 파일을 있는 그대로 웹 브라우저(클라이언트)로 전달한다.
MVC와 템플릿 엔진: 서버에서 프로그래밍을 통해 HTML을 동적으로 바꿔서 보내는 일을 하고, 이를 위해 MVC(Model, View, Controller) 패턴으로 개발하는 경우가 많다.
API - 클라이언트 또는 다른 서버와 JSON이라는 데이터 구조 포맷으로 클라이언트에게 데이터를 전달하는 방식을 말한다.

 

1. 정적 컨텐츠

스프링 부트는 정적 컨텐츠 기능을 자동으로 제공한다.

스프링부트 프로젝트 내 src/main/resource/static 위치에 hello-static.html 파일을 생성한다.

그리고 다음과 같은 코드를 입력 후 프로젝트(HelloSpringApplication.java 파일)를 실행한다.

<!DOCTYPE HTML>
 <html>
 <head>
     <title>static content</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 </head>
<body>
정적 컨텐츠 입니다.
</body>
</html>

그런 다음 "http://localhost:8080/hello-static.html" 주소를 입력하여 브라우저에서 열어보면

body 태그 안에서 작성한 문장이 화면이 뜨는 것을 볼 수 있다.

 

스프링부트에서 정적 컨텐츠를 제공하는 동작 원리는 아래와 같다.

  • 웹브라우저에서 localhost:8080/hello-static.html 주소를 내장 서버인 tomcat에게 요청한다.
  • tomcat이 해당 요청을 받아서 hello-static.html에 대해 스프링 컨테이너에게 요청이 왔음을 알린다.
  • spring이 hello-static.html 요청을 받으면 우선 컨트롤러에서 hello-static과 mapping되는 것이 있는지 확인한다.(즉, 컨트롤러가 우선순위를 가진다)
  • 없다면 resources/static 폴더에서 hello-static.html 파일을 찾고, 해당 위치에 파일이 존재한다면 그 파일을 반환해준다.

 

동적 컨텐츠는 어떤 클라이언트가 언제, 어디서, 어떻게 서버에 요청했는지에 따라 각기 다른 결과를 보여준다

 

2. MVC와 템플릿 엔진

MVC 패턴은 Model, View, Controller을 의미한다.

자인 패턴  하로, 데이터를 표현하는 자인(view)과 로(model)을 분리으로써 느슨결합이 가능하다. Model 은 앱에서 요로 하는 모지속적 데이터를 리하고, View 는 model 에서 받데이터를 시각적으로 할을 한다. Control model 과 view 를 연결하는 할을 한다.

 

템플릿 엔진은 정적 컨텐츠와 다르게 프로그래밍을 해서 html을 동적으로 바꿔서 웹 브라우저에 보내는 일을 한다. JSP, PHP 등이 이에 해당한다.

 

이제 MVC와 템플릿 엔진 방식의 원리를 살펴보자

 

Controller

scr/main/java/hello.hello_spring 위치에 controller 폴더를 하나 만들어서 HelloController.java라는 이름의 자바 파일을 만들어준다.

(폴더 위치는 아래 사진 참고)

 

그리고 다음과 같이 코드를 작성해준다. "hello-mvc"라는 요청이 들어왔을 경우 동작하는 메소드이다.

@Controller
 public class HelloController {
     @GetMapping("hello-mvc")
     public String helloMvc(@RequestParam("name") String name, Model model) {
         model.addAttribute("name", name);
         return "hello-template";
     }
}
  • @GetMapping("hello-mvc")는 GET 요청(/hello-mvc)이 들어오면 helloMVC() 메소드를 호출한다.
  • helloMVC() 메소드의 파라미터 값으로 @RequestParam이라는 어노테이션(주석이라는 뜻을 가진 코드 사이에 특별한 의미, 기능을 수행하도록 하는 기술)을 사용하여 클라이언트가 요청한 URL의 쿼리 파라미터에 대한 값을 받아올 수 있다.
  • addAttribute() 메소드를 이용하여 View에 전달할 데이터를 key, value 형태로 model에 저장한다.
  • View 파일명인 "hello-template"를 반환하면 뷰 리졸버(viewResolver: 객체를 View 영역으로 전달하기 위해 알맞은 View 정보를 설정하는 역할)가 해당 템플릿을 찾아서 Thymeleaf에게 처리해달라고 넘기고, Thymeleaf는 model에 저장된 데이터를 가져와 값을 변환하고, 변환된 HTML을 웹 브라우저에게 반환한다.
참고
@RequestParam("가져올 데이터의 이름") [데이터타입] [가져온 데이터를 담을 변수]

 

 

View

resources/templates 위치에 hello-template.html 이라는 이름으로 파일을 만들어 준다.

(폴더 위치는 아래 사진 참고)

 

그리고 다음과 같은 코드를 작성해준다.

<html xmlns:th="http://www.thymeleaf.org">
 <body>
 <p th:text="'hello ' + ${name}">hello! empty</p>
 </body>
</html>

프로젝트(HelloSpringApplication.java)를 실행시키고 "http://localhost:8080/hello-mvc?name=spring" 처럼 /hello-mvc 요청 다음에 ?name=spring이라고 쿼리 파라미터를 넣어주면 전달받은 데이터를 모델에 저장하고 화면에서 출력시킨다.

 

MVC와 템플릿 엔진의 동작 원리는 아래와 같다.

  • localhost:8080/hello-mvc 경로로 접속하게 되면 내장 톰캣 서버가 해당 요청을 받아서 스프링 컨테이너에게 해당 주소로 요청이 왔음을 알린다.
  • 스프링 컨테이너는 helloController(내부 컨트롤러)에서 해당 URL과 mapping되는 메소드를 찾아서 호출한다. (매개변수로 model을 넘겨받는데, model은 스프링이 만들어서 넣어준다)
  • 메소드 내에서 model 객체에 data라는 이름에 파라미터로 받은 name 값을 넣고 이후 반환값을 리턴한다.(model에 담으면 view에서 렌더링 할 때 사용)
  • 이때 컨트롤러에서 리턴 값으로 문자를 반환하면, 뷰 리졸버가 화면을 찾고 Thymeleaf 템플릿 엔진에 처리를 요청한다. (뷰 리졸버: view를 찾아서 템플릿 엔진을 연결시켜줌)
  • 템플릿 엔진이 렌더링을 해서 변환한 html을 웹 브라우저에 반환한다.

3. API

서버에 요청이 들어오면 view를 거치지 않고 컨트롤러에서 직접 JSON 형식의 데이터를 클라이언트에게 리턴해준다.

 

Controller

@ResponseBody (문자 반환)

다음 코드는 HelloController.java 파일에서 문자를 반환해 주는 코드이다.

HelloController에 "hello-string"이라는 요청이 들어왓을 경우 동작하는 메소드를 작성해주었다.

@Controller
 public class HelloController {
     @GetMapping("hello-string")
     @ResponseBody
     public String helloString(@RequestParam("name") String name) {
         return "hello " + name;
     }
}

@ResponseBody를 사용하면 뷰 리졸버를 사용하지 않고 HttpMessageConverter가 동작해서  HTTPBODY에 문자 내용을 직접 반환하겠다는 것을 의미한다.

프로젝트 실행 후 "http://localhost:8080/hello-string?name=spring!" 링크로 /hello-string 요청을 spring!이라는 파라미터와 같이 보내게 되면 아래 처럼 해당 문자값이 반환되어 있는 걸 볼 수 있다.

(오른쪽은 페이지 소스 보기 화면이다)

 

@ResponseBody (객체 반환)

다음은 HelloController.java 파일에서 객체를 반환하는 코드이다.

HelloController에 "hello-api"이라는 요청이 들어왓을 경우 동작하는 메소드와 hello 객체를 작성해주었다.

@Controller
 public class HelloController {
     @GetMapping("hello-api")
     @ResponseBody
     public Hello helloApi(@RequestParam("name") String name) {
         Hello hello = new Hello();
         hello.setName(name);
         return hello;
     }
     static class Hello {
         private String name;
         public String getName() {
             return name;
             }
         public void setName(String name) {
             this.name = name;
		} 
	}
}

helloApi() 메소드가 실행되면 hello라는 객체를 새로 생성하고 setName()을 통해서 파라미터로 전달받은 값을 이름으로 설정한다.

@ResponseBody를 사용하고, 객체를 반환하면 객체가 JSON으로 변환된다. (hello 객체를 반환)

프로젝트 실행 후 "http://localhost:8080/hello-api?name=spring!" 링크로 /hello-api 요청을 srping!이라는 파라미터와 같이 보내게 되면 다음과 같이 JSON 형식으로 변환되어 출력된 것을 볼 수 있다.(MappingJackson2HttpMessageConverter를 통하여 변환)

 

ResponseBody 작동원리는 아래와 같다.

  • "localhost:8080/hello-api?name=spring"로 접속하게 되면 내장 톰켓 서버에서 요청을 받아 스프링 컨테이너에 해당 주소로 요청이 왔음을 알린다.
  • 스프링 컨테이너는 helloController(내부 컨트롤러)에서 해당 URL과 mapping되는 메소드를 찾아서 호출한다. @ResponseBody 어노테이션을 확인하고 hello 객체를 넘긴다. 뷰 리졸버 대신에 HttpMessageCoonverter가 동작하고, 메서드 내 객체 존재를 확인 후 JsonConverter을 실행한다.
  • 스프링 컨테이너에 @ResponseBody가 붙어있으면 반환값을 보고 HttpMessageConverter가 Json과 String 형식 중에 어떠한 것으로 변환할건지 결정한다. 반환값이 단순 문자열이면 StringConverter, 객체라면 JsonConverter가 동작한다.
<정리>
@ResponseBody를 사용하면
- HTTP의 BODY에 문자 내용을 직접 반환
- viewResolver 대신에 HttpMessageConverter가 동작
- 기본 문자처리: StringHttpMessageConverter
- 기본 객체처리: MappingJackson2HttpMessageConverter
- byte 처리 등 기타 여러 HttpMessageConverter가 기본적으로 등록되어 있음

 

참고 블로그

https://velog.io/@tngh4037/%EA%B9%80%EC%98%81%ED%95%9C-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-2-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9B%B9-%EA%B0%9C%EB%B0%9C-%EA%B8%B0%EC%B4%88

 

[ 김영한 스프링 입문 #2 ] 스프링 웹 개발 기초

[스프링 입문] 두 번째 section은 스프링 웹 개발 기초에 관한 내용이다. 참고로 지난 첫 번째 section의 [view 환경설정]과 유사한 내용이 있으니, 해당 링크를 참고하면서 봐도 좋을 것 같다. 내용은

velog.io

 

https://velog.io/@gerrymandering/Spring-%EC%A0%95%EC%A0%81-%EC%BB%A8%ED%85%90%EC%B8%A0%EB%8F%99%EC%A0%81-%EC%BB%A8%ED%85%90%EC%B8%A0

 

[Spring] 정적 컨텐츠/동적 컨텐츠

정적 컨텐츠와 동적 컨텐츠의 차이에 대해 알아보고 API 방식을 이용하여 JSON 형식의 데이터를 받아오는 코드를 작성해보자

velog.io