[Spring Boot] DTO in Notice

김광일·2024년 10월 7일
0

SpringBoot

목록 보기
16/19
post-thumbnail

[1] NoticeDto

1) 코드

package com.example.demo.dto;

import com.example.demo.domain.Notice;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

public class NoticeDto {

    // Notice를 create, update, delete 등을 할 때 다양하게 사용하므로 클래스 안에 클래스로 선언했다. (static으로 선언)
    @Builder
    @Getter
    @Setter
    public static class CreateReqDto{
        private String title;
        private String content;

        public Notice toEntity(){
            Notice notice = new Notice();
            notice.setTitle(getTitle());
            notice.setContent(getContent());
            return notice;
        }
    }

    @Getter
    @Setter
    public static class CreateResDto{
        private Long id;
    }
}

2) 특징

(1) CreateReqDto 클래스

: 이 클래스는 클라이언트에서 공지사항을 생성할 때 보내는 데이터를 담는다.

(2) toEntity 메서드

: 이 메서드는 CreateReqDto 객체를 Notice 엔티티로 변환해주는 역할을 한다.

  • Notice 객체를 생성하고 title과 content 값을 각각 설정한 후 반환한다.
  • 주로 서비스 계층에서 이 메서드를 사용해 DTO를 엔티티로 변환해 데이터베이스에 저장할 수 있도록 한다.
(3) CreateResDto 클래스

: 공지사항 생성 후, 서버가 클라이언트에 응답할 때 사용하는 DTO이다.

[2] Notice

: NoticeDto.CreateResDto의 Return Type을 가진 toCreateResDto 메소드를 선언한다. (이는 엔티티에서의 id 값만 return 해주기 위함이다.)

package com.example.demo.domain;

import com.example.demo.dto.NoticeDto;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
@Entity
public class Notice {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Setter(AccessLevel.NONE)
    @Id
    Long id; // primary key

    @Column(nullable = false)
    String title; // 공지 제목

    @Column(nullable = false)
    String content; // 공지 내용

    Integer readCount; // 공지 읽은 횟수

    public NoticeDto.CreateResDto toCreateResDto(){
        NoticeDto.CreateResDto dto = new NoticeDto.CreateResDto();
        dto.setId(id);
        return dto;
    }
}

[3] NoticeService

: Return Type과 Param Type을 NoticeDto의 CreateResDto, CreateReqDto로 수정해준다.

1) 코드

package com.example.demo.service;

import com.example.demo.domain.Notice;
import com.example.demo.dto.NoticeDto;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;

@Service
public interface NoticeService {
    NoticeDto.CreateResDto create(NoticeDto.CreateReqDto params);
    
    Notice update(Map<String, Object> params);

    List<Notice> list();

    Notice detail(Long id);

    Notice delete(Long id);

}

[4] NoticeServiceImpl

1-1) 코드 1

@Override
public NoticeDto.CreateResDto create(NoticeDto.CreateReqDto params) {
    Notice notice = params.toEntity(); 						 	// 1. CreateReqDto를 Notice 엔티티로 변환  
    notice = noticeRepository.save(notice); 				 	// 2. 변환된 Notice 객체를 데이터베이스에 저장
    NoticeDto.CreateResDto resDto = notice.toCreateResDto(); 	// 3. 저장된 Notice 객체를 CreateResDto로 변환	
    return resDto;											 	// 4. 변환된 응답 DTO 반환
}

1-2) 코드 2

: 이 코드는 더 간결한 표현이다. 위에서 설명한 첫 번째 코드의 모든 과정을 한 줄로 축약한 형태라고 볼 수 있다.

@Override
public NoticeDto.CreateResDto create(NoticeDto.CreateReqDto params) {
    return noticeRepository.save(params.toEntity()).toCreateResDto();
}

[5] NoticeRestController.java

: Return Type을 NoticeDto.CreateResDto로, Param의 Type을 NoticeDto.CreateReqDto로 수정해준다.
: 추가적으로 Dto를 사용하게 되면 @RequestBody로 지정해주어야 한다.
: GetMapping -> PostMapping으로 수정한다.

1) 코드

    @CrossOrigin(origins = "http://localhost:3000")
    @PostMapping({"/create"})
    public NoticeDto.CreateResDto create(@RequestBody NoticeDto.CreateReqDto params) {
        // @RequestParam 를 삭제한 이유?
        return noticeService.create(params);
    }

2) RequestBody로 지정한 이유

  • 복잡한 데이터 구조 처리: CreateReqDto는 제목(title)과 내용(content) 같은 여러 필드를 포함하고 있다. 이를 쿼리 파라미터로 보내는 대신, JSON 형식의 데이터를 본문에 담아 보내는 것이 일반적이다.
  • JSON 데이터 전송: 클라이언트와 서버 간에 JSON 형식으로 데이터를 주고받는 경우, @RequestBody를 사용해 JSON 데이터를 객체로 자동 매핑할 수 있다.
  • 데이터 보안: 요청 본문은 URL에 노출되지 않아, URL 파라미터로 보내는 것보다 민감한 데이터를 처리할 때 안전하다.

[6] create.html의 create_notice 메소드

1) 코드

function create_notice(){

        const data1 = JSON.stringify({
            title : $("#create_notice_title").val(),
            content : $("#create_notice_content").val(),
        })

        $.ajax({
            url : "/api/notice/create",
            type : "POST",
            contentType : 'application/json; charset=utf-8',
            data : data1,
            cache : false,
            success : (obj_data, status, xhr) => {
                alert(JSON.stringify(obj_data));
                $("#create_notice_title").val("");
                $("#create_notice_content").val("");
            },
            error: (obj_data, status, error) => {
                alert("error!!");
                alert(JSON.stringify(obj_data));
            }

        })
    }
  • type : POST로 수정
  • RequestBody로 담아질 부분을 JSON 객체로 지정해준다.

[7] summary

  • NoticeDto 클래스
    • CreateReqDto: 공지사항 생성 시 클라이언트에서 보내는 데이터를 담는 DTO.
    • toEntity(): CreateReqDto를 Notice 엔티티로 변환.
    • CreateResDto: 공지사항 생성 후 서버가 클라이언트에 응답할 때 사용하는 DTO.
  • Notice 클래스
    • 공지사항 엔티티로, 공지의 제목, 내용, 조회수 등을 관리.
    • toCreateResDto(): 엔티티에서 CreateResDto로 변환하여 ID 값만 반환.
  • NoticeService
    • 공지사항 생성, 수정, 조회, 삭제를 관리하는 서비스 계층 인터페이스.
    • create(): CreateReqDto를 받아 공지사항을 생성하고, CreateResDto로 응답.
  • NoticeServiceImpl
    • create() 메서드를 통해 CreateReqDto를 엔티티로 변환 후 저장, 결과는 CreateResDto로 반환.
    • 두 가지 구현 방식:
      • 과정별로 나눠 구현.
      • 한 줄로 간결하게 축약.
  • NoticeRestController
    • @RequestBody로 JSON 데이터를 받아 CreateReqDto로 매핑.
    • POST 요청으로 공지사항 생성 API 처리.
  • create_notice 메서드 (JavaScript)
    • JSON 형식의 공지사항 데이터를 POST 요청으로 서버에 전송.
    • 성공 시 알림, 입력 필드 초기화, 오류 시 경고창 출력.
profile
안녕하세요, 사용자들의 문제 해결을 중심으로 하는 프론트엔드 개발자입니다. 티스토리로 전환했어요 : https://pangil-log.tistory.com

0개의 댓글