091
[KINO][JAVA/Spring Boot] 좌석 선정 및 예약: WebSocket 응용(2) 본문
Programming Language/Java
[KINO][JAVA/Spring Boot] 좌석 선정 및 예약: WebSocket 응용(2)
공구일 2026. 3. 28. 04:40728x90
*이 글은 프로젝트 KINO CINEMA의 개발 내용을 정리해놓은 글입니다.*
2. SeatSelectRequestDTO & SeatStautsResponseDTO->SeatBookingResponseDTO
- SeatSelectRequestDTO: 클라이언트에서 서버로 요청하는 데이터로, 이름 그대로 선택된 좌석과 관련된 자료가 넘어옵니다.
package com.cinema.kino.dto;
//import문 생략
@Getter
@Setter
public class SeatSelectRequestDTO {
private Long screeningId;
private Long memberId;
private Long guestId;
private List<TicketRequest> tickets;
@Getter @Setter
public static class TicketRequest {
private Long seatId;
private PriceType priceType;
}
}
- SeatBookingResponseDTO: 서버에서 클라이언트로 응답하는 데이터로, 상영정보가 넘어왔을 때 좌석 자리 및 상영 시간과 관련된 것을 보여주기 위한 자료입니다.
package com.cinema.kino.dto;
//import문 생략
@Getter
@AllArgsConstructor
public class SeatBookingResponseDTO {
private ScreeningInfo screeningInfo; //상영/영화/가격 정보 (단 1번만 전송)
private List<SeatInfo> seats; //좌석 목록 배열
// 팩토리 메서드, 서비스 단에서 호출하기 쉽게 만듦
public static SeatBookingResponseDTO of(Screening screening, List<ScreeningSeat> screeningSeats, Map<String, Integer> prices) {
ScreeningInfo info = ScreeningInfo.from(screening, prices);
List<SeatInfo> seatList = screeningSeats.stream()
.map(SeatInfo::from)
.collect(Collectors.toList());
return new SeatBookingResponseDTO(info, seatList);
}
/* ========================
1. 공통 상영 정보
======================== */
@Getter
@AllArgsConstructor
public static class ScreeningInfo {
private Long theaterId;
private String theaterName;
private Long screeningId;
private String screenName;
private String screenType;
private Long movieId;
private String movieTitle;
private String ageRating;
private String posterUrl;
private LocalDateTime startTime;
private LocalDateTime endTime;
// 가격 정보
private Integer priceAdult;
private Integer priceYouth;
private Integer priceSenior;
private Integer priceSpecial;
public static ScreeningInfo from(Screening screening, Map<String, Integer> prices) {
var movie = screening.getMovie();
var screen = screening.getScreen();
var theater = screen.getTheater();
return new ScreeningInfo(
theater.getId(), theater.getName(),
screening.getId(), screen.getName(), screen.getScreenType().getValue(),
movie.getId(), movie.getTitle(), movie.getAgeRating().name(), movie.getPosterUrl(),
screening.getStartTime(), screening.getEndTime(),
prices.getOrDefault("ADULT", 15000),
prices.getOrDefault("YOUTH", 12000),
prices.getOrDefault("SENIOR", 10000),
prices.getOrDefault("SPECIAL", 10000)
);
}
}
/* ========================
2. 개별 좌석 정보
======================== */
@Getter
@AllArgsConstructor
public static class SeatInfo {
private Long seatId;
private String seatRow;
private int seatNumber;
private String status;
private String seatType;
private Integer posX;
private Integer posY;
private Long memberId;
private Long guestId;
public static SeatInfo from(ScreeningSeat ss) {
var seat = ss.getSeat();
return new SeatInfo(
seat.getId(), seat.getSeatRow(), seat.getSeatNumber(),
ss.getStatus().name(), seat.getSeatType().name(),
seat.getPosX(), seat.getPosY(),
ss.getHeldByMember() != null ? ss.getHeldByMember().getId() : null,
ss.getHeldByGuest() != null ? ss.getHeldByGuest().getId() : null
);
}
}
}
-> 팩토리 메서드란 객체 생성자 대신 static 메서드로 처리하는 방식을 사용하고있으며, of를 사용해 여러 개의 매개변수를 입력받아, 하나의 적합한 인스턴스로 집계 및 병합하여 반환하는 메서드입니다. 팩토리 메서드는 생성자가 아니지만, 생성자를 래핑하여 내부에서 대신 호출해주는 프로기 역할을 하는 정적 메서드입니다.
- SeatStautsResponseDTO(삭제, 이전 WebSocketController 때 사용): 이전에 사용했던 응답 데이터인데, 같은 자료가 반복적으로 발송되기 때문에 리팩토링할 때 위처럼 분리작업을 진행하였습니다.
/* ========================
서버 → 프론트로 내려주는 좌석 상태
좌석+상영+영화+홀드 정보를 전부 포함하고 있는 Dto
======================== */
package com.cinema.kino.dto;
import com.cinema.kino.entity.ScreeningSeat;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.time.LocalDateTime;
import java.util.Map;
@Getter
@AllArgsConstructor
public class SeatStatusResponseDTO {
// 좌석 정보
private Long seatId;
private String seatRow;
private int seatNumber;
private String status;
private String seatType;
private Integer posX;
private Integer posY;
// 상영 정보
private Long theaterId;
private String theaterName;
private Long screeningId;
private String screenName; // 상영관 이름
private String screenType;
private Long movieId;
private String movieTitle;
private String ageRating;
private String posterUrl;
private LocalDateTime startTime;
private LocalDateTime endTime;
private Long memberId; // 회원
private Long guestId; // 비회원
private Integer priceAdult;
private Integer priceYouth;
private Integer priceSenior;
private Integer priceSpecial;
public static SeatStatusResponseDTO from(ScreeningSeat ss, Map<String, Integer> prices) {
var seat = ss.getSeat();
var screening = ss.getScreening();
var movie = screening.getMovie();
var screen = screening.getScreen();
var theater = screen.getTheater();
return new SeatStatusResponseDTO(
seat.getId(),
seat.getSeatRow(),
seat.getSeatNumber(),
ss.getStatus().name(),
seat.getSeatType().name(),
seat.getPosX(),
seat.getPosY(),
theater.getId(),
theater.getName(),
screening.getId(),
screen.getName(),
screen.getScreenType().getValue(),
movie.getId(),
movie.getTitle(),
movie.getAgeRating().name(),
movie.getPosterUrl(),
screening.getStartTime(),
screening.getEndTime(),
ss.getHeldByMember() != null ? ss.getHeldByMember().getId() : null,
ss.getHeldByGuest() != null ? ss.getHeldByGuest().getId() : null,
prices.getOrDefault("ADULT", 15000), // 기본값은 안전장치
prices.getOrDefault("YOUTH", 12000),
prices.getOrDefault("SENIOR", 10000),
prices.getOrDefault("SPECIAL", 10000)
);
}
}
728x90
'Programming Language > Java' 카테고리의 다른 글
| [JAVA] JPA, Spring Data JPA (0) | 2026.04.29 |
|---|---|
| [KINO][JAVA/Spring Boot] 좌석 선정 및 예약: WebSocket 응용(3) (0) | 2026.03.29 |
| [KINO][JAVA/Spring Boot] 좌석 선정 및 예약: WebSocket 응용(1) (0) | 2026.03.24 |
| [JAVA/Spring Boot] STOMP: WebSocket 개념 (0) | 2026.03.23 |
| [JAVA/Spring Boot] Spring Framework: IoC, Bean, DI (0) | 2026.03.16 |