
프로젝트 한눈에 보기
해수욕장 정보와 날씨, 이용자의 리뷰를 한곳에서 살펴보고 취향에 맞는 바다를 찾는 여행 서비스입니다. 4인 팀의 팀장으로 서비스 흐름과 UX/UI를 설계하고, 메인 추천·BBTI·지역 탐색·해수욕장 정보 화면을 구현했습니다.
- 개발 기간
- 2024.03.21 ~ 2024.04.19
- 프로젝트 형태
- 4인 팀 · 전원 프런트엔드·백엔드 개발
- 기술 스택
- Spring MVC · MyBatis · JSP · OracleDB
- 제공 상태
- 공개 저장소 · README에 기능별 시연 자료 제공
내가 맡은 일
팀장으로 일정과 요구사항, 전체 로직과 유스케이스를 정리하고 GitHub와 코드 관리를 맡았습니다. 메인 검색·추천, BBTI 로직과 이미지, 지역 선택과 해수욕장 정보·지도, 리뷰 화면의 디자인과 전체 CSS를 담당했습니다. 기상 데이터 처리, 회원·마이페이지, 리뷰·문의 CRUD는 팀원과 역할을 나누어 개발했습니다.
대표 기록
바다 여행에 필요한 정보를 한곳에
바다 여행을 계획할 때 날씨와 바다 상태, 편의시설, 실제 방문 후기를 따로 찾아봐야 하는 불편에서 출발했습니다. 해수욕장 기본 정보에 공공 API의 기상 정보와 이용자 리뷰를 연결해, 여행지를 고르는 데 필요한 정보를 함께 제공하는 서비스를 기획했습니다.
- 지역·추천으로 탐색
지역을 검색하거나 지도를 선택하고, 기본·성향·위치 추천에서 관심 있는 바다를 찾습니다.
- 해수욕장 정보 확인
사진과 설명, 주소·편의시설·주변 특징과 날씨 정보를 살펴봅니다.
- 리뷰로 비교
방문자의 별점과 해시태그, 리뷰를 읽고 여행지를 비교합니다.
- 경험 나누기
방문 후 리뷰와 댓글을 남기고 다른 이용자와 바다 여행 경험을 공유합니다.
서비스 전체에는 바다 여행의 가벼운 분위기를, 리뷰 영역에는 미니홈피를 떠올리는 레트로·도트 디자인을 적용했습니다. 추천 결과에서 해수욕장 정보와 리뷰로 이동할 수 있도록 화면 간 연결도 함께 구성했습니다.
담당 범위와 기술
4명이 기능별로 프런트엔드와 백엔드를 함께 맡았습니다. 저는 팀장으로 전체 흐름을 정리하면서 검색·추천·BBTI와 해수욕장 정보 영역의 로직과 화면을 연결했습니다. 리뷰 영역에서는 팀원이 구현한 기능에 맞춰 화면 디자인과 CSS를 담당했습니다.
| 영역 | 기술 | 적용한 부분 |
|---|---|---|
| 백엔드 | Java · Spring MVC | 페이지 요청 처리와 추천·검색·BBTI 저장 기능 |
| 데이터 | Oracle DB · MyBatis | 해수욕장·회원·리뷰 저장, 해시태그·별점 집계와 추천 조회 |
| 화면 | JSP · Tiles · JavaScript · jQuery · CSS | 공통 레이아웃과 기능별 화면, AJAX 요청, BBTI 문항과 결과 표시 |
| 지도·공공 데이터 | Kakao Maps · 기상청·한국천문연구원 API | 해수욕장 위치 표시와 길찾기 연결, 팀 단위의 날씨·일출·일몰 정보 제공 |
| 실행·협업 | Tomcat · Maven · GitHub · Google Spreadsheet | 웹 애플리케이션 구성, 저장소와 일정·작업 관리 |
| 담당 | 범위 |
|---|---|
| 정지은 | 팀 리딩, 전체 로직·UX/UI·유스케이스, 메인 검색·추천, BBTI, 지역 탐색·해수욕장 정보·지도, 전체 CSS·GitHub 관리 |
| 한지수 | 기상 데이터 수집·가공과 날씨 요약·상세, 순위 페이지와 데이터 통합, 회원가입 보완 |
| 정지수 | 회원 관리, 문의 게시판·이메일 문의, 지역별 채팅과 신고 기능 |
| 홍문선 | DB·ERD 관리, 리뷰·댓글·추천·신고, 로그인·마이페이지, 공지·이벤트 화면 |
Spring MVC와 JSP로 연결한 서비스
- JSP · jQuery 웹
Tiles 공통 레이아웃 · 지역 선택과 BBTI · 추천 결과 AJAX 조회 · 브라우저 위치와 Kakao Maps 사용
공통 API 요청
Controller에서 페이지와 데이터 요청 처리 · MyBatis Mapper로 조회·저장 · 기상 API 응답을 화면 데이터에 연결
데이터 저장 · 외부 서비스 연동
- Oracle DB
해수욕장 기본·상세 정보 · BBTI 성향과 회원 · 리뷰·해시태그·별점 · 문의 데이터
- 공공 기상·천문 API
예보 · 수온·파고 · 기상 특보 · 일출·일몰 정보 제공
페이지 이동은 Spring MVC가 JSP에 데이터를 전달하는 방식으로 구성하고, 메인 추천과 지역별 해수욕장 목록은 AJAX로 조회하도록 했습니다. 추천 요청에서는 MyBatis로 후보를 찾은 뒤 해수욕장 사진, 평균 별점, 리뷰 수와 대표 해시태그를 묶어 JSON으로 반환합니다. 카카오 지도는 브라우저에서 SDK를 호출해 저장된 좌표로 마커를 표시하고 지도 상세·길찾기 링크를 연결합니다.
성향·평점·위치에 따라 나눈 추천
메인 화면에서 여행지를 바로 고를 수 있도록 성향 정보의 유무와 사용자의 선택에 따라 추천 기준을 나눴습니다. BBTI 결과가 있으면 성향과 리뷰 해시태그를 연결하고, 결과가 없으면 리뷰 평균 별점을 기준으로 추천합니다. 위치 추천을 선택하면 현재 좌표에서 가까운 바다를 찾습니다.
| 유형 | 입력 | 선택 기준 |
|---|---|---|
| 기본 추천 | 해수욕장별 리뷰 수·별점 | 리뷰가 3개 이상인 해수욕장 중 평균 별점이 높은 1개 선택 |
| BBTI 추천 | 회원 성향 코드·유형별 해시태그·리뷰 해시태그 | 성향에 정의된 태그와 일치하는 리뷰 태그의 개수가 가장 많은 해수욕장 선택 |
| 위치 추천 | 브라우저의 현재 위치·해수욕장 좌표 | DB의 거리 계산 함수를 호출하고 거리 최솟값에 해당하는 해수욕장 조회 |
- 성향 태그 조회
회원의 BBTI 코드에 미리 연결해 둔 해시태그를 가져옵니다.
- 리뷰 태그 분리
해수욕장별 리뷰 해시태그를 모으고 공백으로 구분된 태그를 각각 분리합니다.
- 일치 개수 집계
성향 태그와 일치하는 리뷰 태그의 개수를 해수욕장별로 셉니다.
- 추천 정보 표시
집계 순위가 가장 높은 바다를 선택하고 별점·리뷰 수·대표 태그를 함께 보여줍니다.
위치 추천에서는 브라우저가 얻은 위도·경도를 서버로 보내고, 해수욕장 좌표와 비교한 결과를 직선거리로 안내합니다. 추천 카드에서 해당 바다의 상세 정보와 리뷰로 바로 이동하도록 구성했습니다.
성향 테스트를 회원 정보와 추천에 연결하기
BBTI는 바다 여행 성향을 8가지 유형으로 나누는 테스트입니다. 9개 성향 문항에서 세 쌍의 선택값을 각각 집계하고, 각 쌍에서 더 많이 선택한 값을 조합해 유형 코드를 만듭니다. 문항과 결과 이미지, 진행 화면과 저장 로직을 함께 구현했습니다.
- 문항에 응답
JavaScript에서 E/I, A/P, F/N 선택 횟수를 각각 누적합니다.
- 유형 결과 확인
세 축의 결과를 조합해 EAF·IPN 등 8개 유형 중 하나와 결과 이미지를 보여줍니다.
- 선택·저장
회원의 BBTI 정보를 서버에 저장하고, 기존 결과가 있으면 변경 여부를 확인합니다.
- 추천에 적용
저장된 유형에 연결된 태그를 메인 추천의 조회 조건으로 사용합니다.
- 직접 선택과 다시 하기테스트 결과 외에도 전체 유형 목록에서 원하는 성향을 선택하거나 테스트를 처음부터 다시 진행할 수 있도록 했습니다.
- 기존 결과 변경이미 결과가 있는 회원은 기존 값을 유지할지 새 결과로 덮어쓸지 선택하도록 했습니다.
- 비회원의 다음 단계로그인하지 않은 사용자가 결과 저장을 선택하면 BBTI 값을 로그인·회원가입 흐름으로 전달하도록 구성했습니다.
지역 선택에서 해수욕장 상세 정보까지
지역을 검색하거나 전국 지도에서 가고 싶은 지역을 선택하면 해당 지역의 해수욕장 목록을 불러옵니다. 목록에서 해수욕장을 고르면 사진·설명·주소·편의시설·주변 특징과 대표 해시태그를 보여주고, 팀원이 구현한 날씨 요약을 같은 결과 화면에 배치했습니다.
- 지역별 탐색지역 선택값을 서버에 전달하고, 조회한 해수욕장 목록을 화면에 표시했습니다. 데이터가 없는 지역에는 안내와 해수욕장 추가 문의 링크를 제공했습니다.
- 지도와 외부 이동저장된 위도·경도로 Kakao Maps에 마커와 정보창을 띄우고, 지도 상세 보기와 길찾기 링크를 연결했습니다.
- 방문 판단에 필요한 정보해수욕장의 시설·주변 특징과 리뷰의 대표 해시태그를 함께 보여주고, 날씨 상세 화면으로 이동할 수 있도록 구성했습니다.
팀 리딩과 기능별 화면 연결
- 요구사항과 진행 관리팀장으로 요구사항과 일정 관리 문서를 작성하고, Google Spreadsheet로 작업을 정리했습니다. 유스케이스 다이어그램으로 서비스의 사용자별 기능과 흐름도 정리했습니다.
- 코드와 저장소 관리GitHub와 커밋 컨벤션을 관리하고 코드 검토를 맡았습니다. 기능과 역할, 사용 기술과 결과물을 README에 정리했습니다.
- 화면의 일관성메인·검색·추천·BBTI를 구현하고, 전체 페이지 CSS를 관리했습니다. 리뷰 영역은 팀원이 구현한 기능에 맞춰 레트로·도트 테마의 화면을 구성했습니다.
하나의 기능만 완성하는 것에 더해, 추천에서 상세 정보와 리뷰로 이어지는 전체 이용 흐름을 함께 다뤘습니다. 프런트엔드에서는 JavaScript와 CSS로 화면을 직접 구성했고, 백엔드에서는 사용자 입력이 어떤 조회와 저장으로 이어지는지 연결하는 경험을 쌓았습니다.
해시태그 집계에서 배운 데이터 모델링
문자열로 저장한 태그는 집계할 때 다시 분리해야 했습니다.
리뷰의 해시태그를 공백으로 구분한 문자열로 보관했기 때문에, 대표 태그와 BBTI 추천을 조회할 때 문자열을 개별 태그로 풀어야 했습니다. REGEXP_SUBSTR와 계층형 조회, LISTAGG 등을 조합해 태그를 분리·집계하면서 쿼리가 복잡해졌고, DB 모델링 단계에서 정규화를 고려해야 한다는 점을 배웠습니다.
향후 리팩토링 계획
다시 발전시킨다면 추천 방식뿐 아니라 추천의 바탕이 되는 데이터 구조와 수집 과정도 함께 개선하고 싶습니다. 문자열 중심의 해시태그 구조를 정리하고, 해수욕장 정보와 리뷰를 지속적으로 보완해 사용자의 여행 목적에 맞는 바다를 추천하는 방향으로 리팩토링할 계획입니다.
- DB 정규화와 기존 데이터 이관해시태그를 별도 테이블로 분리하고 리뷰·태그, 성향·태그 관계를 명시해 문자열 분리 대신 조인과 집계로 조회하려 합니다. 기존 태그의 표기와 중복을 정리한 뒤 데이터를 이관하고, 이관 전후의 집계 결과를 비교할 계획입니다.
- 여행 목적을 반영하는 추천BBTI 태그의 단순 일치 횟수에 더해 편의시설, 방문 목적, 거리와 리뷰의 양·최신성을 함께 고려하는 방법을 실험하고 싶습니다. 후보가 없거나 점수가 같은 경우의 기준을 정하고, 추천 이유를 사용자가 이해할 수 있도록 보여주려 합니다.
- 해수욕장 정보 수집·갱신 자동화공공데이터와 외부 API에서 정보를 가져오는 수집 작업을 화면 조회와 분리하고, 해수욕장별 기준 ID로 출처가 다른 정보를 연결할 계획입니다. 주소·시설·개장 정보와 날씨의 갱신 주기를 구분하고, 마지막 갱신 시각과 수집 실패를 기록해 오래되거나 누락된 정보를 확인할 수 있게 하려 합니다.
- 외부 리뷰 크롤링과 데이터 정제수집 가능한 공개 리뷰를 크롤링해 해수욕장의 특징을 보완하는 방안을 검토하고 있습니다. 출처·원문 링크·수집 시점을 보관하고 중복·스팸·해수욕장 매칭 오류를 정리한 뒤, 방문 목적이나 시설 관련 키워드 추출에 활용하고 싶습니다. 외부 리뷰는 서비스에 직접 작성한 리뷰와 구분해 관리할 계획입니다.
- 추천 품질과 실패 상황 검증기존의 평점·태그 기반 추천을 비교 기준으로 삼고, 목적에 맞는 결과가 나오는지와 추천 후보의 다양성을 확인하려 합니다. 리뷰 부족, 위치 권한 거부, 외부 API 실패, 오래된 정보 같은 상황도 테스트하고 사용자 피드백으로 개선점을 점검할 계획입니다.
- 스키마 정리
태그 관계 정규화 · 기존 데이터 이관과 결과 대조
- 정보 갱신 체계
해수욕장 기준 ID · 출처별 수집 · 갱신 주기와 실패 기록
- 리뷰 데이터 보완
외부 리뷰 수집 · 중복 제거 · 키워드 정제와 출처 구분
- 추천 실험·평가
여행 조건 반영 · 기존 방식과 비교 · 예외 처리와 사용자 확인