ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React]리액트 서버로 파일 전송 하기 (feat.Axious)
    React Meteor 2021. 10. 26. 13:29

    프런트 서버랑 백 서버를 따로두고 개발 테스트를 하던 중

    프런트에서 백 서버로 파일객체를 넘겨주고 백 서버에서 파일업로드 로직을 처리해야하는 일이 생겼다

     

    처음에는 일반 데이터를 보내듯이 JSON타입으로 보냈지만 서버에서 Multipart타입 파일과 매칭이 안되는지 계속

    Exception을 던졌다 어떤게 문제일까 생각하던중

    Http통신 타입을 지정해주지 않았고 제이슨데이터로 보내게되면 스트링타입으로 데이터가 들어가게될 것 이니 문제가 있었지 않았을까 생각해본다.

     

    그래서 JSON타입의 데이터를 FormData로 변경하여 보내주어 서버에서 파일객체를 잘 받을 수 있었다.

    JSON타입으로 데이터를 전송하면서 Image파일도 함께 보내어야 한다면 Base64인코딩 후 JSON 객체로 전송하는 방법도 있으니 JSON 파일 인코딩 키워드로 검색을해서 도움을 받길 바라겠습니다.

    JSON형식으로 파일을 전송하는건 추천하지않는 분위기 같습니다. 인코딩하여 파일객체 정보를 문자열로 바꾼 후 다시 디코딩해야하는 작업이 있어야하고 이 과정에서 데이터 손실이 일어날 수 도있다고 하네요

     

    이제 리액트와 스프링부트 통신에서 파일 객체를 주고받은 코드를 보여드리겠습니다.

     

    <테스트용으로 개발하는거라서 리액트훅스 및 상태관리는 적용하지 않았습니다. 참고 부탁드리겠습니다>

    // 리액트 클래스 생성자
    constructor(props) {
            super(props);
            // form 양식에서 사용 될 파라미터 정의
            this.state = {
                title: '',
                contents: '',
                writer: 'admin',
                file: ''
            }
            this.changeTitleHandler = this.changeTitleHandler.bind(this);
            this.changeContentHandler = this.changeContentHandler.bind(this);
            this.createBoard = this.createBoard.bind(this);
        }
        
        // POST 요청전 Form데이터를 만드는 코드
        createBoard = (event) => {
            event.preventDefault();
            // Form 객체 생성
            const formData = new FormData();
            // Form 객체 데이터 추가 
            // .append("데이터 Name", "데이터 Value")
            formData.append("title", this.state.title);
            formData.append("contents" , this.state.contents)
            formData.append("writer" , this.state.writer)
            formData.append("file" , this.state.file)
    
            console.log("formData => "+ formData);
            BoardService.createBoard(formData).then(res => {
                console.log(res);
                this.props.history.push('/board');
            });
        }

    우선 const formData = new FormData()로 

    새로운 폼데이터 객체를 하나 만들어준 후

    .append를 이용하여 전송 할 데이터들을 추가해주시면 됩니다.

     

    이후 BoardService.createBoard(formData).then(res => {
    this.props.history.push('/board');
    }); 통신 요청을 보냅니다.

     

       createBoard(formData) {
            return axios.post
            (
            // 서버 url 주소 ex)http://localhost:8080/board/save
            BOARD_API_BASE_URL, 
            // 데이터
            formData, 
            // Http통신 헤더 통신 타입 설정 부분 (Http 파라미터 설정 부분)
            {headers: {'ContentType' : 'multipart/form-data'}
           });
        }

    실행 이미지입니다.

    서버 쪽 데이터 request정보입니다.

    Controller단 코드입니다. 

    @PostMapping
        public void postTest(TestBoardDTO board) {
            System.out.println("포스트 진입");
            System.out.println(board);
            System.out.println(board.getFile().getOriginalFilename());
        }

    DTO입니다.

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class TestBoardDTO {
        private Long idx;
        private String title;
        private String contents;
        private String image;
        private String writer;
        private MultipartFile file;
        private Long viewCount;
        private LocalDateTime createDate;
    }

     

     

    이상 리액트를 사용하여 서버로 파일 전송하기 글을 마치겠습니다.

    'React Meteor' 카테고리의 다른 글

    [React] eject 관련 자료 링크 - 공부하고 정리할 것  (0) 2021.10.26
Designed by Tistory.