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가 동작