본문 바로가기
백엔드(Back-End)/Spring Boot

[STS4-Spring Boot] 오디오 스토어 제작

by 기딩 2024. 2. 4.
728x90

프로젝트 개요

 

프로젝트 명 : 스프링을 이용한 오디오스토어 웹

진행 기간 : 2023.12.10 2024.01.27

개발 인원 : 1

 

프로젝트 선정 이유 :

스피커, 헤드폰, 턴테이블 등 오디오 기기에 대한 관심이 증가하는 추세.

국내 오디오 콘텐츠 시장 규모는 2019년 약 259, 2024년에는 약 4.4배 증가한 약 1,115 억원 규모로 증가할 것이라는 통계가 이를 뒷받침.

보통 해외 기업이 많아서인지 해외에서 사용하는 사이트를 그대로 한국어로 번역만 한 쇼핑몰은 UI 등 이용하기에 불편하다고 느껴져, 직접 오디오 스토어를 구현함.

 

프로젝트 주요 내용

- 회원
고객 : 회원가입, 로그인, 회원정보 수정, 회원 탈퇴

관리자 : 회원 목록 조회

- 상품

고객 : 상품 조회

관리자 : 고객기능 + 상품 등록, 수정, 삭제, 조회

- 장바구니

여러 상품과 각 수량을 선택하여 장바구니 담기, 각 상품 삭제

- 주문

장바구니 전체 주문하기 (배송지 변경가능, 배송메시지, 결제방법)

 

개발 환경

Database MySql
프레임워크 이클립스 STS4 (Gradle)
사용 언어 Java, Html, JavaScript, CSS
템플릿 엔진 Thymeleaf

 

부트스트랩 출처

로그인 폼 디자인
https://inpa.tistory.com/entry/CSS-💍-로그인-회원가입-페이지-스타일-🖌-모음

쇼핑몰 웹 디자인

https://themewagon.com/themes/free-html5-ecommerce-website-template/

마이페이지

https://www.bootdey.com/snippets/view/bs4-edit-profile-page

관리자 페이지

https://codepen.io/jasonhowmans/pen/DBdjNM?editors=1111

 

프로젝트 구조

- ERD 다이어그램

- 스프링 구조

웹 어플리케이션 ) 사용자가 주소 or 데이터 입력 등을 컨트롤러로 요청

컨트롤러 ) 사용자 요청 처리, 응답 생성하며 웹의 데이터를 매개변수로 서비스 함수 호출

서비스 ) 로그인 등 비즈니스 로직 수행, 매퍼 함수 호출

매퍼 ) 데이터베이스의 create, select, update, delete문 등의 sql 쿼리 작성

메인/자바

 

configuration (설정 패키지)

  • DBConfiguration : 외부 property 파일의 설정값 읽어오기, MyBatis 매퍼 파일의 위치,  도메인 클래스의 패키지 등 설정
  • SecurityConfig : 스프링 시큐리티 설정, 비밀번호 암호화 인코더

* HikariCP : JDBC(Java Database Connectivity)를 사용하여, 자바 어플리케이션에서 데이터베이스에 접속할 때 발생하는 연결 관리를 효과적으로 수행하는 커넥션 풀 라이브러리

* 커넥션 풀 : 데이터베이스 연결 생성 및 해제, 연결 재사용 등 관리

 

constant (enum 패키지)

  • Method : http 요청 메서드

domain (의도는 DTO 패키지, 웹과 서비스 간의 데이터 전송을 위한 객체 포함 패키지)

  • MemberDTO : 유효성 검사 + 회원 테이블 속성
  • ProductDTO : 상품 테이블 속성 + 카테고리 이름 (테이블에는 카테고리 번호만 있기 때문)
  • ProductImgDTO : 상품이미지 테이블 속성
  • CategoryDTO : 카테고리 테이블 속성
  • OrdersDTO : 주문 테이블 속성
  • OrderDetailDTO : 상세 주문 테이블 속성 + (회원id, 상품이름, 주문날짜, 상품별가격, 결제방법, 배송지, 배송메모, 주문상태, 수정일, 상품이미지명, 상품이미지경로)
  • CartDTO : 장바구니 테이블 속성 + (상품이름, 상품가격, 상품이미지명, 상품이미지경로)

controller (웹 어플리케이션의 사용자 요청을 처리, 응답 생성하는 패키지)

  • AdminController : 관리자 컨트롤러
    의존성 주입 : 회원서비스, 상품서비스

    모든 메서드는 관리자인지 확인
@GetMapping @PostMapping
/admin
/registerItem
상품 등록/수정 페이지 열기
* new ProductDTO(), 특정 ProductDTO(), 카테고리 Model에 추가
/admin
/registerItem
상품 등록하기
* 썸네일 이미지 저장, 이미지 목록 저장, 상품 정보 저장
/admin
/itemList
상품 목록,
삭제된 상품 목록 페이지 열기
/admin
/updateItem
상품 정보 수정
/admin/list 회원 목록 페이지 열기 /admin
/itemDelete
상품 내리기

 

  • MemberController : 회원 컨트롤러
    의존성 주입 : 회원서비스
@PostMapping
/member
/register
회원 등록
* 유효성 검사, 아이디 중복 검사
/member
/update
회원 정보 수정
* 유효성 검사
/member
/delete
회원 탈퇴

 

  • LoginController : 로그인 컨트롤러
    의존성 주입 : 회원서비스
@GetMapping @PostMapping
/member
/login
로그인, 회원가입 페이지 열기
* 로그인 상태 아닌지 확인,
new MemberDTO()
/member
/signin
로그인 요청
* 존재 회원 & 비밀번호 일치 시
HttpSession 생성
/member
/checkLoginStatus
로그인 상태 -> 마이페이지
로그아웃 상태 -> 로그인페이지
/member
/logout
로그아웃
* HttpSession 제거

 

  • HomeController : 홈페이지 이동 컨트롤러
    의존성 주입 : 회원서비스, 상품서비스, 이미지서비스, 주문서비스

    페이지 상단에 회원 이름이 출력되므로 모든 메서드는 회원 정보를 불러옴

@GetMapping
/home 메인 홈페이지 열기
/admin 관리자 페이지 열기
* 관리자인지 확인
/member
/myaccount
마이페이지 열기
* 로그인 상태 확인, 회원정보 전달
/member
/myOrder
주문 목록 페이지 열기
* 로그인 상태 확인
/product 상품 목록 페이지 열기
* 상품리스트 Model에 추가
/product-detail 상세 상품 페이지 열기
* 상품 정보, 이미지리스트,
new CartDTO() Model에 추가
* 조회 수 증가

 

  • CartController : 장바구니, 주문 컨트롤러
    의존성 주입 : 회원서비스, 장바구니서비스, 주문서비스

    모든 메서드는 로그인 상태인지 확인, 회원 정보를 불러옴 (HomeController와 동일메서드)
@GetMapping @PostMapping
/cart 장바구니 페이지 열기
* 장바구니리스트, new OrderDTO Model에 추가
/add-to-cart 장바구니 추가하기
    /cart
/delete
장바구니 상품 삭제하기
    /cart
/order
주문하기
* 주문 & 상세주문추가

 

mapper (매퍼.xml 인터페이스)

  • MemberMapper : 회원
    등록, 조회(by 회원번호, 회원아이디), 수정, 삭제, 탈퇴회원 장바구니 비우기, 목록
  • ProductMapper : 상품
    등록, 이미지등록, 카테고리list, 조회, 수정, 삭제, 삭제 상품 장바구니에서 제외, 목록, 삭제 상품 목록, 이미지수정, 조회수 증가, 재고 감소, 주문수 증가
  • ProductImgMapper : 상품 이미지
    등록, 한 이미지 정보, 수정, 삭제, 목록, 개수 세기
  • CartMapper : 장바구니
    등록, 수량만 수정, 삭제, 탈퇴 시 장바구니 삭제, 조회, 목록, 장바구니 개수 세기
  • OrderMapper : 주문
    등록, 상세주문 조회. 주문 시 장바구니 비우기, 목록

 

service (비즈니스 로직 패키지 : 각 매퍼함수 호출로 내용은 매퍼와 유사)

  • MemberService 인터페이스 & 구현체
  • ProductService 인터페이스 & 구현체
  • ProductImgService 인터페이스 & 구현체
  • CartService 인터페이스 & 구현체
  • OrderService 인터페이스 & 구현체

UiUtils (알림 메시지 alert, 페이지 이동)

 

메인 / 리소스

 

매퍼 쿼리 xml : 매퍼 구현체, sql 쿼리

 

템플릿 : html

  • cart > shopping-cart
  • fragment > common
  • home > index
  • item > product, product-detail
  • manage > admin, itemList, memberList, registerItem
  • member > my_orderList, myaccount, signup
  • utils > message-redirect, success-false

static

  • css
  • fonts
  • images
  • js
  • vendor

- 화면 흐름도

실행 결과

- 홈페이지

- 회원가입, 로그인

 

- 관리자 페이지

 

- 마이 페이지 (정보 수정)

- 마이페이지 (주문 조회)

- 상품 목록

- 상품 상세 정보 (로그인 상태)

- 상품 상세 정보 (로그아웃 상태)

- 재고보다 많은 수량 선택 불가

- 품절 시 장바구니 담기 불가 

 

- 장바구니

- 담아둔 상품의 재고 부족 시, 주문 방지를 위해 자동 삭제

 

진행 중 문제 사항과 해결

문제 사항 해결 방안
회원가입에 대한 유효성 검사 클래스를 따로 만들어서 컨트롤러에서 호출하였는데, 의존성 주입이 되지 않아 MapperServicenull로 받아와짐. @Component로 시도해도 동일 DTO에서 jakarta.validation.constraints를 이용하여 유효성 조건을 정하고, 컨트롤러에서 스프링의 유효성 기능인 @Valid를 이용하여 간단하게 구현
상세 상품 목록에서 카테고리 이름을 띄우려 했으나, 상품 테이블에는 카테고리 번호 속성만 있어서 어쩔 수 없이 카테고리 번호를 출력했음. DTO의 변수와 테이블 속성 외에 다른 변수 추가가 가능함을 알고, ProductDTOCateName 변수를 추가하여, mapper의 쿼리에서 조인을 통해 category 테이블의 cateName도 함께 데이터에 담음
html의 한 태그 내에 타임리프의 th:fieldth:value를 동시에 사용하니 null이 들어감 field가 아닌 nameth:value를 사용하여 해결
스프링 시큐리티를 로그인에 test한 후로 꺼두었다가 기능을 모두 구현하고 활성을 했는데, post와 delete 요청에서 에러와 함께 동작하지 않음 토큰을 추가하여 해결

 

문제점 및 한계

  • 고정적인 이미지 경로
    이미지가 저장되어 있는 경로와 상관없이 이미지를 선택하면, 해당 이미지를 프로젝트 폴더 내에 “product-01.jpg“와 같이 새롭게 저장하기를 의도하였으나, 에러가 해결되지 않아, 이미 프로젝트 폴더 내에 저장이 되어 있어야 정상적으로 이미지가 불러와짐.

, 이미지를 부를 때 static/images/products 폴더 내에서만 찾는데 해당 폴더에 이미지가 존재하지 않을 수도 있음.

  • SOLID 원칙 x
    기능을 최대한 구현하는 것을 우선으로 하여 SOLID 원칙을 고려하지 않음.
    즉, 유지보수에 대해 고려하지 않음.
    * SOLID 원칙 : 객체지향 소프트웨어 설계의 기본원리로서 다음의 5가지 원칙을 제공하여 코드의 가독성, 확장성, 유지보수성을 향상시키고, 객체 간의 결합을 낮춰 유연하고 재사용 가능한 코드를 작성하도록 한다. 단일 책임 원칙, 개방/폐쇄원칙, 리스코프 치환 원칙, 인터페이스 분리 원칙, 의존 역전 원칙
  • 비즈니스 로직을 컨트롤러에 구현
    스프링 구조에서는 보통 서비스에 예외처리와 비즈니스 로직을 구현하는데, 본 프로젝트에서는 수업 자료를 참고하여 컨트롤러에 예외처리와 비즈니스 로직을 구현함.

고찰

본 프로젝트를 진행할 때, 기능과 구조만 계획하고 페이지에 대한 흐름은 한 페이지를 완성하며 세워나갔다. 계획이 부실하여 진행하다가 어떤 흐름으로 가야할지 고민하느라 생각이 꼬이기도 했었다. 다음 프로젝트에서는 pigma 사이트를 이용하여 웹 디자인과 페이지 흐름에 대해 미리 계획할 필요성을 느꼈다.

프로젝트 진행 이유 중 하나였던 스프링 MVC 패턴CRUD에 대한 흐름을 이해할 수 있었다. 데이터가 어떻게 흘러가고, 매퍼, 서비스, 컨트롤러, 웹 어플리케이션의 연결 구조를 완벽히 이해하였다. 하지만, 한 가지 방법을 위주로 사용하여 각 클래스의 내부 함수를 효율적으로 구성하였다고는 생각하지 않았다. @ResponseBodyAJax 방식 등 여러 방법에 대해 공부할 필요와 SOLID 원칙을 잘 지킬 필요성을 느꼈다.

1차 계획에서는 기간이 부족하면 장바구니와 주문 기능까지는 어려울 수도 있다고 생각했지만, 두 기능을 모두 구현하였고, 기대했던 것보다 완성도가 있는 웹 어플리케이션을 제작하여, 스프링을 이용한 웹 프로젝트에 대해 자신감을 얻었고, 더 완벽히 할 수 있지 않을까 욕심이 생겼다.

 

 

 

728x90