Portfolio/Spring Boot

스프링 부트 1일차 - 스프링 부트 시작

Foo 2019. 3. 31. 15:56
728x90

https://book.naver.com/bookdb/book_detail.nhn?bid=14031681

"처음 배우는 스프링 부트 2 - 커뮤니티 게시판을 구현하며 배우는 입문부터 보안까지"

라는 책으로 시작.

 

스프링은 기존에 학과 도서, 장비 대출 시스템(https://github.com/lleellee0/Cs-Rfid)를 만들면서 공부, 사용해 본 적은 있었지만 그간 군에 있으면서 간단히 Node.js만 했었기 때문에 새로 시작하면서 스프링 부트로 공부하려고 함.

근 3주 정도 사이에는 Docker와 AWS에 대해서 공부하고 있었으나 잠시 내려두고 스프링 부트를 통해 다음과 같은 웹 사이트를 구현해보려고 함.

 

  • 약칭 'foopang'으로 coupang과 같은 상품 등록, 판매가 가능한 페이지를 만듬.
  • 총 3가지 타입의 사용자가 있음. 각각의 타입에 대한 세부 사항은 아래에 자세히 다시 기재
    • 소비자(일반 사용자)
    • 판매자(셀러)
    • 사이트 관리자(어드민)
  • 소비자, 판매자, 사이트 관리자에 해당하는 기능들은 MSA처럼 WAS 단 까지는 각자 독립적으로 동작하지만, DB 서버는 하나만 사용한다.

 

각 사용자별 구현되어야할 기능

  • 소비자(일반 사용자)
    • 로그인
      • 아이디와 비밀번호를 통해 로그인 가능
      • 아이디는 이메일 형태, 비밀번호는 사용자마다 다른 Salt를 넣어서 저장, 당연히 Salt까지 같이 저장
      • 비밀번호를 잃어버렸을 때 비밀번호 찾기 기능 제공(E-mail)
      • 회원가입시 이메일, 비밀번호, 비밀번호 확인, 이름 입력
    • 쇼핑
      • 카테고리로 들어가거나, 상품 이름으로 검색
      • 검색이나 카테고리로 들어갔을 때 상품 리스트가 나옴
        • 상품 리스트는 36, 48, 60, 72개 씩 볼 수 있도록 사용자가 선택가능
        • 각각의 상품은 상품 사진, 상품 이름, 가격, 사용자 평점이 나옴
      • 상품을 클릭하면 상품 상세 정보가 나옴
        • 위의 상품 사진, 상품 이름, 가격, 사용자 평점이 다시 한번 나오고, 여기서 장바구니에 담기나 바로구매를 선택할 수 있음.
        • 상품 상세 설명에는 판매자가 등록한 상품 상세 설명이 글, 사진 형태로 나옴
        • 아래 쪽에는 해당 상품을 구입한 다른 사용자들의 후기가 사진+글+평점 으로 나와있음.
          • 후기는 리스트로 10개씩 볼 수 있음.
        • 후기 밑에는 상품문의 하기를 위한 공간이 있고, 상품 문의를 누르면 Modal이 떠서 거기에서 문의 내용을 작성
          • 문의 내용을 작성하면 문의 내용이 나오고 해당 문의 & 답변은 다른 사용자들에게도 공유됨.
      • 상품을 주문하기로 바로 주문하면 해당 상품만 주문/결제 창으로 넘어가서 결제 가능.
        • 구현 상 결제는 그냥 클릭하면 결제 처리 되는 것으로..
        • 받는 사람은 최근 배송된 곳이 뜨도록 하고, 기존에 1번이라도 배송했던 곳의 정보를 리스트로 사용자에게 보여주고 선택도 가능하도록 구현
    • My Page에서는 지금까지 결제했던 내역을 확인할 수 있도록 함.
  • 판매자(셀러)
    • 상품 등록
      • 상품의 이름, 사진, 가격, 상세 내용을 등록할 수 있음.
        • 상품 사진은 대표사진 같은 것을 말하는 것
        • 상세 내용에는 위지윅 에디터 형태로 내용, 사진 입력 가능
        • 사이트에서 제공하는 카테고리를 선택 가능
    • 상품 리스트
      • 해당 판매자가 등록해둔 상품들의 리스트를 제공, 누르고 들어가면 상품 등록처럼 상품의 내용을 수정할 수 있음.
    • 상품 문의 내용 확인
      • 소비자의 상품에 대한 문의를 모아보기로 답변 가능
  • 사이트 관리자(어드민)
    • 카테고리 추가/제거/수정
    • 상품/구매후기 삭제 가능

 

지금까지 생각한 간단한 스펙은 여기까지이다. 프론트엔드는 그냥 jQuery로 플러그인 사용가능한 것 있으면 최대한 활용해서 작성

 

 

다시 스프링 부트 내용으로 돌아와서..

- 메이븐 대신에 그레이들(gradle) 사용 => 기존 메이븐은 xml 형태로 너무 정적임..

- 그레이들을 이용하면 하나의 프로젝트 내에 멀티프로젝트로 구성 가능

    => (내 추측) 프로젝트 내에 다른 프로젝트를 넣어서 멀티프로젝트로 만들 수 있으니 이걸 이용해서 MSA를 하나의 Jar로 만들어서 배포하는게 아닐까 생각해봤음.

 

- application.properties 대신 yml을 통한 프로파일 관리

  => aws에서 codedeploy를 통해 배포할 때 yml을 쓰는 것으로 볼 때 지금 주류를 이루고 있는 것 같음.

       YAML을 사용하려면 snakeYAML 라이브러리를 포함해야 하지만 Spring Boot Starter에는 기본으로 포함되어있음.

 

* 실행 환경 별로 다른 yml 파일 사용하기

  (p.52-53) 책에서는 인텔리제이의 Run/Debug Configurations에 [Spring Boot Settings]에 Active Profiles를 설정할 수 있도록 UI가 구성되어 있는데 내 꺼에는 없음.. 커뮤니티 버전과 얼티밋 버전의 차이인지? 그래서 커맨드로 실행하는 것처럼 -D spring.profiles.active=???로 옵션을 줄 필요가 있었음. 그렇게 주기 위해선 다음과 같이 "VM options"에 옵션을 줄 필요가 있었음.

VM options에 -Dspring.profiles.active=local 설정
나는 local 환경에서는 8080으로 설정을 했기 때문에 8080으로 실행이된다.

 

커뮤니티 버전과 얼티밋 버전의 차이인지, UI 자체가 바뀐건지, 아님 그냥 제가 잘 몰라서 이렇게 된건지 알고 계신분 댓글 부탁드려요 :)

 

p.55-56에 있는 AutoconfigurationApplicationTests.java 코드가 없음 ㅡㅡ 작가 깃헙에도 없고 한빛미디어 홈페이지를 가봐도 없음.. 오타 없이 따라 치느라 애먹었습니다.

package com.example.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AutoconfigurationApplicationTests {
    @Value("${property.test.name}")
    private String propertyTestName;

    @Value("${propertyTest}")
    private String propertyTest;

    @Value("${noKey:default value}")
    private String defaultValue;

    @Value("${propertyTestList}")
    private String[] propertyTestArray;

    @Value("#{'$propertyTestList}'.split(',')}")
    private List<String> propertyTestList;

    @Test
    public void testValue() {
        assertThat(propertyTestName, is("property depth test"));
        assertThat(propertyTest, is("test"));
        assertThat(defaultValue, is("default value"));

        assertThat(propertyTestArray[0], is("a"));
        assertThat(propertyTestArray[1], is("b"));
        assertThat(propertyTestArray[2], is("c"));

        assertThat(propertyTestList.get(0), is("a"));
        assertThat(propertyTestList.get(1), is("b"));
        assertThat(propertyTestList.get(2), is("c"));
    }
}

 

그렇다고 또 실행시키면 실행이 되느냐? 그것도 아닙니다.

> Task :compileJava FAILED
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:3: error: package org.junit does not exist
import org.junit.Test;
                ^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:4: error: package org.junit.runner does not exist
import org.junit.runner.RunWith;
                       ^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:6: error: package org.springframework.boot.test.context does not exist
import org.springframework.boot.test.context.SpringBootTest;
                                            ^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:7: error: package org.springframework.test.context.junit4 does not exist
import org.springframework.test.context.junit4.SpringRunner;
                                              ^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:11: error: package org.hamcrest does not exist
import static org.hamcrest.Matchers.is;
                          ^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:11: error: static import only from classes and interfaces
import static org.hamcrest.Matchers.is;
^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:12: error: package org.junit does not exist
import static org.junit.Assert.assertThat;
                       ^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:12: error: static import only from classes and interfaces
import static org.junit.Assert.assertThat;
^
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:14: error: cannot find symbol
@RunWith(SpringRunner.class)
 ^
  symbol: class RunWith
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:15: error: cannot find symbol
@SpringBootTest
 ^
  symbol: class SpringBootTest
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:32: error: cannot find symbol
    @Test
     ^
  symbol:   class Test
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:34: error: cannot find symbol
        assertThat(propertyTestName, is("property depth test"));
                                     ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:35: error: cannot find symbol
        assertThat(propertyTest, is("test"));
                                 ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:36: error: cannot find symbol
        assertThat(defaultValue, is("default value"));
                                 ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:38: error: cannot find symbol
        assertThat(propertyTestArray[0], is("a"));
                                         ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:39: error: cannot find symbol
        assertThat(propertyTestArray[1], is("b"));
                                         ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:40: error: cannot find symbol
        assertThat(propertyTestArray[2], is("c"));
                                         ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:42: error: cannot find symbol
        assertThat(propertyTestList.get(0), is("a"));
                                            ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:43: error: cannot find symbol
        assertThat(propertyTestList.get(1), is("b"));
                                            ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
C:\Users\이준형\Desktop\dev-spring-boot\demo\demo\src\main\java\com\example\demo\AutoconfigurationApplicationTests.java:44: error: cannot find symbol
        assertThat(propertyTestList.get(2), is("c"));
                                            ^
  symbol:   method is(String)
  location: class AutoconfigurationApplicationTests
20 errors

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

 

이 코드를 실행하는데 필요한 의존성들이 설치가 안되있어서 발생하는 문제들 같은데

분명 책 시작부터 지금까지 spring-boot-stater-web로 시작을 했는데? 

책 공부 첫날인데 이 책이 "처음 배우는" 이라는 이름이 붙어도 되는 책인지 모르겠다..

"처음 배우는" 사람을 강하게 해주는 그런 책인 것 같음.

고3 끝나고 C++을 처음 배울 때도 비슷한 경험이 있었는데 다시 하고 있는 것 같음

(https://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=143105803)