🌱 Spring MVC (15) 파일 μ—…λ‘œλ“œ1 (Multipart/form-data, MultipartFile)

Kim Dae HyunΒ·2021λ…„ 7μ›” 25일
2

Spring-MVC

λͺ©λ‘ 보기
13/13
post-thumbnail

Github μ†ŒμŠ€μ½”λ“œ

πŸ”Ž Multipart/form-data

Sprint MVC의 파일 μ—…λ‘œλ“œμ— λŒ€ν•΄ μ•Œμ•„λ³΄κΈ° 전에 Multipart/form-data에 λŒ€ν•΄ λ¨Όμ € μ•Œμ•„μ•Ό ν•©λ‹ˆλ‹€.

μš°λ¦¬κ°€ 일반적으둜 폼 데이터λ₯Ό μ „μ†‘ν•˜λ©΄ application/x-www-form-urlencoded 의 ν˜•μ‹μœΌλ‘œ μ „μ†‘λ©λ‹ˆλ‹€. HTTP body 에 λ°”λ‘œ μ „μ†‘ν•˜κ³ μž ν•˜λŠ” 데이터가 λ“€μ–΄κ°€λŠ” ν˜•νƒœμž…λ‹ˆλ‹€.
name=kim&age=26 κ³Ό 같은 key-value 쌍이 body에 λ“€μ–΄κ°€λŠ” κ²ƒμ΄μ§€μš”.
μ΄λ ‡κ²Œ λ™μΌν•œ νƒ€μž…μ˜ 문자 데이터λ₯Ό μ „μ†‘ν•˜λŠ” 것은 μ „ν˜€ 무리가 μ—†μŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 이런 key-value ν˜•νƒœμ˜ λ¬Έμžλ°μ΄ν„°μ™€ λ°”μ΄λ„ˆλ¦¬ ν˜•νƒœμ˜ 파일 데이터가 ν•¨κ»˜ μ „μ†‘λ˜μ–΄μ•Ό ν•˜λŠ” κ²½μš°μ—” μ–΄λ–¨κΉŒμš” ?
body의 어디쯀에 μ—¬κΈ°λΆ€ν„°λŠ” 파일이 μ „μ†‘λ˜λŠ” 것이라고 μ•Œλ €μ£Όμ–΄μ•Ό 할텐데 일반적인 application/x-www-form-urlencoded νƒ€μž…μœΌλ‘œλŠ” λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.

μ „μ†‘λ˜λŠ” 각 폼 데이터λ₯Ό ꡬ뢄해주어야 ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ κ΅¬λΆ„λ˜λŠ” ν•œ λ‹¨μœ„λ₯Ό part라고 ν•˜κ³  λ™μ‹œμ— μ—¬λŸ¬ λ‹¨μœ„μ˜ partλ₯Ό λ‚˜λˆŒ 수 μžˆκΈ°μ— multipartλΌλŠ” 이름이 뢙은 것 μž…λ‹ˆλ‹€.

ν˜•νƒœλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

============둜 κ΅¬λΆ„λ˜λŠ” μΌμ’…μ˜ κ΅¬λΆ„μžλŠ” λ‚œμˆ˜κ°’μœΌλ‘œ κ²°μ •λ©λ‹ˆλ‹€.

Content-Type을 multipart/form-data둜 ν•˜κΈ° μœ„ν•΄μ„œ form νƒœκ·Έμ— enctype을 지정해주어야 ν•©λ‹ˆλ‹€.


πŸ”Ž Multipart/form-data νŒŒμ‹±

Spring은 MultipartFile νƒ€μž…μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
λ˜ν•œ κ°μ‚¬ν•˜κ²Œλ„ @RequestParam, @ModelAttributeλ₯Ό λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ¨Όμ € μ‹€μŠ΅μ„ μœ„ν•œ HTMLνŒŒμΌμ„ μž‘μ„±ν•˜κ² μŠ΅λ‹ˆλ‹€.
μƒν’ˆλͺ…κ³Ό μƒν’ˆμ˜ 이미지λ₯Ό μž…λ ₯λ°›λŠ” 폼 μž…λ‹ˆλ‹€.
form νƒœκ·Έμ˜ μ˜΅μ…˜μœΌλ‘œ enctype을 μ„€μ •ν•΄μ£Όμ—¬μ•Ό ν•©λ‹ˆλ‹€.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
  <div>
    <h2>μƒν’ˆ 등둝 폼</h2>
  </div>
  <h4>μƒν’ˆ μž…λ ₯</h4>

  <form th:action method="post" enctype="multipart/form-data">
    <ul>
      <li>μƒν’ˆλͺ…<input type="text" name="itemName"></li>
      <li>파일<input type="file" name="file" ></li>
    </ul>
    <input type="submit"/>
  </form>
</div>
</body>
</html>

이제 폼 데이터λ₯Ό 받아쀄 컨트둀러λ₯Ό μž‘μ„±ν•˜κ² μŠ΅λ‹ˆλ‹€.
μ€‘μš”ν•œκ±΄ @PostMapping λ©”μ„œλ“œμž…λ‹ˆλ‹€.
@RequestMappint을 μ΄μš©ν•΄ μƒν’ˆλͺ…κ³Ό νŒŒμΌμ„ λ°›κ³  μžˆμŠ΅λ‹ˆλ‹€. multipart/form-dataκ°€ μ „μ†‘λ˜λŠ” ꡬ쑰λ₯Ό 보면 각 νŒŒνŠΈλ§ˆλ‹€ name을 κ°–κ³  있기 λ•Œλ¬Έμ— 이런 μ‹μ˜ νŒŒμ‹±μ΄ κ°€λŠ₯ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€.

itemName은 잘 λ„˜μ–΄μ™”λ‹€κ³  κ°€μ •ν•˜κ³  파일만 ν…ŒμŠ€νŠΈλ₯Ό ν•΄λ³Όκ»˜μš”.
MultipartFile은 getOriginalFilename() λ©”μ„œλ“œλ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. 이 λ©”μ„œλ“œλŠ” 파일λͺ…κ³Ό ν™•μž₯μžκΉŒμ§€ λΆ™μ—¬μ„œ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

μ €μž₯ν•  파일의 파일λͺ…κ³Ό ν™•μž₯μžκΉŒμ§€ μ•Œμ•˜μœΌλ‹ˆ 이제 경둜λ₯Ό μ§€μ •ν•˜κ³  μ €μž₯ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€. νŒŒμΌμ„ μ €μž₯ν•˜λŠ” κ²½λ‘œλŠ” 상단에 uploadDiR에 μ§€μ •ν•΄λ‘μ—ˆμŠ΅λ‹ˆλ‹€. ν™˜κ²½λ³€μˆ˜ λ“±μœΌλ‘œ λΉΌλŠ” 것이 μ’‹μ§€λ§Œ κ°„λ‹¨ν•œ μ‹€μŠ΅μ„ μœ„ν•΄ μ΄λ ‡κ²Œ ν–ˆμŠ΅λ‹ˆλ‹€.

μ €μž₯ν•  κ²½λ‘œμ™€ 파일의 이름을 λΆ™μ—¬μ„œ 파일 μ €μž₯에 λŒ€ν•œ μ™„μ „ν•œ 경둜λ₯Ό λ§Œλ“€μ–΄ μ€λ‹ˆλ‹€.

μ™„μ „ν•œ 경둜λ₯Ό File객체둜 λ§Œλ“€μ–΄μ„œ MultipartFile의 transferTo λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ 파일 μ €μž₯이 μ™„λ£Œλ©λ‹ˆλ‹€.

@Slf4j
@Controller
public class TestController {

    private final String uploadDir = "/Users/jeonhyeji/Documents/etc/file/";

    @GetMapping("/review/form")
    public String newForm() {
        return "upload-form";
    }

    @PostMapping("/review/form")
    public String form(@RequestParam String itemName,
                       @RequestParam MultipartFile file) throws IOException {

        if (!file.isEmpty()) {
            String filename = file.getOriginalFilename();
            log.info("file.getOriginalFilename = {}", filename);

            String fullPath = uploadDir + filename;
            file.transferTo(new File(fullPath));
        }
        return "upload-form";
    }
}

κ²°κ³Όμž…λ‹ˆλ‹€.

μ΄μƒμœΌλ‘œ κ°„λ‹¨ν•œ 파일 μ—…λ‘œλ“œμ— λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.
λ‹€μŒμ—λŠ” 쑰금 더 λ³΅μž‘ν•œ 예제λ₯Ό κ΅¬μ„±ν•΄μ„œ 파일 μ—…λ‘œλ“œμ— λŒ€ν•΄ 깊게 μ•Œμ•„λ³Όκ»˜μš”.
κ°μ‚¬ν•©λ‹ˆλ‹€. πŸ˜„

profile
μ’€ 더 천천히 까먹기 μœ„ν•΄ κΈ°λ‘ν•©λ‹ˆλ‹€. 🧐

1개의 λŒ“κΈ€

comment-user-thumbnail
2022λ…„ 8μ›” 12일

μ €λŠ” jspλ₯Ό ν†΅ν•΄μ„œ μ½”λ”© 쀑인데
formνƒœκ·Έμ— enctype을 μž…λ ₯ν•˜μ§€ μ•Šμ•„λ„ Controllerμ—μ„œ 잘 λ°›μ•„μ§€λŠ” 것 κ°™λ”λΌκ΅¬μš”.
μ™œ κ·ΈλŸ°μ§€ ν˜Ήμ‹œ μ•„μ‹œλ‚˜μš”??

λ‹΅κΈ€ 달기