2021. 3. 12. 01:28ㆍWEB Dev./Spring Boot 입문
스프링 웹 개발 기초
웹 개발에는 크게 3가지 방법이 있다.
- 정적 컨텐츠
> 파일을 그대로 웹 브라우저에 보여주는 것 - MVC와 Template Engine
> Template Engine? Ex, JSP, PHP, Thymeleaf, Pug ...
> HTML을 그냥 보여주는 것이 아니라 서버에서 프로그래밍해서 동적으로 바꿔서 보여준다. - API
> 만약 모바일 개발자와 협업을 한다고 하면, 요즘엔 JSON으로 함께 협업한다.
> 또는 서버끼리 데이터를 주고받는 방식을 API라고도 한다.
이 세 가지 방법에 대해 조금 더 자세하게 알아보자.
정적 컨텐츠
스프링 부트는 자동으로 정적 컨텐츠 기능을 제공해준다.
Spring Boot Features
Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and Servlet-based web applications. It occurs as part of closing the application context and is performed in the earliest
docs.spring.io
프로젝트에서 /src/main/resources/static에 아무 파일이나 만들어보자
<!DOCTYPE HTML>
<html>
<head>
<title>static content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
정적 컨텐츠 입니다.
</body>
</html>
localhost:8080/hello-static.html 로 접속하면 위 코드의 내용이 그대로 출력되는 것을 확인할 수 있다.
- 웹 브라우저에서 localhost:8080/hello-static.html로 접속
- 내장 톰캣 서버가 요청을 받는다.
- 스프링 컨테이너에서는 먼저 controller에서 hello-static이 있는지 찾아본다. (즉, controller가 먼저 우선순위를 갖는다)
- 그 다음에 컨테이너에서는 내부에 있는 resources로 접근한다.
MVC와 Template Engine
MVC; Model, View, Controller
과거에는 Controller와 View가 따로 분리되지 않았다. JSP에서는 View에 모든 걸 다 했었다. (Model1 방식)
이렇게 개발하면 특정 파일에 많은 코드를 올려놓게 되므로 유지보수를 하기 힘들다. 따라서 현재는 이러한 방식을 채택하지 않는다.
Controller
@Controller
public class HelloController {
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello-template";
}
}
외부에서 파라미터를 받는 내용이다.
localhost:8080/hello-mvc?name="파라미터 값"
Controller에서는 파라미터로 받은 값을 model로 view에 전달한다.
View
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>
View는 화면에 관련된 일만 하고, Business Logic 등 서버 뒷 단에 관련된 내용은 Controller에서 처리한다.
Controller에서는 필요한 logic을 처리하고 Model에 필요한 내용을 담아서 View로 전달해준다.
위의 내용을 그림으로 다시 확인해보자
- 웹 브라우저에서 localhost:8080/hello-mvc를 넘기면 내장 톰캣 서버를 거친다.
- 내장 톰캣 서버는 이를 스프링 컨테이너에 전달한다. 컨테이너는 helloController에 Mapping 되어 있는 것을 확인한다.
- return 값(hello-spring)과 model을 스프링에게 전달한다.
- 스프링은 viewResolver가 동작하게 한다. viewResolver는 view를 찾아서 템플릿 엔진과 연결하는 역할을 한다.
- 템플릿 엔진은 렌더링해서 변환한 HTML을 웹 브라우저에 반환해준다.
- MVC 정리
> 클라이언트가 요청하는 view를 찾는다 → 템플릿 엔진을 통해 화면을 렌더링 → 웹 브라우저에 리턴
API(Application Programming Interface)
정적 컨텐츠를 제외하면 두 가지 방식만 기억하면 된다.
1) html로 브라우저에 전달하냐
2) API로 데이터에 바로 전달하냐
Example 1.
// API 방식
@GetMapping("hello-string")
@ResponseBody // http에 있는 바디 파트를 의미. 바디 파트에 해당 데이터를 직접 넣겠다는 의미
public String helloString(@RequestParam("name") String name) {
return "Hello " + name;
}
@ResponseBody?
HTTP 통신 프로토콜(Application Layer)에는 Header와 Body 부분으로 이루어져있다. @ResponseBody 어노테이션은 HTTP의 응답 Body 부분에 데이터를 직접 넣어주는 역할을 한다.
API 방식을 쓰면 view를 통해서 데이터를 전달하는게 아니라 이 데이터 자체를 그대로 보낸다.
Example 2.
@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;
}
}
}
static 클래스를 만들면 클래스 안에서 또 클래스를 만들 수 있다.
위의 코드로 브라우저에서 확인하면
{"name" : "파라미터 Value" }
이런식으로 JSON 형태로 보내지게 된다. 최근 들어서는 모든 웹 개발은 JSON으로 데이터를 주고받는 추세이다.
JSON?
JavaScript Object Notation
> {키-값}의 쌍으로 이루어진 데이터 객체를 전달하기 위한 표준이다.
Getter, Setter.. Java Bean 규약이라고 한다. private으로 된 변수를 다른 파일에서 접근하기 힘들기 때문에 Getter, Setter 등을 통해 접근하게 한다. 또는 Property 접근 방식이라고도 한다.
- 웹 브라우저에서 /hello-api로 접근한다.
- 내장 톰캣 서버에서 /hello-api가 왔다고 스프링에게 알려준다.
- 스프링은 hello-api가 있음을 확인한다.
- 만약 @ResponseBody 어노테이션이 붙어있다면, HTTP 응답에 그대로 넘겨야한다고 판단한다.
- Example 1. 처럼 문자 형태의 리턴이었다면 그냥 HTTP 응답으로 넘겼을텐데 Example 2.의 경우처럼 객체를 리턴하는 경우도 있다.
- 객체를 리턴해야 한다면 JSON 형태로 데이터를 만들어서 HTTP 응답에 반환한다. (HttpMessageConverter의 역할)
(객체가 아니었다면 기존 MVC 형태처럼 viewResolver에게 전달했을 것이다.)
기본 문자처리: StringHttpMessageConverter
기본 객체처리: MappingJackson2HttpMessageConverter
(객체를 JSON으로 변환해주는 라이브러리: Jackson, GSON)
공부를 하다가 @Controller와 @RestController의 차이점에 대해서 직접 경험을 통해 구분하게 되었다.
일반적으로 Spring framework과 thymeleaf 엔진만 이용해서 @Controller로 view를 전달하는데에 무리가 없었다. 하지만 객체를 전달해야 하는 경우가 생겼다.
아무리 객체를 리턴해도 에러페이지만 발생했고 원인을 알기 힘들었다. 위에 API Example2에서 확인할 수 있듯이 @Controller에서 객체를 전달하려면 @ResponseBody와 함께 이용해야 한다.
하지만 @RestController를 이용하면 이 두 어노테이션의 역할을 모두 해준다.
Ref.
Request 할 때, 내가 받고 싶은 포맷이 있다. 이럴 땐 Accept 헤더를 이용한다. 그럼 그 포맷의 converter를 통해 요청된다.
TIP (Mac 기준)
Cmd + P: 파라미터 정보를 확인할 수 있다.
Cmd + shift + Enter: ;와 줄바꿈을 한 번에 끝내준다.
Cmd + N: Getter, Setter, Contructor 등 생성
출처: '스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술'
Java: 11
IDE : IntelliJ
'WEB Dev. > Spring Boot 입문' 카테고리의 다른 글
3. SpringBoot 입문 - 회원 관리 예제 백엔드 개발(2) - 회원 도메인과 리포지토리 만들기 (0) | 2021.04.29 |
---|---|
3. SpringBoot 입문 - 회원 관리 예제 백엔드 개발(1) - 비즈니스 요구사항 정리 (0) | 2021.03.14 |
1. SpringBoot 입문 - 프로젝트 환경설정_View 환경설정 & 빌드 및 실행(3) (0) | 2021.03.11 |
1. SpringBoot 입문 - 프로젝트 환경설정_라이브러리살펴보기(2) (0) | 2021.03.10 |
1. SpringBoot 입문 - 프로젝트 환경설정_프로젝트생성(1) (0) | 2021.02.24 |