[스프링] 스프링 웹 기반 기초

gyeol·2023년 6월 27일

스프링

목록 보기
2/50

스프링 강의 2일차 🤓

김영한님의 '스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술'을 듣고 적은 글입니다.

스프링 웹 개발 기초

웹 개발 방법에는 크게 3가지가 있다.

  • 정적 컨텐츠
  • MVC와 템플릿 엔진
  • API

➀ 정적 컨텐츠

정적 컨텐츠 :
서버에서 하는 것 없이 파일을 웹브라우저로 바로 내려준다.

먼저 resources > static 폴더 안에 hello-static.html 파일을 만들어준다.

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

이렇게 입력해준 뒤 url 창에 localhost:8080/hello-static.html을 입력해주면 아래와 같은 화면을 볼 수 있다.

코드를 확인해보면 IntelliJ에 적은 코드와 동일함을 확인할 수 있다.
스프링 부트는 정적 컨텐츠 기능 자동으로 제공한다. 정적 콘텐츠는 원하는 파일을 넣으면 확인 가능하지만 이 안에서 어떤 작업을 할 수는 없다.

정적 콘텐츠의 흐름을 보면, 내장 톰캣 서버가 받은 후 스프링 컨테이너에서 관련 컨트롤러 있는지 확인한 후 컨트롤러가 존재하지 않으면 resources 안에 있는지 확인한다. 이 과정에서 컨트롤러가 우선순위에 놓여있음을 알 수 있다. 이렇게 확인한 후 웹브라우저의 요청에 응답한다.

➁ MVC와 템플릿 엔진

MVC와 템플릿 엔진 :
디자인 패턴 중 하나로 사용자가 controller를 조작하면 controller는 model을 통해 데이터를 가져오고 그 정보를 바탕으로 시각적인 표현을 나타내는 View를 제어해 사용자에게 전달된다.

정적 컨텐츠는 파일을 그대로 웹브라우저에게 전달해주고, MVC와 템플릿 엔진은 서버에서 변형해서 전달해주는 방식에서 차이가 존재한다.

🔸 Model : 애플리케이션의 정보, 데이터를 나타낸다.

규칙 )

  • 사용자가 원하는 모든 데이터를 가지고 있어야 한다.
  • 뷰나 컨트롤러에 대해 어떤 정보도 알지 말아야 한다.
  • 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야 한다.

🔸 View : 사용자 인터페이스 요소를 나타낸다.

규칙 )

  • 모델이 가지고 있는 정보를 따로 저장해서는 안된다.
  • 모델이나 컨트롤러와 같이 다른 구성요소들을 몰라야 한다.
  • 변경이 일어나면 변경 통지에 대한 처리 방법을 구현해야만 한다.

🔸 Controller : 데이터와 사용자 인터페이스 요소들을 잇는 다리 역할을 한다.

규칙 )

  • 모델이나 뷰에 대해 알고 있어야 한다.
  • 모델이나 뷰의 변경을 모니터링 해야 한다.

일단, HelloController.java에 아래와 같은 코드를 추가해준다.

  @GetMapping("hello-mvc")
    public String helloMvc(@RequestParam("name")String name, Model model){
        model.addAttribute("name", name);
        return "hello-template";
    }

그리고 resources > templates 폴더 안에 hello-template.html 파일을 만들어준다.

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

여기에서 p태그 안에 존재하는 hello! empty는 파일을 경로로 복사해 url 창에 옮겨 적으면 확인할 수 있다.

위의 url 주소 창을 보면 Absolute Path copy 버튼을 눌러 복사된 모습이다. 이렇게 html을 그대로 쓰고 서버 없이 열어봐도 껍데기 볼 수 있는 이 방식은 tymeleaf의 장점이라고 한다.

다시 본론으로 돌아가, localhost:8080/hello-mvc?name=spring!!!!으로 적어주면 get 방식으로 지정된 name의 값이 출력된 것을 확인할 수 있다. 이 방식은 앞서 포스팅된 내용과 동일하다.

MVC와 템플릿 엔진의 흐름도 정적 콘텐츠와 비슷하다. helloController에 맵핑된 메소드 호출 뒤 리턴할때 hello-template 모델에는 키는 name, 값은 get방식으로 지정된 것으로 넣은 뒤(?name=spring!!!!) viewResolver로 넘겨준다. 이때 웹브라우저에 응답할때 html로 변환해 넘겨준다.(정적 콘텐츠 방식은 html로 변환해서 넘겨주지 않았다.)

➂ API

API :
JSON 구조 포맷으로 클라이언트에게 전달해준다. 뷰, 리엑트에도 사용. 서버끼리 통신할 때 사용(html로 통신 필요 없기에)

API는 일반 문자열을 전달받았을 때, 객체를 전달받았을 때 서로 다르게 처리된다.

  • 문자열
    먼저 HelloController.java 파일 안에 아래와 같이 일반 문자열을 전달받을 수 있도록하는 코드를 작성한다.
@Controller
public class HelloController {

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

이를 실행시키면,

앞에서 봤던 화면과 동일하게 출력됨을 알 수 있다. get 방식을 통해 name에 spring!!!!이 들어감을 확인할 수 있다.

  • 객체
    그 다음은 객체를 전달받았을 때의 결과를 확인해보겠다. 일단 이것도 위와 동일하게 HelloController.java 파일 안에 아래와 같은 코드를 작성한다.
@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;
        }
    }
}

Hello라는 정적 클래스를 만든 뒤 private로 변수를 선언해주었기에 이 값에 접근하기 위해 접근자/설정자를 만들어준다. 그 후 실행시켜보면,

이렇게 JSON 형식으로 출력되는 것을 확인해볼 수 있다. 이 페이지의 코드를 봐도 {"name":"spring!!!!"} 이 한줄만 덜렁 나와있다.
JSON은 키-값으로 이루어진 자료로 XML에 비해 심플하다. 초창기에는 XML과 경쟁을 했지만, 최근 추세로 JSON 방식으로 거의 통일되어 가고 있다.

앞의 코드들과 차이점이 존재하는데 혹시 찾으셨나요 ?

바로 @ResponseBody 어노테이션이 추가되었다는 것이다.

✔️ @ResponseBody :

http의 body 응답 부분에 직접 값을 넣어 주겠다는 의미. name에 spring이 들어가면 hello spring으로 바뀌며, 내가 요청한 클라이언트에 그대로 전달.

사용 원리를 살펴보면 톰캣 서버에서 스프링 컨테이너로 전달되고
⚠️@ResponseBody라는 어노테이션 있으면⚠️ http body에 문자 내용을 직접 반환한다.
이때 ViewResolver대신에 HttpMessageConverter(기본으로 등록되어 있음)가 동작된다.

객체이면 JsonConverter(MappingJackson2HttpMessageConverter)를 사용하고

일반 문자열이면 StringConverter(StringHttpMessageConverter)를

사용해 데이터를 만들어서 http 응답에 반환한다.

** Jackson : 객체를 JSON으로 바꿔주는 라이브러리. 스프링에 기본으로 탑재.

profile
공부 기록 공간 '◡'

0개의 댓글