[Spring Boot] DTO 정리

김광일·2024년 10월 7일
0

SpringBoot

목록 보기
17/19
post-thumbnail

1. GET

: GET은 서버로부터 데이터를 불러올 때 주로 사용한다.

[1] RestController

: 메소드를 선언 시, @GetMapping을 사용한다.
: @RequestParam으로 선언하여 param에 담아 사용한다.

@GetMapping({"/detail"}) // 특정 사용자 세부정보 요청을 처리
public UserDto.DetailResDto detail(@RequestParam Long id) {
    return userService.detail(id); // 사용자 세부정보 서비스 호출
}

[2] html - script

: ajax의 method type을 GET으로 설정한다.
: 불러올 정보에 대한 value을 data에 담는다. (@RequestParmas에 의해 URL 파라미터로 전달된다.)

function detail_user(){
        $.ajax({
            url : "/api/user/detail",
            type : "GET",
            contentType : 'application/json; charset=utf-8',
            // data : { order : $("#detail_board_order").val()},
            data : { id : final_id},
            cache : false,
            success : (obj_data, status, xhr) => {
                console.log(JSON.stringify(obj_data));
                $("#detail_user_id").val(obj_data["id"]);
                $("#detail_user_username").val(obj_data["username"]);
                $("#detail_user_name").val(obj_data["name"]);
                $("#detail_user_phone").val(obj_data["phone"]);

            },
            error: (obj_data, status, error) => {
                alert("error!!");
                alert(JSON.stringify(obj_data));
            }

        })
    }

2. POST

: POST는 서버에게 데이터를 보낼 때 주로 사용한다.

[1] RestController

: 메소드를 선언 시, @PostMapping을 사용한다.
: @RequestBody로 선언하여 Body에 담아 사용한다.

@PostMapping({"/login"}) // 사용자 로그인 요청을 처리
public UserDto.LoginResDto login(@RequestBody UserDto.LoginReqDto params) {
    // System.out.println(params); // 디버깅용 출력 (주석 처리됨)
    return userService.login(params); // 로그인 서비스 호출
}

[2] html - script

: ajax의 method type을 POST으로 설정한다.
: @RequestBody로 선언되었기에, data에 담은 내용을 JSON.stringify() 처리해줘야 한다.

function login(){
        $.ajax({
            url : "/api/user/login",
            type : "POST",
            contentType : 'application/json; charset=utf-8',
            data : JSON.stringify({
                username : $("#login_username").val(),
                password : $("#login_password").val(),
            }),
            cache : false,
            success : (obj_data, status, xhr) => {
                const name = obj_data.name;

                if(obj_data.result == "login_fail_username"){
                    alert("잘못된 아이디입니다");
                }
                if(obj_data.result == "login_fail_password"){
                    alert("잘못된 비밀번호입니다");
                }

                if(name != null){
                    alert(name + "님 반갑습니다.");
                    window.location.href = "/user/list";
                }


            },
            error: (obj_data, status, error) => {
                alert("로그인 실패!!");
                alert(JSON.stringify(obj_data));
            }

        })
    }

3. DELETE

: POST는 DB에서 삭제하고 싶은 내용이 있을 때 주로 사용한다.

[1] RestController

: 메소드를 선언 시, @DeleteMapping을 사용한다.
: @RequestParam으로 선언하여 param에 담아 사용한다.

@DeleteMapping({"/delete"}) // 사용자 삭제 요청을 처리
public UserDto.DeleteResDto delete(@RequestParam Long id) {
    return userService.delete(id); // 사용자 삭제 서비스 호출
}

[2] html - script

: ajax의 method type을 DELETE으로 설정한다.
: data를 선언하지 않고, url 뒤에 삭제할 id를 지정한다.
: 이때 클라이언트와 서버에서 사용하는 쿼리 매개변수 이름(id)은 반드시 일치해야 하며, 일치하지 않으면 서버에서 해당 매개변수를 찾을 수 없어서 오류가 발생하게 된다.

function delete_user() {
    $.ajax({
        url: "/api/user/delete?id=" + final_id,
        type: "DELETE",
        contentType: 'application/json; charset=utf-8',
        cache: false,
        success: (obj_data, status, xhr) => {
            // alert(JSON.stringify(obj_data));
            alert("삭제되었습니다!");
            window.location.href = "/user/list";
        },
        error: (obj_data, status, xhr) => {
            alert("error!!");
            alert(JSON.stringify(obj_data));
        }
    });
}

4. DTO 생성법 (request, response)

[1] DTO 파일 생성하기 (ex. UserDto.java)

[2] 목적과 사용성에 맞춰서 request, response를 지정한다.

1) 간단한 구분

  • 파라미터 : request
  • 리턴값 : response

2) 필자가 사용한 명명법

  • 메소드 종류 + Req | Res + Dto
  • ex) CreateResDto

3) 메소드 안에 들어가는 값

: 주로 해당 메소드를 통해서 response으로 반환 해주고 싶은 값 또는 request로 다루고 싶은 값을 사용한다.

  • ex) CreateReqDto

    • ID
    • PW
    • name
    • phone
    • id(pk)
    @Getter
    @Setter
    public static class CreateReqDto {
      private String id;          // 사용자 ID
      private String username;    // 사용자 이름 (로그인용 ID)
      private String password;    // 비밀번호
      private String name;        // 사용자 실제 이름
      private String phone;       // 전화번호
    
      // DTO 데이터를 User 엔티티로 변환하는 메소드
      public User toEntity() {
          User user = new User();
          user.setUsername(getUsername());
          user.setPassword(getPassword());
          user.setName(getName());
          user.setPhone(getPhone());
          return user;
      }
    }
    
  • ex) CreateResDto

    • id(pk) : 생성된 사용자의 ID
    • result : 처리 결과
    @Getter
    @Setter
    public static class CreateResDto {
        private Long id;            // 생성된 사용자의 ID
        private String result;      // 처리 결과 (성공/실패 여부)
    }

[3] 예시 코드

package com.example.demo.dto;

import com.example.demo.domain.User;
import lombok.Getter;
import lombok.Setter;

public class UserDto {

    // 사용자를 생성할 때 필요한 데이터를 전달하는 DTO 클래스
    @Getter
    @Setter
    public static class CreateReqDto {
        private String id;          // 사용자 ID
        private String username;    // 사용자 이름 (로그인용 ID)
        private String password;    // 비밀번호
        private String name;        // 사용자 실제 이름
        private String phone;       // 전화번호

        // DTO 데이터를 User 엔티티로 변환하는 메소드
        public User toEntity() {
            User user = new User();
            user.setUsername(getUsername());
            user.setPassword(getPassword());
            user.setName(getName());
            user.setPhone(getPhone());
            return user;
        }
    }

    // 로그인 시 필요한 데이터 전달을 위한 DTO 클래스
    @Getter
    @Setter
    public static class LoginReqDto {
        private String username;    // 사용자 이름 (로그인용 ID)
        private String password;    // 비밀번호

        // 로그인 DTO를 User 엔티티로 변환
        public User toEntity() {
            User user = new User();
            user.setUsername(getUsername());
            // 비밀번호를 잘못 매핑한 부분 수정 필요
            user.setPassword(getPassword());
            return user;
        }
    }



    // 로그인 후 반환되는 응답 DTO
    @Getter
    @Setter
    public static class LoginResDto {
        private String name;        // 로그인한 사용자의 이름
        private String result;      // 처리 결과 (성공/실패 여부)
    }

    // 특정 사용자 상세 정보를 반환하는 DTO
    @Getter
    @Setter
    public static class DetailResDto {
        private Long id;            // 사용자 ID
        private String username;    // 사용자 이름 (로그인용 ID)
        private String password;    // 비밀번호
        private String name;        // 실제 이름
        private String phone;       // 전화번호
    }

    // 사용자 삭제 후 반환되는 응답 DTO
    @Getter
    @Setter
    public static class DeleteResDto {
        private String result;      // 처리 결과 (성공/실패 여부)
    }
}

5. DTO 사용법 (Service, ServiceImpl)

[1] Service

: Return Value, Parameter 두 개 모두 타입으로 지정한다.

1) 코드 (GET - detail, POST - login, DELETE - delete)

package com.example.demo.service;

import com.example.demo.dto.UserDto;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 사용자 관련 서비스 인터페이스
 */
@Service
public interface UserService {
    /**
     * GET
     * 특정 사용자의 정보를 조회합니다.
     *
     * @param id 사용자 ID
     * @return 사용자 상세 응답 데이터
     */
    UserDto.DetailResDto detail(Long id);

    /**
     * POST
     * 사용자 로그인을 처리합니다.
     *
     * @param params 로그인 요청 데이터
     * @return 로그인 응답 데이터
     */
    UserDto.LoginResDto login(UserDto.LoginReqDto params);

	/**
     * DELETE
     * 사용자를 삭제합니다.
     *
     * @param id 사용자 ID
     * @return 사용자 삭제 응답 데이터
     */
    UserDto.DeleteResDto delete(Long id);
}

[2] ServiceImpl

: 지정한 메소드를 구현한다.

1) 코드 (GET - detail, POST - login, DELETE - delete)

package com.example.demo.service.impl;

import com.example.demo.domain.User;
import com.example.demo.dto.UserDto;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 사용자 서비스 구현 클래스
 */
@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository){
        this.userRepository = userRepository;
    }

	//
	// GET
    //
    
    @Override
    public UserDto.DetailResDto detail(Long id) {
        // 특정 사용자의 상세 정보 조회
        return userRepository.findById(id).orElse(null).toDetailResDto();
    }

	//
	// POST
    //
    
    @Override
    public UserDto.LoginResDto login(UserDto.LoginReqDto params) {
        User user = userRepository.findByUsername(params.getUsername());
        UserDto.LoginResDto resDto = new UserDto.LoginResDto();

        // 사용자 존재 여부 확인
        if(user == null){
            resDto.setResult("login_fail_username");
            return resDto;
        }

        // 비밀번호 확인
        if(!user.getPassword().equals(params.getPassword())){
            resDto.setResult("login_fail_password");
            return resDto;
        }

        resDto.setName(user.getName());
        resDto.setResult("로그인 성공");
        return resDto;
    }
    
    //
	// DELETE
    //
    
    @Override
    public UserDto.DeleteResDto delete(Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다."));

        userRepository.delete(user); // 사용자 삭제

        UserDto.DeleteResDto resDto = new UserDto.DeleteResDto();
        resDto.setResult("삭제 성공"); // 삭제 결과 반환
        return resDto;
    }
}
profile
안녕하세요, 사용자들의 문제 해결을 중심으로 하는 프론트엔드 개발자입니다. 티스토리로 전환했어요 : https://pangil-log.tistory.com

0개의 댓글