본문 바로가기
[study]이론정리/Spring Boot

Spring MVC - FileUpload & download

by yoon9i 2024. 7. 2.

12> 파일 업로드
(1) 개요
- 서블릿/JSP 및 Spring Framework 에서는 의존성 설정이 필요함.
- SpringBoot 는 의존성 필요없음. (-starter-web 에 자동으로 포함되어 있음)

(2) 파일 업로드 화면

  <form method="POST" enctype="multipart/form-data" action="fup.cgi">
    File to upload: <input type="file" name="upfile"><br/>
    Notes about the file: <input type="text" name="note"><br/>
    <br/>
    <input type="submit" value="Press"> to upload the file!
  </form>

  반드시 method 와 enctype 를 다음값으로 설정해야된다.
  - method="POST"
  - enctype="multipart/form-data"

  멀티 업로드 가능.
  <input type="file" name="upfile1">
  <input type="file" name="upfile2">

(3) UploadDTO 작성

  public class UploadDTO {

    String theText;
    MultipartFile  theFile;
  }


(4) Controller 업로드 작업

  @PostMapping("/upload")
public String upload(UploadDTO dto) {

String theText = dto.getTheText();
MultipartFile  theFile = dto.getTheFile();

long size = theFile.getSize();
String name = theFile.getName();
String fileName = theFile.getOriginalFilename();
String contentType = theFile.getContentType();


logger.info("logger:theText:{}", theText);
logger.info("logger:size:{}", size);
logger.info("logger:name:{}", name);
logger.info("logger:fileName:{}", fileName);
logger.info("logger:contentType:{}", contentType);

// 서버의 물리적인 디렉터리에 파일 저장 예> c:\\upload

// 파일이 저장할 경로만 알려줌
File f = new File("c:\\upload", fileName);

try {
theFile.transferTo(f);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return "uploadInfo";
}


(5) Controller 다운로드 작업

  <body>
    // uploadInfo 작업
    <h2>uploadInfo</h2>
    내용:${uploadDTO.theText}<br>
    파일명:${uploadDTO.theFile.originalFilename}<br>
    파일명:<a href="down?fileName=${uploadDTO.theFile.originalFilename}">
            ${uploadDTO.theFile.originalFilename}
          </a><br>
</body>

 
//파일다운로드
@Autowired
ServletContext ctx;

  @GetMapping("/down")
  public void fileDown(HttpServletRequest request, HttpServletResponse response)
  throws Exception{

    String fileName = request.getParameter( "fileName" );
    File fNew = new File("c:\\upload", fileName);
    String sFilePath = fNew.getPath();
    // String sFilePath = sDownloadPath + fileName;

    byte b[] = new byte[4096];
    FileInputStream in = new FileInputStream(sFilePath);

    String sMimeType = ctx.getMimeType(sFilePath);
    System.out.println("sMimeType>>>"+sMimeType );

    if(sMimeType == null) sMimeType = "application/octet-stream";

    response.setContentType(sMimeType);

    String sEncoding = new String(fileName.getBytes("UTF-8"),"8859_1");

    response.setHeader("Content-Disposition", "attachment; filename= " + sEncoding);
        
    ServletOutputStream out = response.getOutputStream();
    int numRead;

    while((numRead = in.read(b, 0, b.length)) != -1) {
      out.write(b, 0, numRead);
    }
    
    out.flush(); 
    out.close();
    in.close();
  }

 

package com.exam;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}
package com.exam.controller;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import com.exam.dto.UploadDTO;

@Controller
public class MainController {
	
	Logger logger = LoggerFactory.getLogger(getClass());

	@GetMapping("/upload")
	public String uploadForm() {
		return "uploadForm";
	}
	
	@PostMapping("/upload")
	public String upload(UploadDTO dto) {
		
		String theText = dto.getTheText();
		MultipartFile  theFile = dto.getTheFile();
		
		long size = theFile.getSize();
		String name = theFile.getName();
		String fileName = theFile.getOriginalFilename();
		String contentType = theFile.getContentType();
		
		
		logger.info("logger:theText:{}", theText);
		logger.info("logger:size:{}", size);
		logger.info("logger:name:{}", name);
		logger.info("logger:fileName:{}", fileName);
		logger.info("logger:contentType:{}", contentType);
		
		// 서버의 물리적인 디렉터리에 파일 저장 예> c:\\upload
		
		// 파일이 저장할 경로만 알려줌
		File f = new File("c:\\upload", fileName);
		
		try {
			theFile.transferTo(f);
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return "uploadInfo";
	}
	
	
	//파일다운로드
		@Autowired
		ServletContext ctx;
		
		@GetMapping("/down")
		public void fileDown(HttpServletRequest request, HttpServletResponse response)
		throws Exception{

		 String fileName = request.getParameter( "fileName" );
		        File fNew = new File("c:\\upload", fileName);
			String sFilePath = fNew.getPath();
		//	String sFilePath = sDownloadPath + fileName;

			byte b[] = new byte[4096];
			FileInputStream in = new FileInputStream(sFilePath);

			String sMimeType = ctx.getMimeType(sFilePath);
	System.out.println("sMimeType>>>"+sMimeType );

			if(sMimeType == null) sMimeType = "application/octet-stream";

			response.setContentType(sMimeType);

			String sEncoding = new String(fileName.getBytes("UTF-8"),"8859_1");

			response.setHeader("Content-Disposition", "attachment; filename= " + sEncoding);
			
			ServletOutputStream out = response.getOutputStream();
			int numRead;

			while((numRead = in.read(b, 0, b.length)) != -1) {
				out.write(b, 0, numRead);
			}
			out.flush(); 
			out.close();
			in.close();
		}
	
	
	
	
}
package com.exam.dto;

import org.springframework.web.multipart.MultipartFile;

public class UploadDTO {

	String theText;
 	MultipartFile  theFile;
 	
	public UploadDTO() {}

	public UploadDTO(String theText, MultipartFile theFile) {
		this.theText = theText;
		this.theFile = theFile;
	}

	public String getTheText() {
		return theText;
	}

	public void setTheText(String theText) {
		this.theText = theText;
	}

	public MultipartFile getTheFile() {
		return theFile;
	}

	public void setTheFile(MultipartFile theFile) {
		this.theFile = theFile;
	}

	@Override
	public String toString() {
		return "UploadDTO [theText=" + theText + ", theFile=" + theFile + "]";
	}
 	
 	
}
<%@ page 
         contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"        
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>업로드 화면</h2>
<form method="post" enctype="multipart/form-data" 
      action="upload">
  내용:<input type="text" name="theText"><br>
  파일:<input type="file" name="theFile"><br>
  <input type="submit" value="업로드">
</form>
</body>
</html>
<%@ page 
         contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"        
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>uploadInfo</h2>
내용:${uploadDTO.theText}<br>
파일명:${uploadDTO.theFile.originalFilename}<br>
파일명:<a href="down?fileName=${uploadDTO.theFile.originalFilename}">
     ${uploadDTO.theFile.originalFilename}</a><br>
</body>
</html>
# application.properties
logging.level.org.springframework=info

# tomcat port 번호 변경
server.port=8090

# context 명 변경
server.servlet.context-path=/app

# jsp의 경로와 확장자 지정
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

# 기본 파일 업로드 설정 변경

# 기본 크기 1MB
spring.servlet.multipart.max-file-size=3MB
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.18</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.exam</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-devtools</artifactId>
		</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-jasper</artifactId>
		<scope>provided</scope>
	</dependency> 
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl</artifactId>
	</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>