SPARTA 과제/SPRING

기본 DTO 작성

kjw81024 2026. 2. 3. 17:26

사담

발등에 불이 떨어졌어요


1. 과제 진행 과정 

LV0 ) API 명세서를 작성

https://www.notion.so/API-2fc55c64ceb28017ac38da3959e4289b?source=copy_link 

 

일정 관리 앱 API 명세서 | Notion

API 명세서: 일정 관리 앱 - version: 1.0.0 - Base URL:

www.notion.so

아직 도전과제는 꿈도 못꾸는 시작단계라서 그 부분은 아직 작성 x

 

하지만 댓글까지 관리하게 되는 경우를 생각해서 ERD를 작성해봤다 완전 미완성이니... 주의해서 보시기

댓글에도 Writer 가 존재하니까 writer table 을 분리해줘야하나 고민중

ERD 사이트 

 

https://dbdiagram.io/ 

 

dbdiagram.io - Database Relationship Diagrams Design Tool

 

dbdiagram.io


LV1~LV4 ) POST/GET/PUT/DELETE 구현 

 

프로젝트 명 -> schedule 

종속성은 실습에서 했던 그대로 따라감 

Propertise 설정 ~ DB 연결 


1. 기본설정 해주기 

  • 1) Entity 생성 (Schedule) 하고 Annotation 붙여주기 
  • 2) Controller, Service 에 개별 Annotation과 @RequiredArgsConstructor 붙이기
  • 3) Repository 는 JpaRepository 를 상속받을 수 있게 함

2. BaseEntity 추가해주고 Schedule 이 상속받을 수 있게 함

import jakarta.persistence.*;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@EntityListeners(AuditingEntityListener.class)
@Getter
@MappedSuperclass
public abstract class BaseEntity {
    @CreatedDate
    @Column(updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime modifiedAt;
}

3. ControllerㅡService 만들면서 DTO 를 추가해주며 기본 코드 완성하기

실습과 다르게 구현한 부분

(1) 트러블슈팅 2-<1> get 에 체크로직을 하나 더 작성하여 writer 가 들어오지 않거나 null 인 경우에 전체 schedule 이 출력

(2) Post 에 pw 를 받아와서 체크하는 로직 작성 

# ScheduleService class 의 UpdateScheduleResponse

if (!request.getPw().equalsIgnoreCase(schedule.getPw())){
    throw new WrongPasswordException("비밀번호가 일치하지 않습니다.");
}
# 이후 수정코드가 나옴

# 새로 exception 을 만들어줌

public class WrongPasswordException extends RuntimeException {
    public WrongPasswordException(String message) {
        super(message);
    }
}

pw 가 틀렸다면 console 에 비밀번호가 일치하지 않습니다 메시지 출력, 수정되지 않음 

 

(3) DeleteScheduleRequest DTO 작성

import lombok.Getter;

@Getter
public class DeleteScheduleRequest {
    private String pw;
}

4. DB가 잘 완성되었는지 확인하고, 세부적인 부분 추가해주기 (정렬 등) 

 

+ 신나서 git에 push 도 안 하고 코드를 GET 까지 작성했다... 후딱 git 과 연동해주기

https://kjw81024.tistory.com/32

 

Local -> Git 업로드

1. Repository 만들기 2. 로컬 파일 저장한곳 찾아서 우클릭 -> Open Git Bash here 3. 명령어 따라 작성 git initgit remote add origin http://github.com/{github 이름}/{repository 이름}.git# 그냥 git repository 에서 URL copy 해서

kjw81024.tistory.com


2. 트러블 슈팅 

<1> GET (Writer 기준)

 writer 를 queryString 으로 받아서 와야 필수가 아닌 선택값이 되는데, writer 를 기준으로 GET 요청을 쓸 때 findAll 을 사용하게 되면 for 문 안에서 if 문으로 처리를 해줘야하는지

writer을 required= false 로 처리했는데 writer 값을 주지 않은 경우 writer 는 null 로 처리되는지 

 

일단 실험을 해봤다 (수정삭제 시작도 안 했는데.. ㅎㅎ)

public List<GetScheduleResponse> getUserSchedule(String writer) {
    List<Schedule> schedules = scheduleRepository.findAll();
    List<GetScheduleResponse> dtos = new ArrayList<>();
    System.out.println("*** writer : "+writer);
    for (Schedule schedule : schedules) {
        if (schedule.getWriter().equalsIgnoreCase(writer)){
            GetScheduleResponse dto = new GetScheduleResponse(
                    schedule.getId(),
                    schedule.getName(),
                    schedule.getContents(),
                    schedule.getWriter(),
                    schedule.getCreatedAt(),
                    schedule.getModifiedAt()
            );
            dtos.add(dto);
        }
    }

    return dtos;
}

코드를 위처럼 작성하고 실험

Postman 입력 Console 출력 Postman 출력
http://localhost:8080/schedules?writer=
[]
http://localhost:8080/schedules?writer=냐냐냥
(존재하지 않는 Writer)
[]
http://localhost:8080/schedules?writer=권지원
(존재하는 Writer)
id 가 부여된 정상 출력
http://localhost:8080/schedules
[]

결과는 위와 같음

 

찾아봐야 하는 부분

-> writer 값이 없어도 매개변수가 전달은 되는데 (공백으로) 이걸 어떻게 확인할 수 있는가, 정확히 어떤 값으로 전달되는가

 

공백 또는 null 값이 들어왔을 때 Postman 에 전체 값이 출력되면 된다

 

java.lang.NullPointerException: Cannot invoke "String.isEmpty()" because "writer" is null

writer 이 null 이면 isEmpty 가 검사하기 전에 nullPointerException 으로 터짐

-> 순서 바꿔주기 

java 의 || (or 연산자) 는 앞에꺼부터 검사하고 결과값을 얻으면 뒷 조건은 검사를 안 함 

public List<GetScheduleResponse> getUserSchedule(String writer) {
	# Schedule list와 GetScheduleResponse list 초기화, 선언
    List<Schedule> schedules = scheduleRepository.findAll();
    List<GetScheduleResponse> dtos = new ArrayList<>();
    
    # 입력이 비어있거나, null 인 경우 
    if (writer==null||writer.isEmpty()){
        System.out.println("Writer is empty now!");
        # 전체 Schedule 을 dto 에 담고 
        for (Schedule schedule : schedules) {
            GetScheduleResponse dto = new GetScheduleResponse(
                    schedule.getId(),
                    schedule.getName(),
                    schedule.getContents(),
                    schedule.getWriter(),
                    schedule.getCreatedAt(),
                    schedule.getModifiedAt()
            );
            dtos.add(dto);
        }
        # dtos 반환
        return dtos;
    }

	# 입력이 비어있지 않고 주어진 경우 
    for (Schedule schedule : schedules) {
    	# 동일 값이 있는지 확인하며 dto 에 담고
        if (schedule.getWriter().equalsIgnoreCase(writer)){
            GetScheduleResponse dto = new GetScheduleResponse(
                    schedule.getId(),
                    schedule.getName(),
                    schedule.getContents(),
                    schedule.getWriter(),
                    schedule.getCreatedAt(),
                    schedule.getModifiedAt()
            );
            dtos.add(dto);
        }
    }
    # dtos 반환
    return dtos;
}

조금 .... 코드가 더러워졌지만 일단 정상적으로 출력 된다


<2> POST

문제: 405 오류 ->  웹 서버가 클라이언트의 요청을 인식했으나, 해당 리소스에서 그 HTTP 메서드를 지원하지 않을 때 발생

해결: @PutMapping 을 @PostMapping 으로 오타를 내서 생긴 문제였습니다. 고쳐주니 정상적으로 동작


문제: modified 시간이 바뀌지 않고, GET을 써도 바뀌기 전 상태로 출력되는 걸 보니까 DB에 업데이트가 안 된 듯 함

해결: @Transactional 안에 안 넣어서 생긴 문제였다

더티체킹의 조건... 다시한번 상기시키고 넘어가기 : 트랜잭션 안에 영속상태 객체에 대해 업데이트 가능 

 

+ update 로직에 modifedAt 넣어주지 않기 -> 넣으면 create시점에 null 로 초기화됨 


필수과제 끝

'SPARTA 과제 > SPRING' 카테고리의 다른 글

숙련) 일정관리앱 트러블슈팅 (1)  (0) 2026.02.11
숙련) 일정관리앱 업그레이드 초기설정  (1) 2026.02.10
Schedule README  (0) 2026.02.05
유저 입력 검증  (0) 2026.02.04
댓글 기능 구현, 정렬  (0) 2026.02.04