프로젝트/무인 사물함

[AIoT] 무인 사물함 프로젝트 MVC 모델 작성 Model-DTO

마달랭 2025. 2. 10. 18:58
반응형

개요

Model에 속하는 DTO는 Entity와 다르게 클라이언트와 소통을 할 때 사용한다.

클라이언트로 전달 받은 Post요청의 RequestBody항목들을 파싱하는데도 사용하며

클라이언트로 응답을 보낼 데이터를 정의하고 전달하는 용도로도 사용한다.

 

DTO는 Entity와 달리 API가 추가 될 경우 지속적으로 추가될 가능성이 많다.

DB작업을 통해 필요한 데이터만 보낸다는 느낌으로 이해하면 될 것 같다.

 

예를 들어 회원 정보 수정과 같은 내용을 생각해 보자

클라이언트로 부터 받아야 할 데이터는 ID, 비밀번호, 닉네임, 이메일 등이 있을 것이다.

그렇다면 클라이언트로 부터 온 Request정보를 우선 DTO로 받아준다.

DB작업 이후 클라이언트에게 응답을 다시 보내줄 때는 성공 여부만 리턴해 주면 될것이다.

이 처럼 Entity는 DB작업을 위한 테이블 정보로 활용하고 DTO는 클라이언트로 부터의 요청, 응답에 사용하면 된다.

 

 

사용자 관점에서의 DTO

[AIoT] 무인 사물함 프로젝트 사용자 관점 명세 정의

 

[AIoT] 무인 사물함 프로젝트 사용자 관점 명세 정의

개요지난 기간동안 프로젝트 명세와 ERD 등 많은 변경 사항이 생겼다.따라서 해당 명세에 따라 DB 생성 조건이 변경되었다.우선 사용자 관점에서의 명세는 아래와 같다.  사물함 조회 명세사물

zzzz955.tistory.com

 

위 포스팅에서 명세한 사용자 관련 기능과 관련된 DTO를 고객 여정맵을 기준으로 순차적으로 작성해 보겠다.

 

 

StorageRequest.java

package com.a207.smartlocker.model.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class StorageRequest {
    private Long lockerId;
    private String phoneNumber;
}

 

사용자가 물품 보관을 요청한 경우 사용될 DTO이다.

클라이언트로 부터 유저가 선택한 사물함 번호와 유저의 핸드폰 번호를 전달 받는다.

 

 

StorageResponse.java

package com.a207.smartlocker.model.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Builder
public class StorageResponse {
    private Long lockerId;
    private Long tokenValue;
    private String message;
}

 

물품 보관 로직이 성공했을 경우 응답용으로 사용하게 될 DTO이다.

클라이언트에게 사물함 번호, 토큰 인증 번호, 성공 여부를 전달해 준다.

사물함 번호는 요청을 보낼 시 클라이언트가 인지하고 있을 가능성이 있어 굳이 필요한 정보가 아닐 수 있다.

차라리 success와 같은 논리형 변수를 통해 ture, false여부를 전달해 주어도 상관 없다.

다만, 토큰 인증 번호는 서버 내부 로직으로 생성한 데이터이기 때문에 꼭 클라이언트에게 전달해 주어야 한다.

 

 

RetrieveRequest.java

package com.a207.smartlocker.model.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class RetrieveRequest {
    private Long lockerId;
    private Long tokenValue;
}

 

사용자가 물품 수령을 요청한 경우 사용될 DTO이다.
클라이언트로 부터 유저가 선택한 사물함 번호와 해당 사물함에 부여된 인증 번호 6자리를 전달 받는다.

 

 

RetrieveResponse.java

package com.a207.smartlocker.model.dto;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class RetrieveResponse {
    private Long lockerId;
    private String message;
}


반환 성공 여부를 클라이언트에게 리턴하기 위한 DTO이다.

lockerId와 message를 리턴하지만 StoreResponse와 마찬가지로 lockerId는 어차피 클라이언트에서 인지하고 있을 것이기 때문에 굳이 필요한 정보는 아니다. lockerId 대신 success와 같은 논리형 변수에 True를 담아 보내주어도 상관 없다.

 

 

TaskQueueResponse.java

package com.a207.smartlocker.model.dto;

import com.a207.smartlocker.model.entity.LockerQueue;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TaskQueueResponse {
    private Long taskQueueId;
    private Long lockId;
    private String requestType;

    public static TaskQueueResponse from(LockerQueue lockerQueue) {
        return new TaskQueueResponse(
                lockerQueue.getQueueId(),
                lockerQueue.getLockerId().getLockerId(),
                lockerQueue.getRequestType()
        );
    }
}


명세상 클라이언트로 부터 보관/수령 작업에 대한 요청이 들어왔고, 해당 작업이 성공했을 경우 작업 대기열에 작업 정보를 추가해 주게 된다.

그렇다면 작업 대기열 정보를 클라이언트에게 갱신해 주어야 한다.

따라서 보관/수령 작업 요청이 성공했을 경우 클라이언트는 작업 대기열 최신화 요청을 다시 보내주고, 서버에선 작업 대기열 테이블 정보를 클라이언트에게 다시 전달해 준다.

 

그냥 보관/수령 작업 성공 시 해당 정보를 클라이언트로 리턴해 줘도 되나 모종의 이유로 클라이언트가 다운되거나 멈춰버린 경우 재부팅 시 기존의 대기열 정보를 다시 얻어와야 한다.

이런 예외 상황을 처리해 주기 위해서 해당 DTO를 제작하였다.

 

 

RobotControlRequest.java

package com.a207.smartlocker.model.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RobotControlRequest {
    private Long robot_Id;
    private Long locker_Id;
    private String action;
}


해당 DTO는 작업 대기열에서 가장 오래된 작업 정보를 젯슨 나노 보드의 Flask 서버에 요청하기 위한 DTO이다.

이 DTO를 사용할 땐 SpringBoot 서버가 오히려 클라이언트가 되고, 젯슨 나노 보드가 서버가 된다.

젯슨 나노 보드 서버에 로봇Id, 사물함 번호, 작업 구분(보관/반환)을 보내준다.

 

 

RobotTaskResponse.java

package com.a207.smartlocker.model.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Builder
public class RobotTaskResponse {
    private boolean success;
    private String message;
}


젯슨 나노 보드의 Flask 서버로 부터 작업 성공 여부를 받고 클라이언트에게 작업 성공 여부를 리턴해 주는 DTO

로봇이 작업을 성공적으로 수행한 경우 성공 여부와 메시지를 담아 클라이언트에게 리턴해 준다.

 

 

관리자 관점에서의 DTO

[AIoT] 무인 사물함 프로젝트 관리자 관점 명세 정의

 

[AIoT] 무인 사물함 프로젝트 관리자 관점 명세 정의

개요주제가 AIoT프로젝트인 만큼 웹 기술적인 면에서 API의 종류가 많거나 하지는 않다.따라서 사용자 페이지 이외에도 사용 이력 조회, 로봇 상태 조회, 유저 정보 조회, DAU, MAU 조회 등 관리자를

zzzz955.tistory.com

 

위 포스팅에서 명세한 사용자 관련 기능과 관련된 DTO를 클래스 명을 오름차순으로 하여 작성해 보겠다.

 

AdminLoginRequest.java

package com.a207.smartlocker.model.dto;

import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class AdminLoginRequest {
    private String adminId;
    private String adminPassword;
}

 

클라이언트로 부터 관리자 요청을 받을 경우 RequestBody 항목을 파싱하기 위한 DTO

관리자 ID와 비밀번호를 각각 문자열 변수 adminId, adminPassword로 파싱해 준다.

 

 

AdminLoginResponse.java

package com.a207.smartlocker.model.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class AdminLoginResponse {
    private boolean success;
    private String message;
}

 

로그인 성공 여부를 클라이언트에게 반환해 주기 위한 DTO

성공 여부를 논리형 변수 success, 메시지를 문자열 변수 message에 담아 클라이언트에게 전달한다.

 

 

DateRangeRequest.java

package com.a207.smartlocker.model.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@NoArgsConstructor
public class DateRangeRequest {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private LocalDateTime startDate;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private LocalDateTime endDate;
}

 

클라이언트로 부터 로그 조회 요청을 받을 경우 기간을 전달 받기 위한 DTO

LocalDateTime 형식의 데이터의 경우 "yyyy-MM-ddTHH:mm:ss"로 받게 된다.

하지만 관리자 입장에서 해당 형식으로 데이터를 전달해 주기엔 어려움이 따른다.

따라서 더 간편하게 "yyyy-MM-dd HH:mm"형식으로 데이터를 전송할 수 있게 JsonFormat을 통해 포맷을 변경해 주었다.

 

 

LockerUsageLogResponse.java

package com.a207.smartlocker.model.dto;

import com.a207.smartlocker.model.entity.LockerUsageLog;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
@Builder
public class LockerUsageLogResponse {
    private Long logId;
    private Long lockerId;
    private Long userId;
    private LocalDateTime storeTime;
    private Long storeRobotId;
    private LocalDateTime retrieveTime;
    private Long retrieveRobotId;

    public static LockerUsageLogResponse from(LockerUsageLog log) {
        return LockerUsageLogResponse.builder()
                .logId(log.getLogId())
                .lockerId(log.getLocker().getLockerId())
                .userId(log.getUser().getUserId())
                .storeTime(log.getStoreTime())
                .storeRobotId(log.getStoreRobotId() != null ? log.getStoreRobotId().getRobotId() : null)
                .retrieveTime(log.getRetrieveTime())
                .retrieveRobotId(log.getRetrieveRobotId() != null ? log.getRetrieveRobotId().getRobotId() : null)
                .build();
    }
}

 

로그 정보를 클라이언트에게 응답해주기 위한 DTO

  • 로그ID : logId
  • 사물함 번호 : lockerId
  • 유저ID : userId
  • 보관 시각 : storeTime
  • 보관 작업 담당 로봇ID : storeRobotId
  • 반환 시각 : retrieveTime
  • 반환 작업 담당 로봇ID : retrieveRobotId

여기서 로그 정보가 보관 요청을 했으나 실제 보관 작업 대기중이거나 수령은 아직 하지 않은 상태일 경우 보관/반환 작업 담당 로봇ID와 반환 시각의 경우 null값이 올 수도 있다.

 

 

RobotResponse.java

package com.a207.smartlocker.model.dto;

import com.a207.smartlocker.model.entity.Robot;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RobotResponse {
    private Long robotId;
    private String robotName;
    private Long completedTasks;
    private LocalDateTime lastMaintenance;
    private String robotStatus;

    public static RobotResponse from(Robot robot) {
        return new RobotResponse(
                robot.getRobotId(),
                robot.getRobotName(),
                robot.getCompletedTasks(),
                robot.getLastMaintenance(),
                robot.getRobotStatus().getRobotStatus()
        );
    }
}

 

클라이언트가 로봇 정보를 요청했을 때 응답해 주기 위한 DTO

  • 로봇ID : robotId
  • 로봇이름 : robotName
  • 작업 완료 횟수 : completedTasks
  • 마지막 유지 보수 시간 : lastMaintenance
  • 현재 로봇 상태 : robotStatus

 

728x90
반응형