본문 바로가기
Codepresso

Spring Boot 웹 개발 입문 강의노트

by 선의 2022. 2. 8.

Spring Boot 웹 개발 입문

소개

1) 웹 개발과 Spring Framework 입문 코스

2) 러닝 커브 높다 → 깊이 있게 이해하기 위해 지식 필요

— 객체 지향 설계 원칙 + 디자인 패턴

— IoC, DI, AOP, Bean, Context

활용에 집중

— Todo List 웹 어플리케이션 개발(저장, 삭제, 조회)

— Frontent 코드 O → API 문서 → REST API 개발

Spring Framework 소개

주로 웹 어플 개발을 위해 활용된다

작은 게시판 → Netflix 규모까지 가능

장점

경량화, 재사용가능, 테스트 용이, 보안성 높음

방대한 프로젝트 - 22개 카테고리 수백개의 프로젝트 제공, 웹앱 개발+운영을 위한 거의 모든 기술을 제공

끊임 없는 개선

단점

설정 복잡 - “XML 지옥”, 설정 무거움

Spring Boot

프레임워크 쉽게 활용할 수 있게 지원하는 기술

기능) 설정 간편화(자동 설정), 의존성 관리, 배포 프로세스 간소화, 애플리케이션 모니터링

웹 서비스 개발과 Web Framework의 이해

1) 퍼블리싱 / 마크업: 사용자에게 노출되는 웹 화면 개발, 디자인을 코드로 옮기는 과정

2) 프론트엔드 개발: 사용자 화면과 백엔드와의 중간 커뮤니케이션 역할. 사용자의 이벤트를 받아 백엔드로 전송

3) DB 설계 / 운영: 웹 서비스의 데이터가 저장될 DB 설계 + DBMS를 운영 관리. 분석/설계 || 운영은 다름

4) 시스템 엔지니어링, 인프라 엔지니어링

포스트맨 설치

REST API를 통합 관리하기 위한 SW. Spring Boot로 구현하는 API를 테스트하기 위한 용도

Download Postman | Get Started for Free

여기서 설치

나의 첫 Spring Boot 애플리케이션

순서) spring initializr → IntelliJ import → 코드 개발 → 실행 → 웹 브라우저&Postman 활용하여 테스트

Spring Initializr

package com.codepresso.helloworld.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

//@ 붙은 것들을 annotation이라고 함
@RestController
public class HelloWorldController {

    @GetMapping(value = "/")
    public String hello(){
        return "<h1>Hello Spring Boot!!</h1>";
    }
}

Web의 기초 개념과 HTML의 기초 활용

1. Web과 HTTP의 개념

Web(World Wide Web)

인터넷 상에서 정보를 공유하는 기술 중 하나

기본적으로 Hypter Text 문서(HTML)로 작성되고 공유됨

Hyper Text

일종의 문서 링크를 포함 → 다룬 문서들과 연결 가능

HTTP(Hyper Text Transfer Protocol)

하이퍼 텍스트(웹 페이지)를 컴퓨터가 주고 받기 위한 규약

컴퓨터 간의 데이터를 주고 받기 위한 명확한 약속

웹 브라우저와 서버 간의 전송이 이루어짐

2. IP와 Port

IP

인터넷에 연결된 기기가 가질 수 있는 네트워크 상의 주소

IP 주소 정보로 원격에 있는 자원 요청 가능

공인 IP, 사설 IP(Public vs. Private)

공인은 인터넷 상에 고유한 IP 주소(— 관리하는 기관으로부터 할당 받아 사용 가능)

사설은 특정 조직 내부에서의 사설 네트워크 안에서만 통신 가능한 주소(—내부에는 사설로 통신 가능 외부에서는 불가능)

HostName

읽기 쉬운 형태의 주소

domain과는 엄밀히 말하면 다름, 거의 유사함(HostName이 더 하위에 있다)

호스트명으로 기기의 IP주소를 찾을 수 있다

localhost

현재 작업을 수행 중인 기기를 지칭하는 특수한 호스트명

IP 주소 — 127.0.0.1

Port 주소

호스트 내부의 프로세스의 네트워크 주소

SpringBoot 컨트롤러와 REST API

계층형 아키텍쳐의 이해

SW 아키텍쳐: 소프트웨어의 구조를 정의한 것, 구성하는 주요 요소들과 요소들의 관계를 정의한 것

SW 아키텍처/디자인패턴: 특정 상황의 문제를 해결하기 위한 일반화된 솔루션

계층형 아키텍처 패턴: 웹 서비스 개발에 주로 사용되는 패턴

Presentation Layer — Application Layer — Business Layer — Data Access Layer 등등

Untitled

Presentation Layer @Controller 클라이언트로부터 요청을 받아 다음 레이어에 처리를 위임 // 어플리케이션 레이어의 결과를 최종 클라이언트로 전달

Application Layer @Service 특정 목적을 위한 다양한 비즈니스 로직을 처리

DB Access Layer @Repository DB에 접근하여 데이터를 저장하거나 조회

Spring Controller의 이해 — 컨트롤러의 구현 문법

계층형 아키텍처의 Presentation Layer에 해당

Client들의 요청을 받고 Application Layer 요청에 대한 처리를 위임

Client에 최종 응답을 하는 역할

  • view: Client가 요청에 대한 응담의 결과로 보게 되는 웹 페이지
  • data: Client가 요청에 대한 응답으로 받는 데이터

코드

3개 기본 Annotation을 사용하여 구현

1) @Controller, @RestController

컨트롤러 역할을 하는 클래스를 지정, 클래스 상단에 명시

@Controller → view 응답(html 등)

@RestController → data 응담(문자열, json, xml 등)

2) @RequestMapping

특정 Request를 처리하는 메소드를 지정, 클래스 또는 메소드 상단에 명시

⇒ Spring Framework이 약속된 Annotation들을 스캔하고 관리

Annotation

자바 소스코드에 추가적인 정보를 제공하는 방법

@로 시작, 클래스/메소드/멤버변수/파라미터 등에 부착 가능

유형

1) 자바 컴파일러에 정보 제공 2) 소프트웨어 툴에 의해 사용되어 코드 생성이나 추가 작업을 진행 3) run-time 시 특정 동작을 추가적으로 실행

RequestMapping && URI

URI(Uniform Resourse Locator): 특정한 자원에 접근하기 위한 이름 또는 주소. 웹 상의 모든 자원들은 URI를 갖고 있다

Spring controller의 메소드들은 uri에 따라 호출이 결정된다(기본 도메인에 이어지는 /path 들에 의해 결정

@RequestMapping(value = “/path”)

URI는 요청하는 자원의 종류에 따라 이름을 정함

계층 관계로 표현 가능 — ‘/’로 계층을 구분

API(Application Programming Interface)

Interface: 두 개체 간의 정보를 공유하기 위한 방법(규약)

API: 컴퓨터(프로그램)간의 정보를 공유하기 위한 방법

HTTP API

HTTP를 활용하여 원격의 데이터를 공유하기 위한 API

REST API

REpresentational State Transfer

웹 상에서 효율적으로 데이터를 공유하기 위한 아키텍처 스타일

다양한 조건이 만족되어야 하고 실무에서 모든 조건을 만족하여 구현하기 어렵다

@RestController Annotation

Rest API, HTTP API를 위한 클래스를 명시

@RequestMapping이 붙은 개별 메소드들이 하나의 REST API, HTTP API

package com.codepresso.controllerexercise.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @RequestMapping(value = "/paid")
    public String getPaidUser() {
        return "I'm a paid user";
    }

    @RequestMapping(value = "/enterprise")
    public String getEnterpriseUser() {
        return "I'm a enterprise user.";
    }

}

Request 파라미터

Client가 Server에 요청할 때 추가적으로 전송하는 데이터

Spring Framework는 Request 파라미터를 메소드의 파라미터에 저장함

(1) Query String

URI와 파라미터의 영역을 구분하여 사용

@RequestParam

  • name: query string의 key, key와 변수명이 같을 경우 생략 가능
  • required: 필수 여부
  • defaultValue: 데이터가 없을 경우 기본 값

정렬이나 추가 필터링을 위한 데이터

package com.codepresso.controllerexercise.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestParamController {

    @RequestMapping(value = "/post")
    public String getPost(@RequestParam(required = false) String category,
                          @RequestParam Integer id){
        return "You requested " + category + " - " + id + " post";
    }

}

(2) Path Parameter

URI의 일부로 파라미터 값을 사용함

{}로 Path Param임을 표시

특정 자원을 요청하는 경우

package com.codepresso.controllerexercise.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestParamController {

    @RequestMapping(value = "/post")
    public String getPost(@RequestParam(name = "category") String category,
                          @RequestParam(name = "id") Integer id){
        return "You requested " + category + " - " + id + " post";
    }

}

package com.codepresso.controllerexercise.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestParamController {

    @RequestMapping(value = "/post")
    public String getPost(@RequestParam(required = false, defaultValue = "it") String category,
                          @RequestParam Integer id){
        return "You requested " + category + " - " + id + " post";
    }

}

Response 데이터와 JSON 포맷

JSON 응답 데이터(JavaScript Object Notation)

웹 개발 시 가장 일반적으로 사용하는 응답 데이터 포맷

프론트엔드에서는 JSON 형식의 데이터를 응답받아 화면 구성

각 REST API 별로 어떤 JSON 데이터를 응답할 것인지 사전에 정한다

JSON 문법

객체아 가장 기본 단위 ⇒ “key”:value 데이터 포함

value ⇒ 문자열, 숫자, boolean, 배열 가능

UserDto

package com.codepresso.controllerexercise.dto;

import java.util.List;

public class UserDto {
    Integer id;
    String name;
    String email;
    List<String> specialties;

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }

    public List<String> getSpecialties() {
        return specialties;
    }

    public UserDto(Integer id, String name, String email, List<String> specialties) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.specialties = specialties;
    }
}

UserController

package com.codepresso.controllerexercise.controller;

import com.codepresso.controllerexercise.dto.UserDto;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class UserController {

    @RequestMapping(value = "/user")
    public UserDto getUser(){
        List<String> specialities = new ArrayList<>();
        specialities.add("JAVA");
        specialities.add("Spring Boot");

        return new UserDto(1, "Jin","jin@codepresso.kr", specialities);
    }

}

localhost:8080/user

{
    "id": 1,
    "name": "Jin",
    "email": "jin@codepresso.kr",
    "specialties": [
        "JAVA",
        "Spring Boot"
    ]
}

HTTP Method의 이해

HTTP 규약 중 하나로, 특정 자원에 대해 수행하는 행동의 종류를 명시

단일한 URI로 다양한 행동을 정의 가능

@RequestMapping(method=GET){}

@RequestMapping(method=POST){}

@RequestMapping(method=PUT){}

@RequestMapping(method=DELETE){}

RequestBody

Client가 서버에 요청 시 전달하는 추가적인 Data

크기가 큰 데이터를 보내는 방식

일반적으로 데이터를 저장 및 수정하는 POST, PUT Method에서 사용된다(Get, DELETE는 쿼리 스트링이나 패스파람이 주로 사용)

JSON 데이터 형식으로 다양한 포맷의 데이터를 전송 가능

package com.codepresso.controllerexercise.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/post")
public class PostController {

    @RequestMapping(method = RequestMethod.GET)
    public String getPost(){
        return "GET /post";
    }

    @RequestMapping(method = RequestMethod.PUT)
    public String updatePost(){
        return "PUT /post";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String savePost(){
        return "SAVE /post";
    }

    @RequestMapping(method = RequestMethod.DELETE)
    public String deletePost(){
        return "DELETE /post";
    }
}

http method로 행동을 정의할 수 있다

→ 간소한 annotation

package com.codepresso.controllerexercise.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/post")
public class PostController {

    @GetMapping
    public String getPost(){
        return "GET /post";
    }

    @PostMapping
    public String updatePost(){
        return "PUT /post";
    }

    @PutMapping
    public String savePost(){
        return "SAVE /post";
    }

    @DeleteMapping
    public String deletePost(){
        return "DELETE /post";
    }
}

PostDto.java

package com.codepresso.controllerexercise.dto;

public class PostDto {

    Integer id;
    String title;
    String content;
    String username;

    public Integer getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }

    public String getUsername() {
        return username;
    }

    public PostDto(Integer id, String title, String content, String username) {
        this.id = id;
        this.title = title;
        this.content = content;
        this.username = username;
    }
}

PostController

package com.codepresso.controllerexercise.controller;

import com.codepresso.controllerexercise.dto.PostDto;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/post")
public class PostController {

    @GetMapping
    public String getPost(){
        return "GET /post";
    }

    @PutMapping
    public String updatePost(){
        return "PUT /post";
    }

    @PostMapping
    public String savePost(@RequestBody PostDto postDto){

        System.out.println(postDto.getId());
        System.out.println(postDto.getTitle());
        System.out.println(postDto.getContent());
        System.out.println(postDto.getUsername());

        return "SAVE /post";
    }

    @DeleteMapping
    public String deletePost(){
        return "DELETE /post";
    }
}

전송한 json file

{
    "id" : 1,
    "title" : "hello",
    "content" : "nice to meet to you",
    "username" : "sunnylee"
}

REST API 문서의 활용

API 문서화

API는 정보를 주고 받기 위한 방법/ 약속 → 사용하기 위해 방법을 알아야 함 → API 문서는 API를 사용하는 명세서

REST API 문서화

프론트엔드에서 호출하기 위한 REST API의 정보가 명세된 문서(보통 백엔드 개발자가 만듬)

클라이언트에서 호출하고 활용하는 데 어려움이 없도록 작성해햐 함

REST API 설명, URI, HTTP Method, Request 파라미터(필수 선택), Response 데이터(필수 응답, 선택 응답)

가능한 에러 코드 및 대응 방법

Spring Bean의 개념과 의존성 주입

계층형 아키텍처 패턴의 Application Layer @Service 부분에 해당 → 애플리케이션을 위한 햇김 비즈니스 로직을 구현하는 계층

Servie 구현

클래스에 @Service Annotation 사용

파라미터에 전달된 데이터들의 검증 작업 수행

Repository 계층을 활용하여 database에 접근

애플리케이션의 세부 영역 별로 클래스를 생성하여 구현

Untitled

스프링 빈과 의존성 주입

dependency

멤버 변수 new로 객체 생성+참조 → 생성 객체 호출

의존성 주입 Dependency Injection

객체 생성을 외부에서 대신 수행

활용할 객체에 대한 의존성 설정을 외부에서 대신 함

활용할 클래스 타입의 멤버 변수만 선언 후 생성자 구현

Spring Framework가 객체의 생성과 관리 역할 수행

소스코드 스캔 → 어노테이션 보고(특정 조건) 객체 생성

Component scan

객체 간의 의존성을 연결하는 역할을 대신 수행해 줌

Spring IOC container

제어 역전

객체의 생성과 관리의 역할을 하는 컴포넌트

Spring Bean

스프링 IOC 컨테이너에 의해 만들어져서 사용되는 객체

코드프레소 Java 웹 개발 체험단 활동 중(https://www.codepresso.kr/)