목차
MultipartFile 인터페이스
multipart/form-data 요청을 처리하기 위해 만들어진 객체
Spring 에서는 멀티파트 요청을 처리 하기 위해 MultipartFile 객체를 제공합니다.
public interface MultipartFile extends InputStreamSource { String getName () ; @Nullable String getOriginalFilename () ; @Nullable String getContentType () ; boolean isEmpty () ; long getSize () ; byte [] getBytes() throws IOException; @Override InputStream getInputStream () throws IOException; default Resource getResource () { return new MultipartFileResource (this ); } void transferTo (File dest) throws IOException, IllegalStateException; default void transferTo (Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest)); } }
파일 업로드 구현 파일 업로드를 위한 Controller 구현
multipart/form-data 요청은 Form 형식으로 요청이 오기 때문에 RequestBody 어노테이션이 아니라 RequestParam 어노테이션을 이용해 데이터를 받는다.
@RestController @Slf4j public class FileController { String filePath = "/Users/dongwoo-yang/spring-file/" ; @PostMapping("/file/upload") public ResponseEntity upload (@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) throws IOException, URISyntaxException { if (multipartFile.isEmpty()){ log.info("File is empty" ); } log.info("multipartFile.getName() : {}" , multipartFile.getName()); log.info("multipartFile.getOriginalFilename() : {}" , multipartFile.getOriginalFilename()); log.info("multipartFile.getContentType() : {}" , multipartFile.getContentType()); log.info("multipartFile.getSize() : {}" , multipartFile.getSize()); log.info("multipartFile.getResource() : {}" , multipartFile.getResource()); String fullFilename = multipartFile.getOriginalFilename(); int lastIndex = fullFilename.lastIndexOf("." ); String filename = fullFilename.substring(0 , lastIndex); String ext = fullFilename.substring(lastIndex + 1 ); String newName = UUID.randomUUID() + "." + ext; String uploadPath = filePath + newName; multipartFile.transferTo(Paths.get(uploadPath)); URI uri = new URI (request.getRequestURI()); return ResponseEntity.created(uri).body("File Upload Success" ); } }
File Upload 테스트 코드 작성 파일을 RestTemplate으로 전달할 때는 MultiValueMap 에 담아 전송한다. MultiValueMap 에 들어가는 데이터 형으로는 File 객체가 아니라 Resource 객체를 던져 줘야 mulipart/form-data 형태로 전송이 된다. 이거 때문에 진짜 한참 찾아 다녔다.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class FileControllerTest { @Autowired private TestRestTemplate testRestTemplate; @LocalServerPort int randomServerPort; @Test public void uploadTest () throws IOException { ClassPathResource resource = new ClassPathResource ("testFile.txt" ); File file = resource.getFile(); MultiValueMap multiValueMap = new LinkedMultiValueMap (); multiValueMap.add("file" , resource); HttpHeaders headers = new HttpHeaders (); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity (multiValueMap, headers); String requestURL = "http://localhost:" + randomServerPort + "/file/upload" ; ResponseEntity<String> responseEntity = this .testRestTemplate.exchange(requestURL, HttpMethod.POST, httpEntity, new ParameterizedTypeReference <String>() { }); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED); assertThat(responseEntity.getBody()).isEqualTo("File Upload Success" ); } }
이미지 파일 Upload
PDF 파일 Upload
Mp4 파일 upload