Spring/[인프런] 스프링 입문 - 김영한

[Spring] 스프링 웹 개발 기초

송테이토 2022. 11. 19. 13:13

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

김영한님의 인프런 스프링 입문 - 코드로 배우는 스프링 부트 강의를 듣고 정리한 공부목적의 글입니다.

 

스프링을 웹 개발한다? 3가지 방법이 있다.

  • 정적 콘텐츠

→파일을 그대로 내려줌

  • MVC와 템플릿 엔진(가장 많이 함)

→템플릿엔진을 모델뷰 방식으로 쪼개서 렌더링이 된 html을 클라이언트에 전달

  • API

→ 객체를 반환한다. Json으로 바꿔서 반환을 해주는 것

뷰 없이 httpResponse에 값 넣어서 보여줌

1. 정적 컨텐츠

  • 정적 컨텐츠

→ 스프링은 기본적으로 정적컨텐츠를 제공한다.

<!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

정적 콘텐츠 | Static Content 란?

모든 사용자의 웹페이지에서 콘텐츠가 동일하게 유지되는 것을 뜻합니다.

웹사이트 소유자가 콘텐츠를 업데이트하게 되면,이 새 콘텐츠가 모든 사용자에게 동일하게 보입니다.정적 콘텐츠는 HTML , CSS , JavaScript , 이미지 , 비디오와 같은 파일이 포함됩니다



동적 콘텐츠 | Dynamic Content 란?

사용자의 웹페이지가 동일하게 보이지 않습니다.

위치, 디바이스, 시간, 사용자 프로필 설정에 따라사용자 정보 기반의 맞춤 페이지가 보이게 되는 것이죠. (쇼핑몰, SNS)


2. MVC와 템플릿 엔진

파일을 그대로 올려주는

뷰는 화면을 그리는데 모든 것에 집중

컨트롤러는 내부적인 로직을 처리하는데 집중

그래서 뷰와 컨트롤러는 쪼개는게 원칙이다.

그래야 유지보수도 쉽다,

controller/HelloContreoller.java

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model) {
        model.addAttribute("data", "hello!!");
        return "hello";
    }

    @GetMapping("hello-mvc")
    //RequestParam 피라미터값  문자열 "name" 을 모델에 담는다.
    public String helloMvc(@RequestParam("name") String name, Model model) {
        model.addAttribute("name", name); //a
        return "hello-template";
    }
}

resources/templates/hello-template.html

hello! empty





<p>태그안에 hello! empty 는 뭔가요? -> 타임리프에 장점, 그냥 파일 그대로 소스 열었을때 나옴

실행을 해보자! http://localhost:8080/hello-mvc?name=spring

왜 오류가 나올까?

아 위치가 잘못되었다. static 폴더가 아닌 템플릿 폴더에 넣어야한다.

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model) {
        model.addAttribute("data", "hello!!");
        return "hello";
    }

    @GetMapping("hello-mvc")
    //RequestParam 피라미터값  문자열 "name" 을 모델에 담는다.
    public String helloMvc(@RequestParam(value = "name", required = false) String name, Model model) {
        model.addAttribute("name", name);
        return "hello-template";
    }
}

required = false 값을 넘기지 않아도 됨

required = true 값을 필수로 넘겨야함 (기본이 true임

어떤 방식으로 작동되는가?

키는 name 값은 spring(내가 입력한 값)

return "hello-template";

에 의해 탐리프 템플릿 엔진 처리를 한다.

같은 파일을 찾아주세요~~~~ 요런 것이다.

3. API

→ Application Programming Interface(애플리케이션 프로그램 인터페이스)

응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {.
.
.
.(생략)

    @GetMapping("hello-string")
    @ResponseBody
    public String helloString(@RequestParam("name") String name) {
        return "hello " + name; // name에 길동 넣으면 -> hello 길동
    }
}

view 페이지가 아닌 helloworld  라는 문자열을 그대로 반환하고 싶다면, 해당 메소드 위에 @ResponseBody 를 추가한다.

우와! HTML 태그가 하나도 없다!!!!

템플릿 엔진과 다른 점! 그대로 데이터를 보여준다.!

데이터를 내놓아라 할때

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @GetMapping("hello-api")
    @ResponseBody
    public Hello helloApi(@RequestParam("name") String name) {
        Hello hello = new Hello();
        hello.setName(name); //빋은 name을
        return hello; //객체를 넘겨준다.
    }

    //class안에 class 또 사용 가능하다. HelloController.Hello
    static class Hello {
        private String name;//private기때문에 게터세터에 의해(자바빈표준규ㅇ약)

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

http://localhost:8080/hello-api?name=길동

소스보기를 해도 데이터 그대로 나온다.

이것은 JSON 이라는 방식이다

<aside> 🙆🏻

JSON (JavaScript Object Notation)

  • JavaScript Object Notation라는 의미의 축약어로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식
  • Javascript에서 객체를 만들 때 사용하는 표현식을 의미한다.
  • JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용한다.
  • JSON은 데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다.

JSON 특징

  • 서버와 클라이언트 간의 교류에서 일반적으로 많이 사용된다.
  • 자바스크립트 객체 표기법과 아주 유사하다.
  • 자바스크립트를 이용하여 JSON 형식의 문서를 쉽게 자바스크립트 객체로 변환할 수 있는 이점이 있다.
  • JSON 문서 형식은 자바스크립트 객체의 형식을 기반으로 만들어졌다.
  • 자바스크립트의 문법과 굉장히 유사하지만 텍스트 형식일 뿐이다.
  • 다른 프로그래밍 언어를 이용해서도 쉽게 만들 수 있다.
  • 특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링 할 수 있는 라이브러리를 제공한다.

XML vs JSON

데이터를 나타낼 수 있는 방식은 여러가지가 있지만, 대표적인 것이 XML이고, 이후 가장 많이 사용되는 것이 아마도 JSON일 것이다.

XML

  • 데이터 값 양쪽으로 태그가 있다.(HTML을 근본으로 했기에 태그라는 것이 없을 수가 없는데, 그 태그를 줄인다 해도 최소한 표현하려면 양쪽에 몇글자씩이 있어야 한다.)

JSON

  • 태그로 표현하기 보다는 중괄호({}) 같은 형식으로 하고, 값을 ','로 나열하기에 그 표현이 간단하다.

JSON 문법

{
  "employees": [
    {
      "name": "Surim",
      "lastName": "Son"
    },
    {
      "name": "Someone",
      "lastName": "Huh"
    },
    {
      "name": "Someone else",
      "lastName": "Kim"
    }
  ]
}
  • JSON 형식은 자바스크립트 객체와 마찬가지로 key / value가 존재할 수 있으며 key값이나 문자열은 항상 쌍따옴표를 이용하여 표기해야한다.
  • 객체, 배열 등의 표기를 사용할 수 있다.
  • 일반 자바스크립트의 객체처럼 원하는 만큼 중첩시켜서 사용할 수도 있다.
  • JSON형식에서는 nullnumberstringarrayobjectboolean을 사용할 수 있다.

JSON 형식

1. name-value형식의 쌍

  • 여러가지 언어들에서 object등으로 실현되었다.
  • { String key : String value }
{
  "firstName": "Kwon",
  "lastName": "YoungJae",
  "email": "kyoje11@gmail.com"
}

2. 값들의 순서화된 리스트 형식

  • 여러가지 언어들에서 배열(Array) 등으로 실현되었다.
  • [value1, value2, ...]
{
  "firstName": "Kwon",
  "lastName": "YoungJae",
  "email": "kyoje11@gmail.com",
  "hobby": ["puzzles","swimming"]
}

JSON의 문제점

AJAX 는 단순히 데이터만이 아니라 JavaScript 그 자체도 전달할 수 있다. 이 말은 JSON데이터라고 해서 받았는데 단순 데이터가 아니라 JavaScript가 될 수도 있고, 그게 실행 될 수 있다는 것이다. (데이터인 줄 알고 받았는데 악성 스크립트가 될 수 있다.)

위와 같은 이유로 받은 내용에서 순수하게 데이터만 추출하기 위한 JSON 관련 라이브러리를 따로 사용하기도 한다.

JSON이 가져올 수 있는 데이터

JSON으로 가져올 수 있는 데이터는 해당 자바스크립트가 로드된 서버의 데이터에 한정된다.

예를 들어, http://kwz.kr/json.js에서 불러올 수 있는 데이터는 kwz.kr 서버에 존재하는 것만 가능하다. (구글 데이터를 불러온다거나 네이버 데이터를 불러온다거나 할 수 없다.)

JSON은 단순히 데이터 포맷일 뿐이며 그 데이터를 불러오기 위해선 XMLHttpRequest()라는 JavaScript 함수를 사용해야 하는데 이 함수가 동일 서버에 대한 것만 지원하기 때문이다. ( JSONP 또는 프락시 역할을 하는 서버쪽 Script 파일로 가능하게도 할 수 있다.)

</aside>

키벨류로 이루어진 구조

키: 밸류

key는 name

value String name

@ResponseBody 를 사용

객체를 넘겨준다!

객체면 JsonConverter가 작동!

HTTP의 BODY에 문자 내용을 직접 반환 viewResolver 대신에 HttpMessageConverter 가 동작

  • 기본 문자처리: StringHttpMessageConverter

→문자는 그냥 넣어버리면 되는데

  • 기본 객체처리: MappingJackson2HttpMessageConverter

→ 아 객체가 왔네? 그러면 디폴트인 Json방식으로 http에 응답을 하겠다.

byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음

→내가 원하는대로 바꿀 수 있는데 실무에서 이거 그냥 그대로 쓴다.

손대지….말..아라……

실무에서 거의 손대지 않고 그대로 씀

이거 3개만 써도 크게 문제가 없다.

  • 정적 콘텐츠

→파일을 그대로 내려줌

  • MVC와 템플릿 엔진(가장 많이 함)

→템플릿엔진을 모델뷰 방식으로 쪼개서 렌더링이 된 html을 클라이언트에 전달

  • API

→ 객체를 반환한다. Json으로 바꿔서 반환을 해주는 것

뷰 없이 httpResponse에 값 넣어서 보여줌

1. 정적 컨텐츠

  • 정적 컨텐츠

→ 스프링은 기본적으로 정적컨텐츠를 제공한다.

<!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

정적 콘텐츠 | Static Content 란?

모든 사용자의 웹페이지에서 콘텐츠가 동일하게 유지되는 것을 뜻합니다.

웹사이트 소유자가 콘텐츠를 업데이트하게 되면,이 새 콘텐츠가 모든 사용자에게 동일하게 보입니다.정적 콘텐츠는 HTML , CSS , JavaScript , 이미지 , 비디오와 같은 파일이 포함됩니다



동적 콘텐츠 | Dynamic Content 란?

사용자의 웹페이지가 동일하게 보이지 않습니다.

위치, 디바이스, 시간, 사용자 프로필 설정에 따라사용자 정보 기반의 맞춤 페이지가 보이게 되는 것이죠. (쇼핑몰, SNS)


2. MVC와 템플릿 엔진

파일을 그대로 올려주는

뷰는 화면을 그리는데 모든 것에 집중

컨트롤러는 내부적인 로직을 처리하는데 집중

그래서 뷰와 컨트롤러는 쪼개는게 원칙이다.

그래야 유지보수도 쉽다,

controller/HelloContreoller.java

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model) {
        model.addAttribute("data", "hello!!");
        return "hello";
    }

    @GetMapping("hello-mvc")
    //RequestParam 피라미터값  문자열 "name" 을 모델에 담는다.
    public String helloMvc(@RequestParam("name") String name, Model model) {
        model.addAttribute("name", name); //a
        return "hello-template";
    }
}

resources/templates/hello-template.html

hello! empty





<p>태그안에 hello! empty 는 뭔가요? -> 타임리프에 장점, 그냥 파일 그대로 소스 열었을때 나옴

실행을 해보자! http://localhost:8080/hello-mvc?name=spring

왜 오류가 나올까?

아 위치가 잘못되었다. static 폴더가 아닌 템플릿 폴더에 넣어야한다.

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model) {
        model.addAttribute("data", "hello!!");
        return "hello";
    }

    @GetMapping("hello-mvc")
    //RequestParam 피라미터값  문자열 "name" 을 모델에 담는다.
    public String helloMvc(@RequestParam(value = "name", required = false) String name, Model model) {
        model.addAttribute("name", name);
        return "hello-template";
    }
}

required = false 값을 넘기지 않아도 됨

required = true 값을 필수로 넘겨야함 (기본이 true임

어떤 방식으로 작동되는가?

키는 name 값은 spring(내가 입력한 값)

return "hello-template";

에 의해 탐리프 템플릿 엔진 처리를 한다.

같은 파일을 찾아주세요~~~~ 요런 것이다.

3. API

→ Application Programming Interface(애플리케이션 프로그램 인터페이스)

응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {.
.
.
.(생략)

    @GetMapping("hello-string")
    @ResponseBody
    public String helloString(@RequestParam("name") String name) {
        return "hello " + name; // name에 길동 넣으면 -> hello 길동
    }
}

view 페이지가 아닌 helloworld  라는 문자열을 그대로 반환하고 싶다면, 해당 메소드 위에 @ResponseBody 를 추가한다.

우와! HTML 태그가 하나도 없다!!!!

템플릿 엔진과 다른 점! 그대로 데이터를 보여준다.!

데이터를 내놓아라 할때

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @GetMapping("hello-api")
    @ResponseBody
    public Hello helloApi(@RequestParam("name") String name) {
        Hello hello = new Hello();
        hello.setName(name); //빋은 name을
        return hello; //객체를 넘겨준다.
    }

    //class안에 class 또 사용 가능하다. HelloController.Hello
    static class Hello {
        private String name;//private기때문에 게터세터에 의해(자바빈표준규ㅇ약)

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

http://localhost:8080/hello-api?name=길동

소스보기를 해도 데이터 그대로 나온다.

이것은 JSON 이라는 방식이다

<aside> 🙆🏻

JSON (JavaScript Object Notation)

  • JavaScript Object Notation라는 의미의 축약어로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식
  • Javascript에서 객체를 만들 때 사용하는 표현식을 의미한다.
  • JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용한다.
  • JSON은 데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다.

JSON 특징

  • 서버와 클라이언트 간의 교류에서 일반적으로 많이 사용된다.
  • 자바스크립트 객체 표기법과 아주 유사하다.
  • 자바스크립트를 이용하여 JSON 형식의 문서를 쉽게 자바스크립트 객체로 변환할 수 있는 이점이 있다.
  • JSON 문서 형식은 자바스크립트 객체의 형식을 기반으로 만들어졌다.
  • 자바스크립트의 문법과 굉장히 유사하지만 텍스트 형식일 뿐이다.
  • 다른 프로그래밍 언어를 이용해서도 쉽게 만들 수 있다.
  • 특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링 할 수 있는 라이브러리를 제공한다.

XML vs JSON

데이터를 나타낼 수 있는 방식은 여러가지가 있지만, 대표적인 것이 XML이고, 이후 가장 많이 사용되는 것이 아마도 JSON일 것이다.

XML

  • 데이터 값 양쪽으로 태그가 있다.(HTML을 근본으로 했기에 태그라는 것이 없을 수가 없는데, 그 태그를 줄인다 해도 최소한 표현하려면 양쪽에 몇글자씩이 있어야 한다.)

JSON

  • 태그로 표현하기 보다는 중괄호({}) 같은 형식으로 하고, 값을 ','로 나열하기에 그 표현이 간단하다.

JSON 문법

{
  "employees": [
    {
      "name": "Surim",
      "lastName": "Son"
    },
    {
      "name": "Someone",
      "lastName": "Huh"
    },
    {
      "name": "Someone else",
      "lastName": "Kim"
    }
  ]
}
  • JSON 형식은 자바스크립트 객체와 마찬가지로 key / value가 존재할 수 있으며 key값이나 문자열은 항상 쌍따옴표를 이용하여 표기해야한다.
  • 객체, 배열 등의 표기를 사용할 수 있다.
  • 일반 자바스크립트의 객체처럼 원하는 만큼 중첩시켜서 사용할 수도 있다.
  • JSON형식에서는 nullnumberstringarrayobjectboolean을 사용할 수 있다.

JSON 형식

1. name-value형식의 쌍

  • 여러가지 언어들에서 object등으로 실현되었다.
  • { String key : String value }
{
  "firstName": "Kwon",
  "lastName": "YoungJae",
  "email": "kyoje11@gmail.com"
}

2. 값들의 순서화된 리스트 형식

  • 여러가지 언어들에서 배열(Array) 등으로 실현되었다.
  • [value1, value2, ...]
{
  "firstName": "Kwon",
  "lastName": "YoungJae",
  "email": "kyoje11@gmail.com",
  "hobby": ["puzzles","swimming"]
}

JSON의 문제점

AJAX 는 단순히 데이터만이 아니라 JavaScript 그 자체도 전달할 수 있다. 이 말은 JSON데이터라고 해서 받았는데 단순 데이터가 아니라 JavaScript가 될 수도 있고, 그게 실행 될 수 있다는 것이다. (데이터인 줄 알고 받았는데 악성 스크립트가 될 수 있다.)

위와 같은 이유로 받은 내용에서 순수하게 데이터만 추출하기 위한 JSON 관련 라이브러리를 따로 사용하기도 한다.

JSON이 가져올 수 있는 데이터

JSON으로 가져올 수 있는 데이터는 해당 자바스크립트가 로드된 서버의 데이터에 한정된다.

예를 들어, http://kwz.kr/json.js에서 불러올 수 있는 데이터는 kwz.kr 서버에 존재하는 것만 가능하다. (구글 데이터를 불러온다거나 네이버 데이터를 불러온다거나 할 수 없다.)

JSON은 단순히 데이터 포맷일 뿐이며 그 데이터를 불러오기 위해선 XMLHttpRequest()라는 JavaScript 함수를 사용해야 하는데 이 함수가 동일 서버에 대한 것만 지원하기 때문이다. ( JSONP 또는 프락시 역할을 하는 서버쪽 Script 파일로 가능하게도 할 수 있다.)

</aside>

키벨류로 이루어진 구조

키: 밸류

key는 name

value String name

@ResponseBody 를 사용

객체를 넘겨준다!

객체면 JsonConverter가 작동!

HTTP의 BODY에 문자 내용을 직접 반환 viewResolver 대신에 HttpMessageConverter 가 동작

  • 기본 문자처리: StringHttpMessageConverter

→문자는 그냥 넣어버리면 되는데

  • 기본 객체처리: MappingJackson2HttpMessageConverter

→ 아 객체가 왔네? 그러면 디폴트인 Json방식으로 http에 응답을 하겠다.

byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음

→내가 원하는대로 바꿀 수 있는데 실무에서 이거 그냥 그대로 쓴다.

손대지….말..아라……

실무에서 거의 손대지 않고 그대로 씀

이거 3개만 써도 크게 문제가 없다.