JSL シネマ REMASTER 🎬

レガシーシステムから
モダンアーキテクチャへの進化

単なる機能実装を超え、堅牢なエンタープライズシステムを構築した
バックエンドエンジニアとしての開発の軌跡。

Designed & Developed by

朴潤正 (パク ユンジョン)

TABLE OF CONTENTS

目次 (Index)

01. プロジェクト概要 Project Overview

02. 技術スタックと設計 Tech Stack & ERD

03. コア機能:認証とUI/UX Security & User Experience

04. コア機能:マスターデータ管理 CMS & Master Data

05. コア機能:予約とトランザクション Concurrency & ACID Transaction

06. コア機能:非同期レビューと同期 Async Review & State Sync

07. トラブルシューティング Troubleshooting

08. プロジェクトを通じた成長 Conclusion & Retrospective

01. PROJECT OVERVIEW

プロジェクト概要

開発の背景 (Background)

既存のJSPベースのレガシーシステムが抱えていた、セキュリティの脆弱性と決済トランザクション管理の限界を克服するため。

プロジェクトの目的 (Objective)

単に「動くもの」を作るのではなく、日本のSI現場で求められるバックエンドの基礎体力(SQL制御・例外処理)と堅牢なアーキテクチャ設計能力を証明すること。

アプローチ (Approach)

最新の Spring Boot 3.5.9 と MyBatis を導入し、データ整合性(ACID)を保証するシステムへと全面リファクタリング(Remaster)。

System Architecture Diagram

01. PROJECT OVERVIEW - Directory Structure

プロジェクト概要 (パッケージ構造と役割 : 52Files)

  • src/main/java/com/cinema
    • config/ : 2 Settings
      SecurityConfig, WebMvcConfig
    • controller/: 10 Endpoints
      Admin(Api, Movie, Schedule)/Main/Member/Movie/ReviewApi/Ticket(Api)Controller
    • service/: 4 Modules
      CustomUserDetailsService, Member/Movie/TicketService
    • mapper/: 6 Interfaces
      Admin/Member/Movie/Review/Reservation/ScheduleMapper
    • domain/ & dto/: 5 Models
      Member, Movie, Schedule & CustomUserDetails
  • src/main/resources
    • mapper/: 6 XML Queries
      AdminMapper.xml, MemberMapper.xml, MovieMapper.xml, ReservationMapper.xml, ReviewMapper.xml, ScheduleMapper.xml
    • templates/ & static/: 19 Views
      admin(Dashboard, Movie_list, Movie_modify, Movie_Register, Reservation_list, Schedule_register) / layout / member(join, login) / movie(detail, list) / support(faq, privacy, terms) / ticket(my, reserve, seat) / index / css

config & dto

Spring Securityの認証フィルタおよび権限ルーティング設定と、データ転送オブジェクト(DTO)の管理。

controller

画面遷移(View)を担当する一般コントローラーと、非同期通信(AJAX)のJSONデータを返す ApiController の分離。

service

コアビジネスロジックの実装階層。決済や座席予約における @Transactional を用いたデータ整合性の保証。

mapper & domain

MyBatisインターフェースとXMLマッピングによるSQL制御。Entity層(domain)を通じたDBテーブルとの1:1マッピング。

02. TECH STACK & ER-D

技術スタックとデータベース設計

Java 17 & Spring Boot 3.5.10

コアビジネスロジックの実装に集中。

MyBatis 3 & MySQL 8.0

JPAに依存せずMyBatisを採用。日本のSI現場で求められる複雑なクエリの直接制御とチューニング能力を証明。

Spring Security 6

SecurityFilterChain (Lambda DSL) を適用した堅牢な認証・認可ロジックの実装。

Vanilla JS & Fetch API

React等に依存せず、DOM操作と非同期通信(AJAX)の原理を深く理解するため純粋なJSに固執。

Git & GitHub

コンフリクト解決やコミット履歴の管理を通じた、実務的なバージョン管理の経験。

Entity Relationship Diagram : マウスを乗せるとZOOM-IN

ER-Diagram
外部キー(FK)参照整合性 Auditing (履歴追跡) 予約状態(Status)管理

03. CORE FEATURE: SECURITY & UI/UX

コア機能:認証とユーザー体験

セキュリティと権限制御

CustomUserDetails と Spring Security を用いた堅牢な認証システム。USER と ADMIN の権限を徹底的に分離し、不正なアクセスを遮断します。

非同期トーストUIによるUX向上

ログインや会員登録時、無機質な基本アラートではなく、SweetAlert2 を用いた洗練されたトーストポップアップを導入し、ユーザー離脱率を低下させます。

[Deep Dive] PRGパターンと状態伝達

課題: CUD(作成/更新/削除)処理後のリロードによるデータの二重送信。
解決: 処理後に必ずRedirectを行う PRG (Post-Redirect-Get) パターン を徹底。さらに addFlashAttribute を活用し、URLを汚さずにサーバーセッション経由で1回限りの安全なメッセージ伝達を実現しました。

認証とトーストUI デモ

  • Spring Securityを用いたログインと権限制御フロー
  • SweetAlert2を活用した画面遷移のないToastフィードバック

04. CORE FEATURE: CMS(Content Management System) & MASTER DATA

コア機能:マスターデータ管理 (管理者システム)

MultipartFileとI/O制御

映画のポスター画像登録時、MultipartFile インターフェースを活用。UUIDを用いてファイル名の重複を防ぎ、DBのテキストデータと物理ファイルの保存を同期させるI/Oトランザクションを実装しました。

多対多(N:M)関係の解消

映画(1)と上映館(1)という独立したマスターデータを結びつけ、「スケジュール(N)」を動的に生成する直感的なCMS(コンテンツ管理システム)UIを構築しました。

[Deep Dive] データバインディングの最適化

課題: フロントエンドの時間データ形式とDB(Java)の形式不一致。
解決: HTML5の <input type="datetime-local"> から送信されるISO 8601文字列を、Springの @DateTimeFormat を活用してJavaの LocalDateTime へシームレスにバインディング。パース例外(Parse Exception)を未然に防ぎました。

CMSデモンストレーション

  • ポスター画像の物理アップロードと静的リソースマッピング
  • 映画・上映館・日時を組み合わせたスケジュールの動的生成

05. CORE FEATURE: CONCURRENCY & ACID TRANSACTION

コア機能:予約とトランザクション (同時実行制御と決済)

同時実行制御と座席先占

複数ユーザーによる同一座席への同時アクセス(オーバーブッキング)を防ぐため、DBの制約条件と分離レベル(Isolation Level)を活用したリアルタイムな座席先占ロジックを実装しました。

外部決済API(PortOne)連携

フロントエンドで安全に決済モジュールを呼び出し、サーバー側で検証(Validation)を行うことで、データの改ざんを防ぎ信頼性の高い決済プロセスを構築しました。

[Deep Dive] ACID原則と完全なロールバック

課題: 決済完了後にシステムエラーが発生した場合のデータ不整合。
解決: 「座席確保 ➔ 決済実行 ➔ ポイント減算 ➔ チケット発行」 の一連のプロセスを、Service階層で単一の @Transactional にバインド(Bind)。いずれかの段階で例外(Exception)が発生した場合は即座に完全なロールバック(Rollback)を行い、データ無欠性(Integrity)を保証しました。

予約・決済トランザクション デモ

  • Fetch APIを用いたリアルタイム座席状態の同期
  • PortOne API呼び出しと決済完了後のチケット自動発行フロー

06. CORE FEATURE: ASYNC REVIEW & STATE SYNC

コア機能:非同期レビューと状態同期 (コミュニティ機能)

非同期CRUDとインライン編集

Fetch APIを活用し、ページ遷移なしでレビューの作成・修正・削除が可能。修正時にはモーダルを開かず、その場で入力フォームに切り替わるインラインエディティング(Inline Editing)を実装しました。

クライアント状態同期による負荷軽減

レビュー更新の度にサーバーへ平均スコアの集計クエリを投げるのではなく、フロント側のJS reduce() 関数で計算し、DOMを直接更新する状態同期(State Synchronization)でサーバー負荷を軽減しました。

[Deep Dive] 多層防御 (IDOR対策)

課題: フロントエンドのボタン非表示だけでは、APIの直接叩きによるデータ改ざん(IDOR攻撃)を防げない。
解決: Controller層で Spring Security の Principal.getName() から認証情報を取得し、MyBatisの WHERE userid = #{userid} 条件と結合。他人のデータを絶対に操作できないよう、バックエンドでの交差検証(Cross-validation)を徹底しました。

非同期レビュー&状態同期 デモ

  • ページリロードなしでのレビュー登録と平均評価の即時反映
  • シームレスなUXを提供するインラインエディティング

07. TROUBLESHOOTING & PROBLEM SOLVING

トラブルシューティングと問題解決

  1. AmbiguousMappingException

問題: サーバー初期化時、HandlerMappingで衝突が発生し起動失敗。
原因と解決: MainControllerMemberController の両方に GET /login が存在。Springの「1つのURLは1つのメソッドにマッピングされる」という鉄則に基づき、スタブ(Stub)コードを削除してルーティングを整理しました。

  2. Git履歴の乖離と強制同期

問題: ローカルとリモートの履歴(History)が乖離し git pull が競合(Conflict)。
原因と解決: Gitの保護メカニズムが作動したため、誤ったローカル変更を破棄。git reset --hard origin/main コマンドを使用してリモートの最新状態に強制同期させることで解決しました。

  3. PRGパターンとMVCデバッグ

問題: CUD作業後のリダイレクトとデータ検証の困難。
解決: クエリストリングではなく addFlashAttribute で安全な1回限りのToast UI伝達を実現。エラー発生時は、View ➔ Controller ➔ DB の順でデータのライフサイクルを逆追跡し、バインディング漏れを正確にデバッグしました。

  4. 複数座席の動的クエリバインディング

問題: 複数座席予約時、単一Stringの伝達によるMyBatis IN 句のバインディング失敗。
解決: String.split()List<String> にパース。動的SQL(<foreach>)を活用し、要求数とロックを確保した座席数を交差検証するロジックへ改編。予約失敗率を0%へ改善しました。

08. CONCLUSION & RETROSPECTIVE

プロジェクトを通じた成長 (総括と今後の目標)

  1. アーキテクチャの本質的な理解

レガシーJSPからSpring Bootへの移行を通じ、MVCパターンの本質と「関心事の分離(SoC)」の重要性を体感しました。各レイヤー(Controller, Service, Mapper)の責任を明確にする設計能力を養いました。

  2. データ保護とバックエンドの責任

トランザクション(ACID)制御と多層防御(Security)の実装により、企業が最も重視する「データ無欠性(Data Integrity)」を担保するロジックと、その重みを深く理解しました。

  3. 自立的な問題解決能力

単なる勘に頼るデバッグではなく、エラーログを精緻に分析し、公式ドキュメントやフレームワークの基本原則に立ち返ってバグを根本から解決するエンジニアリングの姿勢を獲得しました。

「コーダー」から
「エンジニア」

本プロジェクトは、単なる機能実装の練習ではなく、
安定したシステムを設計・運用する
バックエンドエンジニアとしての第一歩です。

Thank You!

ご清聴ありがとうございました。

GitHub Repository
1 / 2