Time does not change us. It just unfolds us.

Web/Else

[Web]multipart/form-data

소젬 2021. 10. 28. 18:31

프로젝트를 진행하면서 view에서 controller로 deb, tar, jpg 등의 파일을 보내주는 경우가 굉장히 많았다.

처음에는 임시로 String으로 이름만 받다가 서버 쪽에 전송을 해야하여 multipart/form-data를 이용하였다.

내가 작성한 소스를 먼저 살펴보고 개념을 하나씩 정리해 봐야겠다.


.ftl 파일

<form method="post" id="install_form" onsubmit="return false">
	<div class="modal-header">
		<label class="modal-title">설치 Modal</label>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
        	<i aria-hidden="true" class="ki ki-close"></i>
        </button>
    </div>
    <div class="modal-body">
    	<div class="form-group" id="install_area">
        	<label>DT 설치 파일</label>
            <div class="custom-file">
            	<input type="file" class="custom-file-input" name="file" id="install_file" accept=".tar" />
                <label class="custom-file-label" for="dt_install_pkg_area">설치 파일을 첨부하세요.</label>
            </div>
        </div>
    </div>
    <div class="modal-footer">
        <button type="submit" class="btn btn-primary font-weight-bolder btn-shadow" id="install_btn">저장</button>
        <button type="button" class="btn btn-light-primary font-weight-bold btn-shadow" data-dismiss="modal">닫기</button>
    </div>
</form>

.js 파일

var form = $('#install_form')[0];
var data = new FormData(form);

$.ajax({
    type: "PUT",
    enctype: 'multipart/form-data',
    url: "/install",
    data: data,
    processData: false,
    contentType: false,
    cache: false,
    success: function(data) {
         alert('success');
    }
});

controller.java 파일

consumes를 통해 특정 타입만 처리하도록 정해서 이상한 타입의 파일은 거르도록 한다.

@PutMapping(value = "/install", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
@ResponseBody
public ApiResponse install(@ModelAttribute Request request) {
    return installService.install(request.getFile());
}

이 때 form data로 받은 Request.java class는 이렇게 정의되어 있다.

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Request {
	public static final String MULTIPART_INSTALL_PARAM = "file";
    private MultipartFile file;
}

client.java의 경우는 FeignClient를 사용하여 다음과 같이 간단히 API를 호출했다.

@PutMapping(value = "/install", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ApiResponse install(@RequestPart(value = Request.MULTIPART_INSTALL_PARAM) MultipartFile file);

 

 

 


Client -> Server upload 이해

  1. 파일 업로드를 구현할 때, 클라이언트가 웹브라우저라면 폼을 통해서 파일을 등록해서 전송한다.
  2. 웹 브라우저가 보내는 HTTP 메시지는 Content-Type 속성이 multipart/form-data로 지정되고 정해진 형식에 따라 메시지를 인코딩하여 전송한다.
  3. 이를 처리하기 위한 서버는 멀티파트 메시지에 대해서 각 파트별로 분리하여 개별 파일의 정보를 얻게 된다.

 

multipart/form-data 이해

<form action="/home/uploadfiles" method="post" enctype="multipart/form-data">
    파일명 : <input type="file" name="myfile">
    <button type="submit">제출하기</button>
</form>

-Form 이해

form은 입력 양식 전체를 감싸는 태그이다.
  • name : form의 이름, 서버로 보내질 때 이름의 값으로 데이터 전송한다.
  • action : form이 전송되는 서버 url 또는 html 링크.
  • method : 전송 방법 설정. get은 default,
    post는 데이터를 url에 공개하지 않고 숨겨서 전송하는 방법이다.
  • autocomplete : 자동 완성. on으로 하면 form 전체에 자동 완성 허용한다.
  • enctype : 폼 데이터(form data)가 서버로 제출될 때
    해당 데이터가 인코딩되는 방법을 명시한다.
그 중 오늘의 포스트는 entype의 속성값 중 하나이다.
이 속성은 <form> 요소의 method 속성값이 post인 경우에만 사용할 수 있다.

 

- entype 속성값 중 하나인 multipart/form-data

모든 문자를 인코딩하지 않음을 명시한다.
이 방식은 <form> 요소가 파일이나 이미지를 서버로 전송할 때 주로 사용한다.

 

- Contenty-Type

Content-Type 개체 헤더는 리소스의 media type을 나타내기 위해 사용한다.
어떤 유형의 미디어타입이 전송되고 있는지 알려주는 것이 주요목적이며,

세부적으로는 media-type / charset / boundary로 나눌 수 있다.

Form 내에서 이미지와 텍스트 등을 함께 전송하려면 Content-type을 multipart/form-data로 설정해야 한다.


 

참고

https://velog.io/@shin6403/HTTP-multipartform-data-%EB%9E%80

 

HTTP multipart/form-data 란?

프로젝트를 진행하면서 프론트 -> 백엔드로 이미지를 전송하는 경우가 있었다.오늘은 HTTP, multipart, multipart/form-data 세 가지 키워드에 대해 알아보고, 그 중에서 중요한 개념중에 하나인 multipart/for

velog.io

https://passionha.tistory.com/214

 

파일업로드 처리(MultipartResolver, MultipartFile)

인코딩 타입이 Multipart인 경우 파라미터나 업로드한 파일을 구하려면 전송 데이터를 알맞게 처리해 주어야 한다. 스프링은 Multipart 지원 기능을 제공하고 있기 때문에, 이 기능을 이용하면 추가

passionha.tistory.com

 

'Web > Else' 카테고리의 다른 글

[Web]Token 기반 인증  (0) 2021.11.11
[Web]Maven LifeCycle  (0) 2021.11.04
[Web]Url 주소 가져오기  (0) 2021.10.25
[Web]사용자 정의 예외 클래스  (0) 2021.10.25
[Web]@ContollerAdvice, @ExceptionHandler 예외처리  (0) 2021.10.22