파일 업로드 content-type 오류 발생

이상혁·2024년 4월 24일
0

문제 상황

게시판을 구현하는데 파일업로드를 하는 기능이 있었다.
RequestPart로 구현을 했을 진행을 했고 dto와 multipartFile로 파일과 내용을 받아서 구현을 했다.

@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<BoardResponseDto> createBoard(@RequestPart(value = "dto", required = false) BoardRequestDto boardRequestDto,
                                                        @RequestPart(value = "file", required = false) List<MultipartFile> multipartFiles,
                                                        @AuthenticationPrincipal CustomUserDetails customUserDetails
    ) {
        BoardResponseDto board = boardService.createBoard(boardRequestDto, customUserDetails.getEmployee(), multipartFiles);
        return ResponseEntity.ok(board);
}

controller에서 위에 코드와 같이 구현을 했고

위와 같이 요청을 보냈을 때 업로드와 게시판 등록이 매우 잘 되었다.
그런데 포론트에서 api를 통해서 게시판을 등록할 때 문제가 발생을 했다.
그냥 제목, 내용을 작고 등록을 하면 게시판 등록이 잘 되었지만 파일을 넣고 하면 content-type 에러가 발생을 하였다.
프론트쪽에서 dto는 application/json으로 파일은 multipart로 잘 넣어서 보냈는데도 에러가 발생을 했다.

해결 방법

HttpMessageConverter를 커스텀해서 에러를 해결했다.
알아보니 spring은 기본적으로 multipart 요청, data-form을 처리하는데 MultiPartResolver를 사용을 하는데 이 MultiPartResolver는 텍스트 기반의 메시지 변환만을 지원을 해서 Json이 들어가면 처리하지 못 하는 것이다.
그래서 Custom한 Converter를 만들어서 Json을 따로 추출하는 과정이 필요하다.

package com.github.riset_backend.global.config.uplaod;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;

@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {

    public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
        super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
    }

    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return false;
    }

    @Override
    public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
        return false;
    }

    @Override
    protected boolean canWrite(MediaType mediaType) {
        return false;
    }
}

먼저, spring에서 Http를 Json으로 변환을 하는 AbstractJackson2HttpMessageConverter를 상속을 받아서 기능을 확장을 해준다.
AbstractJackson2HttpMessageConverter 상속을 통해서 Json을 파싱하는 기능을 추가해준다.

MultipartJackson2HttpMessageConverter 메소드를 통해서 AbstractJackson2HttpMessageConverter 생성자를 생성을 하고 application/octet-stream을 타입으러 지정을 해주어서 multiPart에서도 Json을 추출을 해서 사용할 수 있도록 해준다.

canWrite 메소드들을 false로 해주어서 읽기만 가능하도록 해준다.

이 방법을 통해서 헤결을 해주었다.
프론트에서도 해보니 multiPart안에 Json을 넣어도 content-type 에러가 발생하지 않고 S3에 업로드도 잘 되었다.

profile
개발 공부 하기 위해 만든 블로그

0개의 댓글