첫 프로젝트였던 마취모를 마치며

0

ಥ_ಥ들어가기전에 앞서서...

첫 프로젝트를 시작할때는
'처음하는 프로젝트니까 하나하나 블로그에 기록해야지!'
현실은 그렇지만은 않았다.

프로젝트를 진행하는 와중 여러가지 변수가 생기면서 최우선적으로 해야할것과 미뤄야할것은 정했는데 그게 결국 블로그가 되었다.
나 이외에는 다른 팀원들은 처음써보는 타임리프,인텔리제이,스프링부트
다들 처음엔 헤매고 어려워했지만 금새 적응하고 잘헤쳐 나갔던거 같다

처음하는 웹개발 프로젝트 처음 써보는 도구들 어찌보면 다 낯선 환경이지만
나한테 부담없이 질문해주고 잘 배워줬던 동료들, 열심히 리더쉽을 발휘해줬던 형까지 모두가 있었기에 잘 끝냈던거 같다.

가끔 블로그를 쓴다고는 말은 했으나 이 글 까지 찾아보진 않을거 같다. 쑥쓰러워서 말 못했지만 정말 고맙고 다들 한달간 고생이 정말정말 많았다 특히 팀장형은 나랑 이틀밤을 같이 새느라 고생하셨다.

처음 학원에서 남아서 공부하고 같이 밥도 먹는 사람들끼리 팀원이 되고 마음이 잘 맞아서 정말 다행이다 팀원들을 잘만난거 같다.

뭐 블로그 하루에 하나씩 적자는게 매일 실패하면 어떠냐 계속 도전하면 되는거고 써가면 되는거지

왜 마취모인가

취지는 평소에 내가 좋아하는 애니메이션을 주제로 시작했다.
커뮤니티 + 쇼핑몰 + 경매를 넣고 싶었는데 규모가 너무 커지니
쇼핑몰은 커뮤니티 기능은 빼버렸다.

취미로 소장하고 있는 물건들을 경매에 올리고 경매를 진행시켜
이용자들에게 경매의 재미와 합리적인 소비를 이끌어 내고 싶어서 시작하였다.
대상은 마이너한 취미를 가진 사람들을 대상으로 진행하였고,
애니메이션은 어찌보면 필수 요소였다.

시간이 더 있었더라면 애니메이션 외에
신발,카메라,레트로 물품 같은것들도 카테고리에 추가 했을텐데
그 부분이 조금 아쉬운거 같다.

마취모라는 이름도 오타쿠들의 모음이 될 뻔 한 걸
"마이너한 취미를 가진 모임"으로 순화하였다.

사용된 기술들

타임리프,자바17,스프링부트 3.xx ,html css js 삼형제들,제이쿼리와 ajax, Oracle11,mybatis,InteliJ IDEA 그리고 우리의 빛과 소금이었던 부트스트랩 그리고 부트스트랩 스타터라는 사이트에서 템플릿을 퍼와서 조립했다

처음엔 스프링 시큐리티도 적용 시켜볼까 하다가 더 이상의 개척은 모두가 힘들거 같아서 패스 하였다.

사용한 이유와 사용후기

타임리프

우선 타임리프의 경우 학원에서는 서버 사이드 템플릿 엔진으로 jsp를 배웠고
머스터치,벨로시티,프리마커등 다양한 서버 사이드 엔진이 있지만 왜 타임리프를 쓰자 제안했냐면 단순히 그냥 스프링에서 밀어주고 있기 때문에 타임리프로 정했다. 타임리프에 장점보다는 단점으로 속도가 다른 사이드 템플릿 엔진들에 비해 느리다는것만 알고 시작해봤는데 쓰면 쓸수록 다양하게 활용 할 수 있고 코드가 태그 안에 있다보니 jsp보다 깔끔하고 무엇보다 th:에 값이 있으면 순수 html로 작성했던 값이 덮어씌어지다 보니 설계 단계에서 편리했다.

자바17

학원에서 알려주는건 자바8버전인데 우리 프로젝트에선 자바17를 사용했다
이것을 제시한 이유는 LTS 때문인것도 있지만 아무래도 15버전 부터 새로 추가된 record와 조금 더 간편한 문법등 때문이다 라고 팀원들에게 말했지만 솔직히 안 배웠던 최신버전을 사용해보고 싶었다

그래서 주로 VO들은 record를 사용했는데 장점이 굉장했다
일단 문법적으로 코드가 너무 깔끔해진다.

롬복에 종속되지도 않고 한 번 값이 세팅되면 바뀌지도 않아서 안정적이었다.

JsonNaming을 사용못한다는건 아쉬웠다 그래서 VO들은 DAO와 주로 사용하였고 DTO들은 Json을 받아올때 많이 사용했다.
근데 난 지금까지 VO는 불변객체로 DTO는 가변객체인줄 알았는다
근데 오늘 찾아보니 DTO는 일단 가변객체가 맞다.
근데 VO는 DTO처럼 가변객체가 될 수도 있고 불변 객체가 될 수도 있다는 말을 듣고 더 혼동이 왔다. 아 그리고 switch문이 되게 간결해졌다
var로 타입을 지정하지 않고 선언할 수 있다는 부분도 좋았던거 같지만
쓰진 않았다. 아 참 var키워드는 11도 쓸 수 있다

스프링부트

일단 젤 큰 이유는 힙하기 때문이다. 신입 개발자, 학원에서 아직 배우지도 못한 스프링부트로 개발을 한다는거 자체가 사람들에게 흥미롭게 다가왔나보다 바로 승낙해줬다 이건
확실히 이니셜라이저로 기본적인 디펜던시를 설정해서 띄우는게 편하다 정말로 초기 설정도 안 해도 되는 것도 그렇고 배우는데는 조금 걸렸지만 초반 설정단계를 거의 건너뛰다 싶이 했기 때문에 나름대로 시간을 아꼈던거 같다.

mybatis

JPA를 도입해보면 어떨까 했지만 시간 관계상 이거는 거절당했다.
근데 나도 인정하는게 사람들도 이걸 다 알아야하기에 거절 할 수 밖에 없는 것은 당연한거다 그냥 거절당할 용기로 말해봤지만 여튼 JPA는 거절당했다
그래서 mybatis 사용했다 인텔리제이에 mybatis플러그인을 쓰면 확실히 더 더 빠르게 생성이 가능하다 처음부터 잘 매핑시키면 인텔리제이에서 자동완성 까지 지원하기 때문에 빠르게빠르게 DAO를 찍어내듯이 했다
딱히 mybatis에 단점은 없는거 같다 새가 귀엽기도 하고

InteliJ IDEA

난 기존에 유료결제 하던게 있어서 그걸로 그대로 사용했다
팀원들은 대학생 이메일 정보가 남아있어서 그걸로 무료로 썼다
덕분에 인텔리제이를 사용했고 진짜 인텔리제이는 코드를 정말 빠르게 찍어낼 수 있게 도와준다(얼티메이트 기준) 자동완성이 너무너무 편리하다 정말...

부트스트랩

진짜 백엔드 밖에 없는 상태에서 부트스트랩은 빛이자 소금 젖과 꿀이 흐르는 땅이었다... 조금만 숙지하고 부트스트랩 스타터라는 페이지까지 잘 이용한다면 화면을 꾸미는건 정마 간단해졌다
그치만 특색은 없다 화면에 근데 화면이라도 찍어낼 수 있는게 어딘가 싶다

내가 구현한거

구매페이지

경매 기능

처음에는 단순히 값을 비교하고 더 크면 가격을 업데이트 시켜주면 될 줄 알았다.
근데 이것도 맞는 말이다 현재 최고 입찰가와 사용자가 입력한 금액과 비교해서 올려주기만 하면된다. 근데 진짜 이건 경매라는 단순한 생각에서 온 거 같았다.
처음 그렇게 값을 비교하고 리퀘스트를 내려주는거 까진 어떻게 쉽게 만들었고, 여러가지 생각을 해봤다.

그 중 제일 먼저 들었던 생각은
'근데 경매는 어떻게 끝내지?'

생각해보니 내가 아는 것중엔 경매를 끝낼 방법이 없었다
제일 처음 생각난건 사용자가 메인페이지에 들어왔을때 쿼리를 업데이트 시켜야하나?? 라는 단순한 생각뿐이었다.

근데 조금만 더 생각해보니
'그냥 이벤트를 발생 시키면 되는거 아닌가?'
근데 뭘 기준으로 발생시키지라는 생각과 더욱 머리가 복잡해져서
팀장형한테 물어보니 자바도 인터럽트 같은게 있을지도 모른다 해서
찾아보았더니 스케줄 이라는 기능이 있었고

어플리케이션이 시작되고 정해진 시간마다 새로고침 마냥 되는거 같았다
그래서 구글링 해보고 하니 쉽게 해결되었다. 역시 딱히 떠오르는 아이디어가 없으면 물어보는게 이야기 하면서 풀어나가는게 젤 나은 방식인거 같다.
내가 생각지도 못한걸 상대는 한 번쯤은 해봤거나 경험 해봤을지도 모르니

입찰

장바구니

일반 쇼핑몰같은 경우 장바구니에 같은 물건을 여러개 담을 수 있겠지만 우리는 그게 불가능 하기 때문에 장바구니에 중복으로 등록되지 못하도록 처리하였다

찜 기능

그냥 단순히 찜 기능이다 괜찮은 버튼 모양을 찾다가
https://www.youtube.com/watch?v=BjjzptCjehU
이 분이 올린 css를 사용했다

자바 스크립트가 없는 좋아요다보니 자바스크립트를 추가 해주었고 게시글에 찜을 누른 이력이 있으면 하트 모양을 유지시키게 하였다

즉시구매

이건 그냥 즉시구매다...

알림기능

처음 프론트에 메인화면을 디자인을 해줬던 팀원 누나가 있었는데
거기에 보면 알람이 있었다 빼도 되지만 학원에서 배운건 crud 게시판이 전부였고 crud 게시판 보다는 안 해본걸 해보고 싶어서 저런 자잘자잘한것들을 맡아서 했다. 물론 그렇다고 기본을 안 한건 아니다. 나름 그래도 독학으로 책 읽어가며 crud 게시판도 만들어보고 그랬던지라 진짜 안 해본걸 해보고 싶었다.

우선 만든건 경매가 끝난 상품을 기준으로 알람을 전송할려했다.
근데 여기서도 생각해봐야 할게 경매가 끝났다는건 두 가지 경우다

알람 데이터 중복문제

입찰자가 존재하여서 판매가 완료 되었냐 입찰자가 발생하지 않은 상태에서
경매가 종료되었느냐 두 가지 경우다 그걸 어떻게 분기 처리를 할까 고민을 하다가 그냥 DB에서 Insert시켜주면 되겠다 싶어서 DB에서 Insert 시켜주고 스케줄러가 그 Insert문을 계속 실행 시켜주게 했는데
쿼리를 잘못 짰던게 중복된 값이 계속해서 쌓여서 올라갔다
스케줄이 10초마다 반복되게 해놨는데 10초마다 똑같은 알람이 계속 쌓였고
중복된 값은 Insert하지 못하게 DB에서 바꿔줬다.

알람 html에 출력 문제

컨트롤러에서 모델에 값을 담아서 같이 보내주면 이게 문제라 생각도 못했을텐데
fragment로 해더와 푸터를 분리해두었고 그때 당시에 생각으론 다시 헤더와 푸터를 합쳐서
각 페이지마다 알람을 모델에 담아야하나... 생각 했었고 그 방법은 너무 비효율적이고
다른 사이트들을 보니 푸터와 해더를 분리해둔거 처럼 되어있었는데 그렇다는건 방법이 이것도 효율적인 방법이 있다 생각하여 커뮤니팅에 질문 해보았다

고마운 분이 답글을 달아주셨고

ControllerAdvice를 이용해 해더에 들어갈 값들을 정의 해두었더니 잘 해결되었다

주문 페이지

아임포트 API

아임포트를 사용해 카카오페이,토스페이,신용카드 결제를 구현 하였다

어려웠던점은 프론트와 함께 API를 사용해보는건 처음이라 많이 당황했지만
구글링으로 자료들이 있길래 참고하였다

기능은 단순 결제 기능도 있지만

사용자가 결제 금액이나 사용한 포인트를 조작하여 결제를 하였을경우 결제가 취소가 되게끔 막아놨다

자잘자잘한 기능들

검색 기능들

마찬가지로 해더에서 검색기능을 지원하기 때문에 간단하게 구현 했었는데
문제는 사용자가 선택한 검색 유형과 입력값이 검색을 하고 나면 input태그에서 계속 사라졌었다 이걸 해결하기위해 세션으로 처리하였다 근데 세션으로 처리 하니 다른 페이지에 들어가더라도
세션이 남아 있어서 이걸 어떻게 하면 좋을지 고민하다가 인터셉터를 이용해 다른 페이지에 들어갔을때 세션을 삭제 시켰당

검색 결과가 없을때

검색 결과가 존재 할 때

주문 에러 페이지

구매페이지에 없는 상품번호를 url에 입력하였을때 NPE가 발생하였는데 이걸
예외핸들러를 만들어서 사용자에게 보여주는 페이지를 처리하였다

코드

에러 페이지

서버에서 에러가 발생하였을때도 처리하였다

실행화면

멤버접근만 가능하게 AOP로 구현

멤버만 접근 가능한 주소를 항상 컨트롤러에서 세션으로 검사했는데
컨트롤러에서 검사하는건 단일책임 원칙에서 벗어나는거 같아 AOP로 세션체크를 처리하였다

0개의 댓글