콘텐츠로 건너뛰기

Spring Boot 기초 공부 – IoC,DI,SpringBean,REST API 예제

💡 웹이란, 우리 모두를 위한 정보 공유의 장.

섹션2 : 웹이 뭐길래

인터넷 안에서 웹 공간을 찾아가려면!

HTTP (Hyper Text Transfer Protocol)

  • 받는 사람, 인사, 말, 끝인사, 보내는 사람 → 형식을 맞추어서!
  • 예시) https://www.naver.com
    • https의 s는 secure.

섹션3: 백엔드 개발자는 API를 만듭니다.

API란

API (Application Programming Interface)

  • 시스템과 유저 사이에서 일정한 ‘틀’을 제공하여 필요한 정보만 받을 수 있도록 하는 시스템.

REST API

REST API ( Representational State Transfer API)

  • 백엔드 개발자가 만들어야 할 것.
  • REST API가 생겨나게 된 배경은
    • 고전적인 API는 화면을 포함한 모든 데이터를 틀에 맞지 않게 작성하여 전달. → 성능이 느리다.
    • 틀과 규칙을 맞추고, 필요한 데이터만 전달하도록 진화. → REST API의 정의. 가볍고 빠르다.
    • REST’ful’ ? : 규칙을 잘 지킨~ 이라는 느낌.

URL

웹에서 요청을 하는 방법

= API를 사용하는 방법

= API를 호출하는 방법

  • 데이터를 가져오려면 JAVA로 메서드를 호출해야하는데, 이걸 어떻게 하는가?
    • URL을 호출함으로서 사용한다.

REST API에 맞는 HTTP

HTTP 틀에 잘 맞추려면

  1. URL : 이 API의 이 기능을 호출하고 싶어!
  2. 목적 : 조회, 등록, 수정 etc..
  3. 데이터 : body에 담아서.

그 외에 여러가지가 있지만 기본은 위 세가지.


섹션4. Hello Spring

스프링 프레임워크란?

  • 개발자 지향적인 기술
  • 웹을 만들기 위해 필요한 모든 것이 있는 프레임워크.

라이브러리 vs 프레임워크

  • 라이브러리 : 도서관.
    • 쉽게 풀이 : 내가 필요한 걸 직접 찾아서 하나하나 찾아 쓴다.
    • ‘소프트웨어를 개발할 때 컴퓨터 프로그램이 사용하는 비휘발성 자원의 모음’ 이라는 뜻.
  • 프레임워크 : 틀 안에서 다 해결됨.
    • 쉽게 풀이 : 이 안에 있는 것 중에서 골라서 쓴다.
    • ‘일정한 틀과 규약을 가지고 일하다’ 라는 뜻.
    • 모든 기능을 이 안에서 해결하기 때문에 인수인계가 쉬우며, 팀 단위 개발을 할 때도 중구난방이 되지 않을 수 있다.

스프링 프레임워크 안에 이렇게 많이 들어있다고?

  • Spring framework로 모든 작업을 할 수 있지만, 최근 추세가 frontend는 별개의 프레임워크(ex. React) 로 구현을 하기 때문에 Spring은 Rest API를 만드는 프레임워크로 자리를 잡게 됨.
  • Spring 안에는..
    • 데이터베이스 접근
    • web쪽 기능
    • AOP
    • Test기능
    • Core 기능
  • 백엔드 개발에 화면은 필수가 아니다.

스프링 부트란?

스프링을 직접 다루기 위해서는 설정할 게 많다. 설정을 쉽게 하기 위해 사용하는 것이 Spring Boot.

스프링 부트는..

  • 웹 서버 + 웹 어플리케이션 서버가 포함되어있음.
  • 개발자가 로직에 더 집중할 수 있도록 해준다.

섹션5. SpringBoot

💡 실습 환경IDE는 IntelliJ로 진행한다. Community버전은 무료이며, jetbrain toolbox로 설치하는 것이 권장된다. (업데이트 때문에)

Project는 Gradle-Groovy, Language는 Java, Boot 버전은 2.7, Java 1.8, Packaging은 Jar, Dependencies는 Spring Web 으로 사용한다.

start.spring.io 설명 및 프로젝트 다운로드

  • spring initializr에서 기반을 미리 다 만들어줘서, 빠르게 개발을 시작할 수 있다.
  • 빌드 도구
    • Ant → Maven → Gradle
      • Gradle이 좀 더 빠르고, 간결.
      • Gradle에도 사용하는 언어에 따라 두 가지로 나뉘는데
        • Groovy : 주로 많이 사용. Gradle만을 위해 사용하는 언어로 쉽게 사용 가능.
        • Kotline
  • 언어 선택
    • Java
    • Kotline
    • Groovy
  • Spring Boot
    • 여러가지 버전이 있지만, 번호만 적혀있는 Stable 버전을 사용하는 것을 권장.
      • jdk 버전 8, 11 사용할 경우 2.x 사용 → 지원기간 종료로 지원 X
      • jdk 17 이상일 경우 3.x 사용
  • Project Metadata
    • 프로젝트명, 패키지명, JDK버전 등 내용 작성.
      • Artifact : 프로젝트명
      • Packaging
        • Jar : 웹서버, WAS까지 한 번에 압축
        • War : 웹 제외하고 압축
  • Dependencies
    • 사용을 하는 것들.
    • REST API를 만들기 위해서는 Spring Web Dependency는 필수.
    • 나중에 추가도 가능.

프로젝트 구조 살펴보기

💡 IntelliJ에서 Project open 시에는 폴더 내의 build.gradle 파일을 열어야 한다.

💡 처음 Open할 때는 이것저것 모두 받아오기 때문에 느리다. 좌측 하단의 Build에서 Build Successful 문구를 확인하자.

  • src
    • 실질적인 로직을 짜는 곳은 src > main > java
    • 소스 코드 외의 것들 src > resources
    • TDD : Test Driven Development
      • 테스트를 기반으로 구현하는 개발방법.
      • src > test 폴더 제공을 하고 있음.
  • build.gradle
    • gradle이 빌드를 할 때 사용하는 파일.
    • groovy로 작성되어있음.
  • gradlew.bat
    • 이 프로그램을 패키징할 때 사용함.
    • window는 bat, mac은 다른걸 사용.
  • External Libraries
    • Gradle이 다운받은 라이브러리들 모음.

IoC, DI

스프링의 주요 개념(Core)

  • IoC
  • DI
  • Container
  • Spring Bean

IOC

: 제어의 역전 (Inversion of Contorl)

  • inverse : 정반대로 뒤집힌다. (갖고있다 → 가지고있지 않다) control : 제어 “프로그램의 흐름”
  • = 프로그램의 흐름을 제어하는 주체가 정반대로 뒤집힌다. = 객체의 흐름을 제어하는 주체가 정반대로 뒤집힌다. (객체의 생성, 사용, …라이프사이클)
  • 원래 객체생성은 개발자가 코드로 직접 생성하여 사용하였으나, 이를 spring이 대신해주는 것을 의미한다.

DI

: 의존성 주입 (Dependency Injection)

  • 의존한다 = 사용한다.
  • 객체를 사용한다. = 객체의 메소드, 필드를 사용한다. → 객체의 생성부터 해야한다(IoC).
  • 내가 직접 객체 생성을 해서 쓰는게 아니라 주입을 당해서 사용한다. IoC가 생성한 객체를 사용하도록 주입해달라고 요청.

Container

: 담아두는 공간, 박스

  • 스프링이 객체를 생성해서 관리를 해야하는데, 이 객체를 담아두는 게 Container.
  • IoC를 위한 컨테이너, DI에 사용하는 컨테이너 등으로 표현하기도 하지만, 최근에는 DI컨테이너라고 한다.

Spring Bean

  • 스프링(이 컨테이너에 담아놓고 관리하는) 객체

스프링 MVC: Controller – Service – Repository

Spring MVC

  • Model :
    • 데이터 처리(연산), 로직
    • 데이터를 가지고 연산을 하려면, 데이터베이스와 소통 필요
    • (계층, 클래스) Service / Repository
  • // View : 화면
  • Controller :
    • Model – View 중간 매개체(기존)
    • Model – 사용자 중간 매개체(최근)

💡 REST API 환경을 구성한다고 했을 때, Spring에서 화면을 구현하는 경우는 드물기 때문에 View가 잘 사용되지 않는다. 그래서 위에서 View는 다루지 않고, Controller에서도 view가 아닌 사용자(Client)로 변경됨.

프로젝트 구동 시켜보기

  • 가장 처음 확인해야 하는 것은 main method가 정상적으로 기동하는지 이다.
  • 상단의 start버튼 클릭하여 기동 테스트를 하고, http://localhost:8080으로 접속 테스트 진행
  • 기동 로그 : 정상 기동됨을 확인.
오후 1:26:16: Executing ':com.example.demo.DemoApplication.main()'...

> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE

> Task :com.example.demo.DemoApplication.main()

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v2.7.17)

2024-08-21 13:26:19.507  INFO 16432 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication using Java 1.8.0_202 on P94101681-003 with PID 16432 (D:\demo\build\classes\java\main started by jsm5125 in D:\demo)
2024-08-21 13:26:19.511  INFO 16432 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to 1 default profile: "default"
2024-08-21 13:26:20.533  INFO 16432 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-08-21 13:26:20.545  INFO 16432 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-08-21 13:26:20.545  INFO 16432 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.82]
2024-08-21 13:26:20.717  INFO 16432 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-08-21 13:26:20.717  INFO 16432 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1147 ms
2024-08-21 13:26:21.093  INFO 16432 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2024-08-21 13:26:21.104  INFO 16432 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.938 seconds (JVM running for 2.609)

브라우저 결과 : 아직 아무것도 안했기 때문에 안나오는게 맞음.

Controller, Service, Repository 클래스만 만들어보기

  • new > Java Class로 클래스 생성

자바 어노테이션

  • 어노테이션을 기재함으로써, 의도하지 않은 실수를 방지할 수 있다.
  • 그 외에도 여러가지 기능들이 있기 때문에 Spring에서 주요한 역할을 한다.
  • 아래 예제는 Override 환경에서 오탈자가 발생했을 때 @Override annotaion이 해당 내용을 확인해주는 내용이다.

패키지 구조, 이름 생각해보기 + Controller부터 만들기

구현 예제 : 상품 등록, 조회 API 프로젝트

  • 화면 없이, Spring을 이용한 Backend API.

DDD : Domain Driven Development (도메인 단위로)

  • 상품 등록, 상품 조회 라는 기능에서 공통된 “상품”이라는 도메인을 사용
  • new > package로 도메인명으로 패키지 생성

유지보수를 위해, 모듈화를 진행 (product의 controller, order의 controller 등)

  • Refactor > Rename 하여 classfile의 이름을 변경
//controller

package com.example.demo.product;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

//Controller annotation 설정
//ResponseBody는 REST API 의 틀에 맞게 "body"에 넣어 보내줘야함. 이 어노테이션이 REST API로 인식하게 해주어 정상적으로 데이터가 표출된다.
@Controller
@ResponseBody
public class ProductController {
    // "사용자(화면)" 요청을 던지면 그걸 받아서
    // 요청에 맞는 메소드를 실행시킵니다.
    // 그 안에서 그에 맞는 로직을 수행할 수 있도록 서비스한테 시킴.

    //handler = 요청에 따른 메소드 호출.

    //상품 조회
    //()안의 요청이 들어오고 method가 일치한다면 이 메서드를 실행하도록 한다.
    //value 내부 값이 http://localhost:8080인 경우 생략 가능.
    @RequestMapping(value="", method= RequestMethod.GET)
    public String findProduct(){
        return "Notebook";
    }
}

너에게 요청하는 목적, HTTP method

  1. 조회 : GET
  2. 등록(생성) : POST
  3. 수정 : 전체 – PUT 부분 – PATCH
  4. 삭제 : DELETE

Service 추가해보기 (Service – Repository 틀 만들기)

컨트롤러는 요청을 받아 서비스한테 일을 시키고

서비스는 일을 처리해서 결과를 반환하도록 변경.

//ProductController

package com.example.demo.product;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody
public class ProductController{
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String findProduct(){
        ProductService productService = new ProductService();
        return productService.findProduct();
    }
}
//Product Service

package com.example.demo.product;

import org.springframework.stereotype.Service;

@Service
public class ProductService {
    public String findProduct(){
        return "Notebook!";
    }
}


섹션6. 스프링 코어

스프링 IoC & 스프링 빈 등록 방법 2가지 & DI

1 . 우리가 직접 객체를 생성하는 대신, 스프링이 객체를 생성 등 관리하라고 요청

  • = 스프링 빈으로 등록해줘.
  • 등록 방법
    1. @Component
    2. @Configuration + @Bean

💡 *Service 어노테이션에는 Component가 이미 등록되어있다 (Cntl+ 서비스 어노테이션 클릭으로 확인 가능)

  1. 스프링에게 컨테이너에 서비스 빈을 달라고 요청. (DI)
    • = 등록된 빈을 사용하게 주입해줘
    • 등록방법
      • Controller에 Service Class의 필드를 생성하고 @Autowired 어노테이션을 추가.
package com.example.demo.product;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody
public class ProductController{
    @Autowired
    private ProductService productService;

    @RequestMapping(value = "", method = RequestMethod.GET)
    public String findProduct(){
        //ProductService productService = new ProductService();
        return productService.findProduct();
    }
}

@Component를 달아두면 생기는 일

  • Spring이 Spring Bean으로 만들어서 써야함을 인식하는 태그
    • Service뿐만 아니라 Controller에도 들어가있음.
  • SpringBootApplication 어노테이션을 확인해보면 컴포넌트를 찾아주는 역할을 수행함을 확인할 수 있음.

Repository는 Map으로

서비스는 연산,로직 담당.

Repository가 데이터를 꺼내오는 역할.

  • @Repository 어노테이션 작성.

💡 DB는 현재 연결하기 번잡스러움으로 Map을 통해 간략히 만들어만 두고, Return은 String으로 처리한다.

//Service

package com.example.demo.product;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public String findProduct(){
        return productRepository.findProduct();
    }
}
//Repository

package com.example.demo.product;

import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.Map;

@Repository
public class ProductRepository {
    private Map<Integer, String> db = new HashMap<>();
    private int id = 1;

    public String findProduct(){
        return "NoteBook";
    }
}

DI 3가지 방법 – 추가적으로 알아보기 필요.

  1. 필드로 주입 받음
    • 필드 위에 @Autowired
    • 테스트하기에 어려움이 있음.
  2. Setter로 주입 받음
    • 최근에는 잘 사용되지 않음.
    • setter메서드 위에 @Autowired.
    • 사용 안하는 이유 : public으로 열려있어 누구나 접근이 가능하기 때문에 사용하지 않음.
  3. 생성자로 주입 받음
    • 생성자 위에 @Autowired.
    • 테스트하기에 좋으므로 권장됨.
//ProductService 생성자로 주입받는 코드

package com.example.demo.product;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    private ProductRepository productRepository;

    @Autowired
    ProductService(ProductRepository productRepository){
        this.productRepository = productRepository;
    }

    public String findProduct(){
        return productRepository.findProduct();
    }
}

섹션7. 상품 등록해보기

“Notebook” 등록하기.

  • Repository에 save 메서드 생성하여 db에 데이터 넣기.
@Repository
public class ProductRepository {
    private Map<Integer, String> db = new HashMap<>();
    private int id = 1;

    public String findProduct(){
        return db.get(1);
    }

    public void save() {
        db.put(id++,"NoteBook");
    }
}
@Service
public class ProductService {

    private ProductRepository productRepository;

    @Autowired
    ProductService(ProductRepository productRepository){
        this.productRepository = productRepository;
    }

    public String findProduct(){
        return productRepository.findProduct();
    }

    public void saveProduct(){
        productRepository.save();
    }
}
  • Controller에서 setProductService 메서드 생성하여 ProductService.saveProduct()호출
@Controller
@ResponseBody
public class ProductController{
    @Autowired
    private ProductService productService;

    @RequestMapping(value = "", method = RequestMethod.GET)
    public String findProduct(){
        return productService.findProduct();
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public void setProductService(){
        productService.saveProduct();
    }

REST API URL 규칙

localhost:8080

메서드가 get, post로 다르므로 product_get 등을 사용하지 않아도 된다.

테스트 방법

테스트 수행 방법

  • 간단한 테스트를 수행하기 위해서는 로그를 남기는데, System.out.println() 은 간단하게 사용하긴 좋지만 권장되진 않는 방법.
  • 어.. IntelliJ에서 Sysout하면 안되네 어떻게하지?
    • → 어휴.. return 아래에다 하니까 안되지!

Hello Postman

post 테스트를 위해 postman을 설치.

  • desktop 버전을 권장. (온라인 버전은 안되는 기능이 좀 많음)
  • 사용 방식은 method와 url을 입력하여 테스팅.
    • Status code가 200이면 성공.
    • post 시도 후 get 시도하였을 때 정상적으로 데이터가 “Notebook” 으로 찍히는 것을 확인.

섹션 9. 원하는 상품을 가져오기

요청을 받을 때 데이터도 같이 받는 방법

  1. HttpServletRequest
  2. @RequestParam
    • http://localhost:8080/products? → requestparam(쿼리스트링)
      • name=~~~~
      • 개인정보는 입력받지 않게! URL에 개인정보 돌아다니는건 좀..
      • RequestParam을 사용하면, url에서 꼭 name=“” 으로 하지 않고 name=~~ (따옴표 없이) 해도 알아서 지정한 타입(현재는 String)으로 받는다.
  3. @RequestBody
  4. @ModelAttribute
  5. @PathVariable
  • code
    • RequestParam을 이용하여 Controller → Service → Repository로 데이터를 이동하고 내부 로직을 수정하여 가장 최근에 입력한 내용을 가져오도록 수정.
    • Repository에서, 강의 그대로 진행하면 db의 첫번째 들어간 데이터만 반환하게 되므로, 아래와 같이 로직을 수정함. (이후 과정에서 재수정함)
//Controller

@Controller
@ResponseBody
public class ProductController{
    @Autowired
    private ProductService productService;

    @RequestMapping(value = "/products", method = RequestMethod.GET)
    public String findProduct(){
        return productService.findProduct();
    }

    @RequestMapping(value = "/products", method = RequestMethod.POST)
    public void setProductService(@RequestParam(value="name") String productName){
        //http://localhost:8080/products?name=~~ -> productName
        //받아온 데이터를 서비스에 전달
        productService.saveProduct(productName);
    }
}
//Service

@Service
public class ProductService {

    private ProductRepository productRepository;

    @Autowired
    ProductService(ProductRepository productRepository){
        this.productRepository = productRepository;
    }

    public String findProduct(){
        return productRepository.findProduct();
    }

    public void saveProduct(String productName){
        productRepository.save(productName);
    }
}
//Repository

@Repository
public class ProductRepository {
    private Map<Integer, String> db = new HashMap<>();
    private int id = 0;

    public String findProduct(){
        return db.get(id);
    }

    public void save(String productName) {
        db.put(++id,productName);
    }
}

테스트 방식

  • postman의 POST를 사용하여 macbook을 등록
  • postman의 GET을 사용하여 macbook을 가져오기

@PathVariable로 조회하고싶은 상품 id를 직접 받아보기

  • 언제 무엇을 사용하는가?
    • 입력을 받는 값을 사용 할 때 = @RequestParam
    • 정해져 있는 시스템 값의 조회를 하고싶다면 = @PathVariable
  • url
  • code
    • PathVariable을 사용하여 Controller → Service → Repository를 거쳐 데이터를 정상적으로 조회할 수 있도록 작성한다.
    • @RequestMapping에서 받을 때부터 url에 {id}를 넣어주어야 정상적으로 인식하여 들어온다.
//Controller

@Controller
@ResponseBody
public class ProductController{
    @Autowired
    private ProductService productService;

    @RequestMapping(value = "/products/{id}", method = RequestMethod.GET)
    public String findProduct(@PathVariable("id") int id){
        System.out.println(id);
        return productService.findProduct(id);
    }

    @RequestMapping(value = "/products", method = RequestMethod.POST)
    public void setProductService(@RequestParam(value="name") String productName){
        //http://localhost:8080/products?name=~~ -> productName
        //받아온 데이터를 서비스에 전달
        productService.saveProduct(productName);
    }
}
//Service

@Service
public class ProductService {

    private ProductRepository productRepository;

    @Autowired
    ProductService(ProductRepository productRepository){
        this.productRepository = productRepository;
    }

    public String findProduct(int id){
        return productRepository.findProduct(id);
    }

    public void saveProduct(String productName){
        productRepository.save(productName);
    }
}
//Reposirtory

@Repository
public class ProductRepository {
    private Map<Integer, String> db = new HashMap<>();
    private int id = 1;

    public String findProduct(int idx){
        return db.get(idx);
    }

    public void save(String productName) {
        db.put(id++,productName);
    }
}

섹션 10. 상품에 데이터를 더 넣기

상품 객체 만들어서 @RequestBody로 받아보기

  • 객체(class)를 만들어 세트로 움직이기.
    • 각 properties가 private이기 때문에, 다른 클래스의 메서드에서 가져와 사용할 수 없음. 이 때 getter, setter를 사용함.
      • 생성 방법은 클래스 내부에서 마우스 우클릭 → generate → getter, setter
public class Product {
    private String name;
    private int price;
    private String description;
    
    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
//controller

@Controller
@ResponseBody
public class ProductController{
    @Autowired
    private ProductService productService;

    @RequestMapping(value = "/products/{id}", method = RequestMethod.GET)
    public String findProduct(@PathVariable("id") int id){
        System.out.println(id);
        return productService.findProduct(id);
    }

    @RequestMapping(value = "/products", method = RequestMethod.POST)
    public void setProductService(@RequestBody Product product){
        productService.saveProduct(productName);
    }
}

Json

: Java Script Object Notation.(자바 스크립트 객체 형태)

key-value 형태로 기재됨.

var product = {
	name: "handcream",
	price: 15000
}

product.name
product.price
형식으로 사용.

💡 @RequestBody에서 알아서 매핑해줌. 자바스크립트에서 건너오는 객체를 이름만 맞다면 필드값을 하나하나 맞춰서 데이터를 담아줌. → Message Converter로 인해서 이 기능이 가능. 추가적인 정보가 필요하면 찾아보기.

postman으로 테스트해보기

  • RequestBody로 받으려면 postman에서 Body > raw에서 Json 형식으로 데이터를 보내줘야함
{
    "name":"hihi",
    "price":150000,
    "description":"hi im hihi"
}

Repository 고도화하기

  • 조회 시에 해당 데이터들을 모두 가져오게 하기 위해서, return type을 Product로 변경.
//Controller

@Controller
@ResponseBody
public class ProductController{
    @Autowired
    private ProductService productService;

    @RequestMapping(value = "/products/{id}", method = RequestMethod.GET)
    public Product findProduct(@PathVariable("id") int id){
        System.out.println(id);
        //json형태로 반환됨.
        return productService.findProduct(id);
    }

    @RequestMapping(value = "/products", method = RequestMethod.POST)
    public void setProductService(@RequestBody Product product){
        productService.saveProduct(product);
    }
}
//Service

@Service
public class ProductService {

    private ProductRepository productRepository;

    @Autowired
    ProductService(ProductRepository productRepository){
        this.productRepository = productRepository;
    }

    public Product findProduct(int id){
        return productRepository.findProduct(id);
    }

    public void saveProduct(Product productName){
        productRepository.save(productName);
    }
}
//Repository

@Repository
public class ProductRepository {
    private Map<Integer, Product> db = new HashMap<>();
    private int id = 1;

    public Product findProduct(int idx){
        return db.get(idx);
    }

    public void save(Product productName) {
        db.put(id++, productName);
    }
}
  • Controller에서 Return까지 Product로 하면, 브라우저에서는 JSON 형식으로 받게 된다.

섹션 11. 앞으로..

  • 상품 수정, 삭제
  • @Configuration+ @Bean 조합으로 스프링 빈 등록 해보기.
  • Entity vs DTO → DTO를 사용하는 이유
  • DB연결 (JPA)
  • AOP

후기

사실 Java 와 Spring 모두 배웠었지만.. 그 때 당시엔 전혀 이해가 안됐었는데, 이 강의를 듣고 가닥이 잡히는 느낌이다.

이래서 돈 주고 비싼 강의를 듣는거구나 싶다. 이번에 이렇게 시작하게됐으니 완전히 전문적인 백엔드 까진 아니더라도 스타트업 초기 사업모델 만들 수 있을 정도의 백엔드 실력(어떻게든 돌아가는)을 갖추는 걸 목표로 노력해보자!

우선 현재 위 예제를 모두 이해하며 안 보고 처음부터 끝까지 만들어보는 걸 다섯 번 해봤고, 마지막으로 한 번 더 복습 후 다음 강의로 넘어가려한다.

그나저나.. 노션으로 정리한 내용 워드프레스 붙여넣는거 굉장히 불편한데 무슨 다른 방법이 없으려나ㅋ큐ㅠㅠ

출처 : Udemy- 옆집 개발자와 같이 진짜 이해하며 만들어보는 첫 Spring Boot 프로젝트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다