Spring | 객체를 JSON 형태로 반환할 때 주의할 점

바다·2024년 5월 16일
0

Spring

목록 보기
5/13
post-thumbnail

RestController에서 객체를 반환하기

form-data 형식으로

  • MultipartFile 타입의 file과
  • String 타입의 description으로

파일 저장을 요청한 후,
파일 저장이 완료된면 저장된 파일에 대한 정보를 FileDTO 객체로 응답하려고 함

기존 FileDTO

@Setter
@AllArgsConstructor
public class FileDTO {
    private String originalFileName;
    private String savedName;
    private String filePath;
    private String description;
}

FileUploadController

@RestController
@RequestMapping("/api")
public class FileUploadController {
    private final FileUploadService fileUploadService;

    public FileUploadController(FileUploadService fileUploadService) {
        this.fileUploadService = fileUploadService;
    }

    @PostMapping("/files")
    public ResponseEntity<List<FileDTO>> uploadFiles(
            @RequestParam("files") List<MultipartFile> files,
            @RequestParam("description") String description) throws FileUploadException {
        List<FileDTO> uploadFiles = fileUploadService.uploadFiles(files, description);

        return new ResponseEntity<>(uploadFiles, HttpStatus.OK);
    }
}

FileUploadService

@Service
public class FileUploadService {
    @Value("${file.upload-dir}")
    private String uploadDir;

    /*
    1. 파일 업로드
     */
    public List<FileDTO> uploadFiles(List<MultipartFile> files, String description) throws FileUploadException {
        if (!files.isEmpty()) {
            List<FileDTO> fileList = new ArrayList<>();
            for (MultipartFile file : files) {
                FileDTO responseDTO = saveFile(file, description);
                fileList.add(responseDTO);
            }
            return fileList;
        } else {
            throw new FileUploadException("파일이 비어있습니다.");
        }
    }

    /*
    컴퓨터에 파일 저장
     */
    private FileDTO saveFile(MultipartFile file, String description) throws FileUploadException {
        //파일 저장 경로 설정
        String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
        Path path = Paths.get(uploadDir + fileName);
        try {
            Files.createDirectories(path.getParent());
            Files.write(path, file.getBytes());

            return new FileDTO(file.getOriginalFilename(), fileName, path.toString(), description);
        } catch (IOException e) {
            throw new FileUploadException("파일 저장에 실패했습니다.");
        }
    }

}

문제점

"파일은 정상적으로 저장되는데, Response가 아래처럼 빈 객체로 오는 상황 발생"

[
	{},
    {}
]

디버깅

  • 컴퓨터에 있는 폴더에 파일이 저장이 정상적으로 됨
  • 응답코드도 200 OK를 받음
  • service 레이어에서 fileList도 정상적으로 생성되고, 각 파일이 반환될 때마다 fileDTO도 정상적으로 생성된 후에 fileList에 저장됨
  • service에서 반환하는 uploadFiles도 정상적으로 넘어옴

디버깅을 통해 "ResponseEntity"에 "uploadFiles"를 담아서 응답하는 과정에서 문제가 있다는 사실을 알아냄

내가 있고 있었던 점

객체를 return할 때, 해당 원본 클래스이 멤버변수에는 반드시 "Getter"가 존재해야 한다

아... 나는 FileDTO 에 Setter는 만들어두었지만, Getter는 만들어 두지 않았음 😩

내가 너무 싫어지는 순간..~

문제 해결

수정한 FileDTO

@Getter
@Setter
@AllArgsConstructor
public class FileDTO {
    private String originalFileName;
    private String savedName;
    private String filePath;
    private String description;
}

기존 FileDTO 코드에 Lombok으로 Getter를 추가하니 무슨 일 있었냐는 듯 너무나 깔끔한 응답이 옴

JSON 응답

[
    {
        "originalFileName": "증명1.jpg",
        "savedName": "ed278095-dba7-4f85-ab3b-65142d681ac5_증명1.jpg",
        "filePath": "./files/ed278095-dba7-4f85-ab3b-65142d681ac5_증명1.jpg",
        "description": "사진에대한 설명입니다"
    },
    {
        "originalFileName": "증명2.jpg",
        "savedName": "0224f9e5-3e28-4ffe-94b5-40b597e88b34_증명2.jpg",
        "filePath": "./files/0224f9e5-3e28-4ffe-94b5-40b597e88b34_증명2.jpg",
        "description": "사진에대한 설명입니다"
    }
]

다들 나같은 이런 바보같은 실수 하지 말기..~

profile
ᴘʜɪʟɪᴘᴘɪᴀɴs 3:14

0개의 댓글