개발자/Spring

[SPRING] spring으로 파일 업로드 구현

푸루닉 2023. 1. 3. 13:42
package com.itbank.controller;

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 org.springframework.web.servlet.ModelAndView;

import com.itbank.service.FileService;

@Controller
public class Ex02Controller {
	
	@Autowired
	private FileService fileService;
	
	@GetMapping("/ex02")
	public void ex02() {}
	
	@PostMapping("/ex02")
	public ModelAndView ex02(MultipartFile uploadFile) {	// input의 name과 매개변수가 일치해야한다.
		// request 없이 parameter를 단일 변수로 받을 수 있듯
		// MultipartRequest를 지정하지 않아도 곧바로 MultipartFile로 받을 수 있다.
		
		ModelAndView mav = new ModelAndView("redirect:/ex02");
		int row = fileService.upload(uploadFile);
		System.out.println(row);
		return mav;
	}

}

준비

 

의존성 세팅

(https://mvnrepository.com/)

	<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
		    <groupId>commons-io</groupId>
		    <artifactId>commons-io</artifactId>
		    <version>2.11.0</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.4</version>
		</dependency>

 

객체 생성 및 빈 등록

<!-- 요청이 multipart/form-data 형식으로 전달될 때 파일을 처리할 객체를 스프링 빈으로 등록 -->
	<beans:bean id="multipartResolver"
				class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<beans:property name="maxUploadSize" value="10485760"/>
		<beans:property name="maxInMemorySize" value="10485760" />
		<beans:property name="defaultEncoding" value="utf-8"/>
	</beans:bean>

반드시 id를 multipartResolver로 선언

 

 

 최대 업로드 가능한 바이트 크기(바이트 단위), -1은 제한이 없음을 의미 -
      <beans:property name="maxUploadSize" value="10485760" />
      
       업로드 요청을 변환할 때 사용할 문자 인코딩 방식 
      <beans:property name="defaultEncoding" value="utf-8" />

 

이 두가지는 꼭 기억해주자 

 


컨트롤러 방식(MultipartRequest 방식)

package com.itbank.controller;

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 org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.servlet.ModelAndView;

import com.itbank.service.FileService;

@Controller
public class Ex01Controller {
	
	@Autowired
	private FileService fileService;
	
	@GetMapping("/ex01")
	public void ex01() {}
	
	@PostMapping("/ex01")
	public ModelAndView ex01(MultipartRequest request) {
		// HttpServletReuqest를 MultipartRequest로 변환하는 코드를 작성할 필요가 없다
		// Service의 함수를 호출할 때는, 가급적 request를 넘기지 않는다
		ModelAndView mav = new ModelAndView("redirect:/ex01");
		
		MultipartFile file =  request.getFile("uploadFile");
		System.out.println(file.getContentType());			// 파일의 유형
		System.out.println(file.getName());					// input의 name
		System.out.println(file.getOriginalFilename());		// 파일의 원래 이름
		System.out.println(file.getSize());					// 파일 크기(byte)
		System.out.println("================================");
		
		int row = fileService.upload(file);
		System.out.println(row);
		
		return mav;
	}
}

파일서비스

package com.itbank.service;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.itbank.model.Ex03DTO;
import com.itbank.repository.UploadDAO;

@Service
public class FileService {
	
	@Autowired private UploadDAO dao;
	
	private final String saveDirectory = "D:\\upload_2023";
	
	public FileService() {
		File dir = new File(saveDirectory);
		if(dir.exists() == false) {
			dir.mkdirs();
		}
	}
	public int upload(MultipartFile file) {
		File dest = new File(saveDirectory, file.getOriginalFilename());
		
		try {
			file.transferTo(dest);
			System.out.println(dest.getAbsolutePath());
			return 1;
			
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
		}
		
		return 0;
	}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>

<h3>MultipartRequest를 이용한 파일 업로드</h3>

<form method="POST" enctype="multipart/form-data">
	<p><input type="file" name="uploadFile"></p>
	<p><input type="submit"></p>
</form>

</body>
</html>

컨트롤러 방식(MultipartFile 방식)

package com.itbank.controller;

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 org.springframework.web.servlet.ModelAndView;

import com.itbank.service.FileService;

@Controller
public class Ex02Controller {
	
	@Autowired
	private FileService fileService;
	
	@GetMapping("/ex02")
	public void ex02() {}
	
	@PostMapping("/ex02")
	public ModelAndView ex02(MultipartFile uploadFile) {	// input의 name과 매개변수가 일치해야한다.
		// request 없이 parameter를 단일 변수로 받을 수 있듯
		// MultipartRequest를 지정하지 않아도 곧바로 MultipartFile로 받을 수 있다.
		
		ModelAndView mav = new ModelAndView("redirect:/ex02");
		int row = fileService.upload(uploadFile);
		System.out.println(row);
		return mav;
	}

}

파일서비스

package com.itbank.service;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.itbank.model.Ex03DTO;
import com.itbank.repository.UploadDAO;

@Service
public class FileService {
	
	@Autowired private UploadDAO dao;
	
	private final String saveDirectory = "D:\\upload_2023";
	
	public FileService() {
		File dir = new File(saveDirectory);
		if(dir.exists() == false) {
			dir.mkdirs();
		}
	}
	public int upload(MultipartFile file) {
		File dest = new File(saveDirectory, file.getOriginalFilename());
		
		try {
			file.transferTo(dest);
			System.out.println(dest.getAbsolutePath());
			return 1;
			
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
		}
		
		return 0;
	}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>

<h3>MultipartFile를 이용한 파일 업로드</h3>

<form method="POST" enctype="multipart/form-data">
	<p><input type="file" name="uploadFile"></p>
	<p><input type="submit"></p>
</form>

</body>
</html>

DTO를 이용한 파일업로드

DTO

package com.itbank.model;

import org.springframework.web.multipart.MultipartFile;

//create table uploadTest3 (
//	name		varchar2(100)	not null,
//	age			number			not null,
//	fileName	varchar2(255)	
//);

public class Ex03DTO {
	private String name;
	private int age;
	private MultipartFile uploadFile;
	private String fileName;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public MultipartFile getUploadFile() {
		return uploadFile;
	}
	public void setUploadFile(MultipartFile uploadFile) {
		this.uploadFile = uploadFile;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
}

컨트롤러

package com.itbank.controller;

import java.util.List;

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.servlet.ModelAndView;

import com.itbank.model.Ex03DTO;
import com.itbank.service.FileService;

@Controller
public class Ex03Controller {
	
	@Autowired
	private FileService fileService;
	
	@GetMapping("/ex03")
	public ModelAndView ex03() {
		ModelAndView mav = new ModelAndView();
		List<Ex03DTO> list = fileService.getList();
		mav.addObject("list", list);
		return mav;
	}
	
	@PostMapping("/ex03")
	public ModelAndView ex03(Ex03DTO dto) {
		
		System.out.println(dto.getName());
		System.out.println(dto.getAge());
		System.out.println(dto.getUploadFile().getOriginalFilename());
		System.out.println("==================================");
		
		
		ModelAndView mav = new ModelAndView("redirect:/ex03");
		int row = fileService.uploadDTO(dto);
		System.out.println(row);
		return mav;
	}
	

}

파일서비스

package com.itbank.service;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.itbank.model.Ex03DTO;
import com.itbank.repository.UploadDAO;

@Service
public class FileService {
	
	@Autowired private UploadDAO dao;
	
	private final String saveDirectory = "D:\\upload_2023";
	
	public FileService() {
		File dir = new File(saveDirectory);
		if(dir.exists() == false) {
			dir.mkdirs();
		}
	}
    	public int uploadDTO(Ex03DTO dto) {
		File dest = new File(saveDirectory, dto.getUploadFile().getOriginalFilename());
		
		try {
			dto.getUploadFile().transferTo(dest);
			System.out.println(dest.getAbsolutePath());
			// 사용자가 입력한 내용은 [이름], [나이], [파일]
			// DB에 저장할 내용은 [이름], [나이], [파일이름]
			dto.setFileName(dto.getUploadFile().getOriginalFilename());
			int row = dao.insert(dto);
			return row;
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
		}
		
		return 0;
	}
	public List<Ex03DTO> getList() {
		return dao.selectAll();
	}

업로드DAO

package com.itbank.repository;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import com.itbank.model.Ex03DTO;

@Repository
public interface UploadDAO {

	@Insert("insert into uploadTest3 values (#{name}, #{age}, #{fileName})")
	int insert(Ex03DTO dto);
	

	@Select("select * from uploadTest3")
	List<Ex03DTO> selectAll();
	
}

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>

<h3>DTO를 이용한 파일 업로드</h3>



<form method="POST" enctype="multipart/form-data">
	<p><input type="text" name="name" placeholder="이름"></p>
	<p><input type="number" name="age" placeholder="나이"></p>
	<p><input type="file" name="uploadFile"></p>
	<p><input type="submit"></p>
</form>

<table>
	<tr>
		<th>NAME</th>
		<th>AGE</th>
		<th>FILENAME</th>
		<th>이미지태그</th>
	</tr>
	<c:forEach var="dto" items="${list }">
	<tr>
		<td>${dto.name }</td>
		<td>${dto.age }</td>
		<td>${dto.fileName }</td>
		<td><img src="${cpath }/upload/${dto.fileName }" height="150"></td>
	</tr>
	</c:forEach>
</table>


</body>
</html>