Spring & SpringBoot
[Spring 입문] Spring 웹 개발 기초 (정적 컨텐츠, MVC와 템플릿 엔진, API)
유자바
2024. 7. 25. 15:03
스프링 웹은 정적 컨텐츠, MVC와 템플릿 엔진, API를 기본으로 개발된다.
각 개념이 무엇인지, 어떻게 개발하는지를 알아보도록 하자.
정적 컨텐츠
SpringBoot는 /static 디렉토리나 ServletContext의 루트에서 정적 컨텐츠를 가져와 전달하는 한다.
아래와 같이 static 디렉토리 아래 hello-static.html을 작성하고 localhost:8080/[파일명]으로 접근하면 정적 컨텐츠를 확인할 수 있다.
아래는 정적 컨텐츠가 사용자에게 나타나는 과정을 나타낸다.
- 웹 브라우저에서 hello-static.html를 찾으면
- 내장 톰켓 서버가 스프링에 전달한다.
- 스프링은 hello-static 관련 컨트롤러를 먼저 찾는다. (controller의 우선순위가 resources보다 높다는 걸 알 수 있다.)
- 스프링 부트가 resources/static/ 에서 hello-static.html을 찾고, 이를 찾으면 반환한다.
MVC와 템플릿 엔진
MVC: Model View Controller
기존에 작성해뒀던 HelloController.java에 아래 코드를 추가해준다.
아래는 localhost:8080/hello-mvc로 매핑되는 코드이고, templates의 hello-template.html을 웹에 띄워준다.
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam(value="name", required = false) String name, Model model){
model.addAttribute("name", name);
return "hello-template";
}
여기서 잠깐⚠️ RequestParam의 required
RequestParam의 required default값은 true로 parameter가 없을 시 에러를 발생한다.
required=false로 지정해주면 parameter가 없을 시 위와 같이 null로 표현된다.
- 웹 브라우저에서 localhost에서 hello-mvc를 넘기면
- 스프링부트가 띄워질 때 같이 나오는 내장 톰켓을 먼저 거치게 되는데, 톰켓이 스프링에게 hello-mvc가 왔다고 알려준다.
- 스프링은 helloController에 매핑되어 있는 것을 확인하고 해당 함수와 매핑해준다.
- 스프링의 viewResolver가 templates의 hello-template의 이름을 가진 html 파일을 찾아서 변환한 html을 웹 브라우저에 넘겨준다.
여기서 잠깐⚠️ static content와 템플릿 엔진
static content에서는 resource의 static 디렉토리에서 html 파일을 찾은 후 프로그래밍하지 않고 그대로 웹 브라우저로 넘겼지만,
템플릿 엔진은 templates 디렉토리에서 html 파일을 찾은 후 프로그래밍을 거쳐 웹 브라우저로 넘겼다.왼쪽은 hello-template.html 코드를 그대로 가져온 것이고, 오른쪽은 템플릿 엔진이 렌더링을 해서 변환을 한 html을 사용자에게 나타낸 결과이다.
API
@Controller
public class HelloController {
@GetMapping("hello-string")
@ResponseBody
public String helloString(@RequestParam("name") String name) {
return "hello " + name;
}
}
- @ResponseBody : HTTP body에 데이터를 직접 넣어줄 때 사용하는 annotation
@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;
}
}
위와 같이 객체를 반환했을 때는 json 형식의 데이터가 전달된다.
요즘에는 @ResponseBody annotation이 붙어 있는 것은 대부분 json 방식으로 데이터를 전달한다.
@ResponseBody의 사용 원리
- 처음엔 static content와 템플릿 엔진 방식과 같이 내장 톰켓 서버에서 스프링으로 hello-api가 호출되었음을 알려준다.
- 사용자가 원하는 경로(hello-api)를 스프링이 찾았는데 해당 함수에는 @ResponseBody annotation이 붙어 있는데 객체를 반환하기 때문에 HttpMessageConverter가 동작함 (기존에는 viewResolver가 동작)
- 기본 문자면, StringHttpMessageConverter가 동작
- 객체면, MappingJackson2HttpMessageConverter가 동작