본문 바로가기

개발/02-2.점프 투 스프링부트3

[SpringBoot, Day1] ~ 2-02 : 간단한 웹 프로그램 만들기(page.56)

배경 : 진현님 고등학교 베프 학생분과 이야기를 하면서, 이 친구에게 조금이라도 독려를 해주고 싶은 마음과, 도움을 주고 싶은마음에,  마침 나도 회사에서 중요한 업무들이 끝나는 시점이라 같이 따라하면서 기본을 챙기고, 그 친구에게 조금이라도 좀 더 도움을 주고 싶은 마음에서 시작함.

 

참고 : 아래 글은 점프 투 스프링부트 위키독스 내용을 공부하였고, 그 내용을 정리하였습니다 

https://wikidocs.net/160023

 

내용:


1장 스프링 부트 개발 준비하기

 스프링부트를 향한 첫걸음 -> 절반은 성공! ㅋㅋ

"흐름" 이 중요, "시작" 이 중요!


1-01 스프링 부트란?

  • 웹 프로그램(어플리케이션)을 쉽고 빠르게 만들 수 있도록 도와주는 (자바의) 웹 프레임워크
  • 스프링(Spring) 프레임ㅋ워크 + 톰캣(Tomcat) 서버 내장, 여러 편의 기능을 추가.

웹 프레임워크란?

쿠키, 세션, 로그인/로그아웃, 권한, 데이터베이스 등 기능들을 웹 프레임워크에 이미 기능들이 만들어져 있어서,  이 웹 프레임워크에 있는 기능을 익혀서 사용하기만 하면 된다. (웹 프로그램을 만들기 위한 스타터 키트)

 

예제) 웹 프라우저에 Hello World  출력 

@Controller 
public class HelloController { 
    @GetMapping("/") 
    @ResponseBody 
    public String hello() { 
        return "Hello World"; 
    } 
}

 

스프링 부트를 배워야 하는 이유

1. 튼튼한 웹 프레임워크

보안 기능

SQL 인젝션[악의적인 SQL 주입], XSS(cross-site scripting)[자바스크립트 삽입], CSRF(Cross-Site Request Forgery)[위조된 요청], 클릭재킹(clickjacking)[의도치 않은 클릭 유도]과 같은 보안 공격을 막아준다.

 

여러 기능

로그인  : 네이버나 구글 로그인 처럼 사용자 인증 하는 기능]

페이징  : 한 페이지에 데이터가 많으면 페이지별 나누어 조회할 수 있계 하는 기능] 

 

WAS가 필요없다.

스프링부트에는 톰캣 서버가 내장되어 있고, 설정도 자동 적용됨

배포되는 jar 파일에도 톰캣 서버가 내장되어 실행.

 

WAS란

  • 웹 어플리케이션과 서버 환경을 연결하는 중간 역할을 하는 소프트웨어 플랫폼
  • 사용자가 웹 브라우저로 서버에 요청을 보내면, WAS는 사용자의 요청을 해석하여 그에 맞는 서버 프로그램을 구동 한 후 그 결과를 사용자에게 보여줌

2. 설정이 쉽다

스프링으로 개발시 복잡한 설정 때문에 많은 어려움을 겪음.

이 복잡한 설정을 자동화,단순화 하여, 누구나 쉽게 스프링을 사용할 수 있도록 한 프레임워크

 

3. 재미 있다

레고를 조립하는 것 처럼 웹 애플리케이션이 완성되어 가는 과정을 즐기게 된다. (필자 왈 ㅎㅎ)


1-02 스프링 부트 개발 환경 준비하기

 

 

1~3 생략. 

4 는 IntelliJ 로 진행.

프로젝트 --> 프로젝트 생성 --> 아래 정보로 입력 --> 다음 클릭

 

스프링 부트 버전은 3.3.6, 의존성은 Web --> Spring Web 선택 후 생성 버튼 클릭

 

프로젝트가 생성 완료 된 것을 확인 할 수 있다.

 

 

막 뭔가 다운로드 받다가.. 오류 메세지 나서 Gradle 재 빌드를 했더니 아래와 같이 정상 노출되었다


1-03 스프링 부트 맛보기

Hello World 출력 하는 웹 프로그램 만들어보기.

웹 서비스는 어떻게 동작할까?

클라이언트와 서버 구조 이해하기

                           요청

     웹브라우저      -->     웹 서버     

↗  html 문서        <--      html 문서    ↖

                           응답 

     [클라이언트]             [서버] 

 

브라우저 --> 서버 요청 보낼때는 서버의 주소(IP) 또는 서버의 주소를 대체할 수 있는 도메인명 을 알아야 함.

예시) naver.com 입력 --> 네이버에서 운영하는 웹 서버 호출 --> 서버는 요청에 대한 응답을 브라우저에 돌려준다.

즉 웹 서버는 요청에 대한 응답으로 HTML 문서나 다른 리소스들을 브라우저에 표시.

 

IP 주소와 포트 이해하기

프로토콜 서비스 내용 포트
HTTP 웹 서비스 80
HTTPS SSL을 적용한 웹 서비스 443
FTP 파일 전송 서비스 21
SSH, SFTP 보안이 강화된 TELNET, FTP 서비스 22
TELNET 원격 서버 접속 서비스 23
SMTP 메일 전송 서비스 25

(필요에 따라 포트 번호를 별도로 정의, 변경 가능. 예시 - HTTP 포트를 80 대신 8080 사용할 수 있음)

 

localhost:8080 이해하기

localhost(로컬호스트) : 도메인명, 127.0.0.1 이라는 ip 주소를 의미.   (127.0.0.1 = 내 컴퓨터 의미)

localhost:8080 = 내 컴퓨터(localhost)에 8080번 포트로 실행된 서비스를 의미

내 컴퓨터에 실행된 서버는 로컬 서버 이므로, 외부에서는 접속 불가. (외부에서 접속하게 하는 방법은 4장에서 설명)

 

컨트롤러 만들기

http://localhost:8080/hello 와 같은 브라우저의 요청을 처리하려면 컨트롤러가 필요함

컨트롤러 : 서버에 전달된 클라이언트의 요청을 처리하는 자바 클래스.

 

HelloController Class 생성 후 책 본 내용을 입력

package com.ksko.sbb;

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

@Controller//HelloController 클래스가 컨트롤러의 기능을 수행 한다는 의미
public class HelloController {

    /*
      용어 설명
     1. 애너테이션(annotation) : 자바의 클래스, 메서드, 변수 등에 정보를 부여하여 부가 동작을 할 수 있게 하는 목적으로 사용
     2. 매핑(mapping)하다 : 특정 URL 경로를 서버의 특정 메서드와 연결하는 것을 의미
     3. Get 방식, Post 방식 차이
      - Get과 Post는 HTTP 프로토콜을 사용하여 데이터를 서버로 전송하는 방식
      1) Get 방식 :  데이터를 URL에 노출시켜 요청하며, 주로 서버에서 데이터를 조회하거나 읽기 위한 목적으로 사용
      2) Post 방식 :  데이터를 숨겨서 요청하므로 로그인 정보와 같은 민감한 데이터를 서버에 제출하거나 저장하는 목적으로 사용
      @GetMapping : Get 방식으로 URL 요청
      @PostMapping : Post 방식으로 URL 요청
     */
    @GetMapping("/hello") // http://localhost:8080/hello URL 요청이 발생하면 hello 메서드가 실행됨을 의미. 즉 /hello URL과 hello 메서드를 매핑하는 역할. 이때 URL명과 메서드명이 동일할 필요는 없다. 즉, /hello URL 일때 메서드명을 hello가 아닌 hello2 와 같이 써도 상관 없음
    @ResponseBody // hello 메서드의 출력 결과가 문자열 그 자체임을 나타냄.(출력결과는 이런 String 문자열 보다, html 파일과 같은 템플릿이 주로 사용)
    public String hello() {
        return "Hello World";
    }
}

 

로컬 서버 실행하기

SbbApplication 실행

 

Hello World (하 얼마만에 헬로월드냐 ㅠㅠ)

 


1-04 스프링 부트 도구 설치하기

라이브러리 : 웹 프로그램 개발을 도와주는 스프링 부트의 도구. // 개발시 자주 사용하는 코드를 모아 둔 것

Spring Boot Devtools 설치하기

Hello World --> Hello SBB로 교체

 

리턴 문자값을 변경하고 URL 붙어도 Hello World로 나온다. 그 이유는 프로그램이 변경되어도, 별도의 과정 없이는 로컬 서버가 변경된 클래스를 즉시 반영하지 않기 때문이다.

프로그램을 간단히 수정하더라도, 변경된 사항을 확인하기 위해서는 매번 서버를 재시작 해야 하므로, 개발 과정이 꽤 번거롭다.

 

Devtools : 서버를 매번 재시작하지 않고 수정한 내용이 반영된다.

 

Devtools 설치 방법

 

build.gradle

 

developmentOnly : 개발 환경에만 적용. 운영 환경에 배포 되는 jar, war 파일에는 이 라이브러리가 포함되지 않는다.

 

build.gradle 파일에 작성한 내용 적용하려면 gradle 재 빌드 또는 갱신 해준다.

 

[참고] 인텔리제이에서는 자동빌드 옵션 안쓰고 하기로 함. 

그래도 다른분들이 정리한 내용 아래 적어둔다.

https://wikidocs.net/blog/@ilco/391/

 

[점프투스프링부트3] 인텔리제이에서 devtools 자동빌드 적용하기

[점프투스프링부트3] 인텔리제이에서 devtools 자동빌드 적용하기

wikidocs.net

롬복 설치하기

롬복(Lombok) 라이브러리 : 소스 코드 작성할 때, 자바 클래스에 애너테이션을 사용하여 자주 쓰는 Getter, Setter, 생성자 등을 자동으로 만들어주는 도구

  • Getter, Setter : 자바 클래스의 속성값을 읽거나 저장할 때 사용

SBB 게시판 만들면서, 게시물과 관련된 데이터를 처리하기 위해 엔티티 클래스나 DTO 클래스 등을 사용해야하는데, 그러기 위해서는 먼저 이 클래스들의 속성값을 읽고 저장하는 Getter, Setter 메서즈를 만들어야 한다. 

  • 엔티티 클래스 : 데이터베이스에 데이터를 저장하고 조회하기 위한 클래스
  • DTO 클래스 : 데이터 베이스로 조회한 데이터들을 관리하기 위한 클래스

롬복 설치 방법 

build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    
    compileOnly 'org.projectlombok:lombok' //롬복
    annotationProcessor 'org.projectlombok:lombok' // 롬복 
}

 

위 추가 후 Refresh Gradle Project 진행. 라이브러리 다운 완료.

> Task :prepareKotlinBuildScriptModel UP-TO-DATE
Download https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.36/lombok-1.18.36.pom, took 109 ms
Download https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.36/lombok-1.18.36.jar, took 214 ms

BUILD SUCCESSFUL in 1s

 

롬복(Lombok)으로 Getter, Setter 메서드 만들기

HelloLombok.java

package com.ksko.sbb;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class HelloLombok {
    private String hello;
    private int lombok;

    public static void main(String[] args) {
        HelloLombok helloLombok = new HelloLombok();
        helloLombok.setHello("헬로");
        helloLombok.setLombok(5);

        System.out.println(helloLombok.getHello());
        System.out.println(helloLombok.getLombok());
    }
}

 

실행결과

한글 깨짐

 


[참고] 인텔리제이 한글 깨짐 현상 인코딩 (참고 : https://nsmchan.tistory.com/17)

1차적으로 했음. 이거만 하면 안됨

 

vm 설정

인텔리제이 에서 쉬프트 2번 클릭 --> 검색창에 vm 입력 --> 사용자 지정 VM 옵션 편집 클릭

 

-Dfile.encoding=UTF-8

-Dconsole.encoding=UTF-8

어? 이거 이렇게 되어있음..

 

인텔리제이 재기동 해도 마찬가지임

근데.. 일반 컨트롤러로 하면 한글안깨지는데 메인메서드 를 따로 해서 실행하면 한글 깨짐 왜지?

 

chatGPT 통한 해결

B. Windows 기본 콘솔 설정 변경

Windows에서는 기본 콘솔 출력이 깨질 수 있으므로 다음 단계를 통해 변경합니다.

  1. IntelliJ 터미널에서 코드 페이지 변경
    • IntelliJ 터미널 또는 명령 프롬프트에서 다음 명령을 실행:
      shell
      코드 복사
      chcp 65001
      이 명령은 콘솔의 코드 페이지를 UTF-8로 설정합니다.
  2. PrintStream으로 강제 설정 후 출력 확인 코드를 약간 수정하여, 콘솔 출력 스트림을 UTF-8로 설정한 후 직접 출력해보세요:
  3. java
package com.ksko.sbb;

import lombok.Getter;
import lombok.Setter;

import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

@Getter
@Setter
public class HelloLombok {
    private String hello;
    private int lombok;

    public static void main(String[] args) {
        System.out.println("Default Charset: " + java.nio.charset.Charset.defaultCharset());
        System.out.println("file.encoding: " + System.getProperty("file.encoding"));
        System.out.println("Default Locale: " + java.util.Locale.getDefault());
        System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8)); // 콘솔 출력 스트림을 UTF-8로 설정후 하니 나옴 ㅠㅠ

        HelloLombok helloLombok = new HelloLombok();
        helloLombok.setHello("헬로");
        helloLombok.setLombok(5);

        System.out.println(helloLombok.getHello());
        System.out.println(helloLombok.getLombok());
    }
}

 

롬복으로 생성자 만들기.

package com.ksko.sbb;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

@Getter
//@Setter
@RequiredArgsConstructor
public class HelloLombok {
    //1.롬복으로 getter, setter 만들기
    /*
    private String hello;
    private int lombok;
    */

    private final String hello;
    private final int lombok;

    public static void main(String[] args) {
        //한글 인코딩 깨짐 현상 확인 및 수정
        System.out.println("Default Charset: " + java.nio.charset.Charset.defaultCharset());
        System.out.println("file.encoding: " + System.getProperty("file.encoding"));
        System.out.println("Default Locale: " + java.util.Locale.getDefault());
        System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
        //1.롬복으로 getter, setter 만들기
        /*
        HelloLombok helloLombok = new HelloLombok();
        helloLombok.setHello("헬로");
        helloLombok.setLombok(5);

        System.out.println(helloLombok.getHello());
        System.out.println(helloLombok.getLombok());
        */
        HelloLombok helloLombok = new HelloLombok("헬로", 5);
        System.out.println(helloLombok.getHello());
        System.out.println(helloLombok.getLombok());
    }
}

 

hello, lombok 속성에 final 추가하고 @RequredArgsConstructor 애너테이션을 적용하면, 해당 속성(hello, lombok)을 필요로 하는 생성자가 롬복에 의해 자동으로 생성된다.

  • final : 뒤에 따라오는 자료형과 변수 등을 변경할 수 없게 만드는 키워드. 만약 클래스 속성을 정의한 코드에 final이 없다면 생성자에 포함되지 않는다. 또한 final을 적용하면 속성값을 변경할 수 없기 때문에, @Setter 는 의미가 없고, Setter 메서드 또한  사용할 수 없다.

2장 스프링 부트의 기본 기능 익히기

스프링 부트 개발 하는 데 필요한 기본 내용 다룸!

SBB 게시판은 빌딩 --> 기본 기능은 기초 공사!

 

목표

  • 컨트롤러를 이용해 URL과 매핑되는 메서드를 관리한다.
  • JPA를 이용해 데이터베이스를 제어한다.
  • HTML, CSS 등을 활용하여 웹 프로그램을 꾸민다.

2-01 스프링 부트 프로젝트의 구조 이해하기

프로젝트 전체 구조

 

src/main/java 디렉터리 살피기

자바 파일을 저장하는 공간

 

com.ksko.sbb 패키지

컨트롤러, 폼과 DTO, 데이터베이스 처리를 위한 엔티티, 서비스 등의 자바파일 위치

  • 컨트롤러 : URL 요청을 처리하고 폼은 사용자의 입력을 검증한다.
  • DTO, 엔티티, 서비스  : 데이터베이스를 처리하기 위해 필요한 파일 .

SbbApplication.java 파일

모든 프로그램에는 프로그램의 시작을 담당하는 파일이 있다. 스프링 부트로 만든 프로그램(=스프링 부트 애플리케이션)에도 시작을 담당하는 파일이 있는데. 그 파일이 바로 "프로젝트명 + Application.java" 파일이다. 스프링 부트 프로젝트를 생성할 때 프로젝트 명으로 'sbb' 라는 이름을 입력하면, 다음과 같이 SbbApplication.java 파일이 자동으로 생성된다.

 

package com.ksko.sbb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SbbApplication {

    public static void main(String[] args) {
        SpringApplication.run(SbbApplication.class, args);
    }

}

 

@SpringBootApplication 애너테이션을 통해 스프링 부트 애플리케이션을 시작할 수 있다.

 

src/main/resources 디렉터리 살펴보기

자바파일을 제외한 HTML, CSS, 자바스크립트, 환경 파일(프로젝트 설정 정보를 저장하는 파일) 등을 저장하는 공간.

  • HTML : 웹 페이지의 기본 구조를 만들 수 있는 마크업 언더
  • CSS : 웹 페이지에 옷을 입히는 스타일 시트 언어
  • 자바스크립트 : 웹 페이지의 상호 작용과 동작 등을 할 수 있게 만드는 프로그래밍 언어

templates 디렉터리

src/main/resources 디렉토리 하위 디렉터리인 templates 에는 템플릿 파일을 저장

템플릿 파일 : 자바 코드를 삽입할 수 있는 HTML 형식의 파일. 

스프링 부트에서 생성한 자바 객체를 HTML 형태롤 출력할 수 있음.

 

static 디렉터리

스타일시트(css 파일), 자바스크립트(js 파일) 그리고 이미지 파일(jpg파일, png파일 등) 등을 저장한다.

 

application.properties 파일

sbb 프로젝트의 환경 변수, 데이터베이스 등의 설정을 파일에 저장.

 

src/test/java 디렉터리 살펴보기

sbb 프로젝트에서 작성한 파일을 테스트하는 코드를 저장하는 공간

JUnit 과 스프링 부트의 테스트 도구를 사용하여 서버를 실행하지 않은 상태에서 src/main/java 디렉터리에 작성한 코드를 테스트 할 수 있다.

  • JUnit : 테스트 코드를 작성, 작성한 테스트 코드를 실행할 때 사용하는 자바의 테스트 프레임워크

build.gradle 파일 살펴보기

그레이들(Gradle)이 사용하는 환경 파일. 그루비(Groovy) 기반으로 한 빌드도구.

  • 그루비 : 그레이들 빌드 스크립트를 작성하는데 사용하는 스크립트 언어
  • 빌드 도구 : 소스 코드를 컴파일 하고 필요한 라이브러리를 내려받을 때 사용한다. sbb 프로젝트 완성시 단 한개의 jar 파일로 패키징하여 서버에 배포할 수 있는데 이떄에도 빌드 도구를 사용

2-02 간단한 웹 프로그램 만들기

웹 브라우저에서 http://localhost:8080/sbb 페이지를 요청했을 때 '안녕하세요 sbb에 오신 것을 환영합니다.'라는 문자열을 출력하도록 만들어 보자.

 

URL 매핑과 컨트롤러 이해하기

로컬 서버 구동 후 http://localhost:8080/sbb 페이지 요청하자

404 오류

status=404 는 HTTP 오류 코드 중 하나로, 브라우저가 요청한 페이지를 찾을 수 없다. 는 의미

즉, 스프링 부트 서버가 http://localhost:8080/sbb 라는 요청을 해석할 수 없기 때문에 이와 같은 오류가 발생한 것이다.

(위 URL로 요청 --> 스프링부트 서버에서는 404오류 (스프링부트 로컬 서버에는 그런 URL은 없던데?)

 

이 오류를 해결하려면? --> /sbb URL에 대한 매핑을 추가하면 해결할 수 있음.

  • URL 매핑 : URL과 컨트롤러의 메서드를 일대일로 연결하는 것을 말한다. 

이미지 참고 : https://wikidocs.net/160543

컨트롤러 만들어서 URL 매핑하기

웹 브라우저와 같은 클라이언트의 요청이 발생하면 서버 역할을 하는 스프링 부트가 응답해야 한다. 그러기 위해서, URL이 스프링 부트에 매핑되어 있어야 하고, 이를 위해서는 먼저 컨트롤러를 만들어야 한다.

이미지 참고 : https://wikidocs.net/160543

 

1. MainController.java

package com.ksko.sbb;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MainController {
    @GetMapping("/sbb")
    public void index() {
        System.out.println("index");
    }
}
  1. MainController 클래스에 @Controller 애너테이션을 적용하면. MainController 클래스는 스프링 부트의 컨트롤러가 된다.
  2. index 메서드에 @GetMapping 애너테이션은 요청된 URL (/sbb)과의 매핑을 담당한다. (브라우저가 URL을 요청하면 스프링부트는 요청하는 페이지와 매핑되는 메서드를 찾아 실행한다.)

실행결과

 

이번에는 500 오류 발생. 

http://localhost:8080/sbb 요청 --> MainController 클래스의 index 메서드가 호출되긴 했지만, 오류 발생

원래 URL과 매핑된 메서드는 결과값을 리턴해야 하는데 아무 값도 리턴하지 않아. 이런 오류가 발생한 것.

즉, 오류를 해결하려면 클라이언트(브라우저)로 응답을 리턴해야 한다.

  • 콘솔 로그를 보면 index 메서드에서 실행한 System.out.println("index");가 실행되어 ‘index’라는 문자열이 출력된 것을 확인할 수 있다. 따라서 index 메서드가 호출되었음을 알 수 있다.

 

수정 해보자

package com.ksko.sbb;

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

@Controller
public class MainController {
    
    @GetMapping("/sbb")
    @ResponseBody
    public String index() {
        return "index";
    }
}

 

응답으로 "index" 문자열을 브라우저에 출력하기 위해

1. index 메서드의 리턴 자료형을 String으로 변경 하고 문자열 'index'를 리턴함

 - @ResponseBody 애너테이션 : URL 요청에 대한 응답으로 문자열을 리턴 하라

  • 만약 @ResponseBody 애너테이션을 생략한다면 스프링 부트는 'index' 라는 문자열을 리턴하는게 아니라, index 라는 이름의 템플릿 파일을 찾게 된다. 

다시 서버 재기동 하고 실행하면 index가 잘 나온다.

문자열 index 대신  '안녕하세요 sbb에 오신 것을 환영합니다.'를 출력해 보자.

이미지 참고 : https://wikidocs.net/160543

 

잘 되었다.

 

여기까지 공부한 것을 github 에 올려보자.

https://github.com/ksko1/sbb_study

 

GitHub - ksko1/sbb_study

Contribute to ksko1/sbb_study development by creating an account on GitHub.

github.com

 

728x90