본문 바로가기
Spring공부/3-파일업로드

파일 formData와 String 서버에 보내기 / 파일 업로드 다른 정보도 같이 보내기

by 으노으뇨 2022. 12. 12.
728x90
반응형
SMALL

웹에서 파일을 서버로 보내는 방법과 파일 외에도 다른 정보를 서버로 보내는 방법

파일을 서버로 보내다 보면 이런저런 어노테이션과 그럴싸한 소스들을 붙이는데 

이 포스팅은 담백하게 깔끔하게 진행하는 소스이다.


테스트 환경

내가 업로드할 파일
평밤한 hwp
과학기술정보통신부공고 제2022-0980호_우주항공청설립추진단의 설치 및 운영에 관한 규정 제정안 행정예고.hwp​

JSP 소스

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>FILE TEST 페이지 입니다.</title>
</head>
<body>
	<input type="file" id="postFile" value="send data post">
	<input type="button" id="post" value="send data post">
</br>
	<input type="file" id="putFile" value="send data put">
	<input type="button" id="put" value="send data put">
 </br>
	<input type="file" id="patchFile" value="send data patch">
	<input type="button" id="patch" value="send data patch">
	<script type="text/javascript" src="/resources/js/test/FileTest.js"></script>
</body>
</html>

VIEW

우선 put, patch 방식은 그냥 넣어봤다.

::  조건  ::
1. $Ajax 를 사용할 것
2. 서버로 파일이 도달하는지만 확인할 것
3. 다른 조잡한 어노테이션 사용 X
4. 특별하게 METHOD 방식을 XML이나 Config파일을 수정하여 올리지 않기

Post 매서드를 이용한 @RequestParam(" ") MultipartFile file

Post 매서드를 이용해서 서버로 보내는 방법이 가장 보편적이다.
@RequestParam("file") final MultipartFile file
바로 이렇게 보내는것이다.

AJAX 소스
function _post()
{
	let inFile = document.getElementById('postFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	$.ajax({
  		type: "post"
  		, url: "file"
		, processData : false
		, contentType : false
  		, data : inData
		, dataType : 'json'
  		, success: function(){}
	});  
}​

서버 소스

	@PostMapping(value = "/file")
	private String postFile(@RequestParam("file") final MultipartFile file) throws Exception
	{
		return null;
	}

실행 화면

파일이 formData에 잘들어간 모습
파일이 서버로 잘 들어간 모습

설명 : 이건 아주 간단하게 설계되었다. 실패할 수 값없는 것이다. 그러나 dataType 이나 processData , contentType 이걸 다르게 해서 설정한다면 어떻게 될까?

1. processData : true :: 실패 - Uncaught TypeError: Illegal invocation

2. contentType : true :: 실패 - 500 오류
3. dataType : 미설정 및 선언 안했을때 :: 잘넘어왔다...?

function _post()
{
	let inFile = document.getElementById('postFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	$.ajax({
  		type: "post"
  		, url: "file"
		, processData : false
		, contentType : false
  		, data : inData
		//, dataType : 'json'
  		, success: function(){}
	});  
}

이런데도 실행화면을 보면

잘들어왔다...

 우선 해당 데이터 타입을 선언안해도 기본값으로 JSON 형태라서 이렇게 들어오는것인가? XML 로 설정해서 해보겠다.
xml으로 설정했을떄

, dataType : 'xml'

을 했을때도 정상적으로 들어갔다.
데이터 타입이 꼭 JSON 일 필요가 없나... TEXT로 설정해도 잘들어가진다. 

파일외에 다른정보도 함께 넣어서 보내기

파일외에 다른정보들도 함께 보내는 방법이 있다.
만약 파일을 업로드해야하는데 파일만 보내서 DB에 올리는것이 아니라 파일에 대한 사용자권한 제한이라던가
뭐 파일이 올라가는 게시판이름이나 사용자 정보등을 보내는 방법이 있다. 그것을 한번에 처리하고 싶은 사람들이 있을테니 이 방법을 쓰면 좋을 것 같다.

AJAX 소스
function _post()
{
	let inFile = document.getElementById('postFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	inData.append('auth', 'master');
	inData.append('type', 'manual');
	$.ajax({
  		type: "post"
  		, url: "file"
		, processData : false
		, contentType : false
  		, data : inData
		, dataType : 'JSON'
  		, success: function(){}
	});  
}

formData에 파일과 똑같게 키-밸류 형태로 넣어주었다.

서버 소스

	@PostMapping(value = "/file")
	private String postFile(@RequestParam final Map<String, String> param
    		, @RequestParam("file") final MultipartFile file) throws Exception
	{
		return null;
	}

실행 화면

폼데이터에 어팬드한 값들이 소실없이 모두 도착했다.

@RequestPart 사용하여 파일 데이터 서버로 전송하기

@RequestParam 외에도 다른방법으로 서버에서 파일형태를 받는 형태가 있다.

AJAX 소스
function _post()
{
	let inFile = document.getElementById('postFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	$.ajax({
  		type: "post"
  		, url: "filePart"
		, processData : false
		, contentType : false
  		, data : inData
		, dataType : 'JSON'
  		, success: function(){}
	});  
}

 

서버 소스
	@PostMapping(value = "/filePart")
	private String postPartFile(@RequestPart final MultipartFile file) throws Exception
	{
		return null;
	}

실행 화면

@RequestPart를 사용해도 정상적으로 들어온모습

여기서도 @RequestParam 을 합쳐서 다른 값들도 가져올 수 있을까?
다시 데이터 2개를 더 어팬드 해주는 소스

function _post()
{
	let inFile = document.getElementById('postFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	inData.append('auth', 'master');
	inData.append('type', 'manual');
	$.ajax({
  		type: "post"
  		, url: "filePart"
		, processData : false
		, contentType : false
  		, data : inData
		, dataType : 'JSON'
  		, success: function(){}
	});  
}
	@PostMapping(value = "/filePart")
	private String postPartFile(
			@RequestParam final Map<String, String> param
			, @RequestPart final MultipartFile file
			)
	{
		return null;
	}

리퀘스트파라미터를 붙여준모습
실행 화면

이또한 정상적으로 들어온 모습

PUT 매서드를 이용해서 파일업로드

우선 그냥 추가한 PUT 매서드를 이용한 파일업로드이다.
과연 이게 정상적으로 돌아갈 것인가 ?
물론 가능하다. 그러나 우선적인 조건으로는 노말한 환경에서 진행하는 업로드이다.
AJAX 소스
function _put()
{
	let inFile = document.getElementById('putFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	$.ajax({
  		type: "put"
  		, url: "file"
		, processData : false
		, contentType : false
  		, data : inData
		,dataType : 'json'
  		, success: function(){}
	});  
}
서버 소스
	@PutMapping(value = "/file")
	private String putFile(@RequestPart final MultipartFile file) throws Exception
	{
		return null;
	}

실행화면

잘들어왔다.

PATCH 매서드를 이용해서 파일 업로드

우선 그냥 추가한 PATCH 매서드를 이용한 파일업로드이다.
과연 이게 정상적으로 돌아갈 것인가 ?
물론 가능하다. 그러나 우선적인 조건으로는 노말한 환경에서 진행하는 업로드이다.
AJAX 소스
function _patch()
{
	let inFile = document.getElementById('patchFile').files[0];
	let inData = new FormData();
	inData.append('file', inFile);
	$.ajax({
  		type: "patch"
  		, url: "file"
		, processData : false
		, contentType : false
  		, data : inData
		, dataType : 'JSON'
  		, success: function(){}
	});   
}

서버 소스

	@PatchMapping(value = "/file")
	private String patchFile(@RequestPart final MultipartFile file) throws Exception
	{
		return null;
	}

실행화면

잘들어왔다.

:: 그러나 ,,,

Put은 대상 리소스 값을 교체한다는 의미이다. 서버는 어떤 컨테이너 포맷이라도 사용해서 이 기능을 반드시 구현해야하는데, 여기서 포맷은 보통 multipart MIME 을 사용하지 않고 RFC 1867에 따라 브라우저도 파일 업로드 기능으로 지원하지 않는다. PUT으로 패키지를 올리기 원한다면 패캐지 포맷(zip 같은)을 나타내니느 리소스를 정의하고 해당 리소스의 값을 갱신하는 리소스에 PUT 사용해야한다.

그렇다. put이나 patch는 리소스를 갱신하는 역할하는데 멀티파트로 보내는것과는 맞지 않다는 것이다.

우선 PUT이나 POST 나 PATCH 모두 잘 작동한다. 그러나 POST 를 사용하는 것을 조금더 적극 권장한다.

728x90
반응형
LIST

댓글