@Bean //AppConfig.java
public MultipartResolver multipartResolver() {
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setDefaultEncoding("UTF-8");
commonsMultipartResolver.setMaxUploadSize(1024 * 1024 * 100); // 전체 첨부 파일의 최대 크기 100MB
commonsMultipartResolver.setMaxUploadSizePerFile(1024 * 1024 * 10); // 개별 첨부 파일의 최대 크기 10MB
return commonsMultipartResolver;
}
Multipart라는 단어가 보이면 전부 file을 뜻하는 것.commonsMultipartResolver지만 반환타입은 MultipartResolver이다. (스프링에서는 인터페이스 기준으로 타입을 찾는다)@Component 필요 (@Autowired로 불러쓰기 위해 스프링 컨테이너 bean으로 잡아두는 작업) // 파일이 저장될 경로 반환하기
public String getPath() {
/* /storage/yyyy/MM/dd */
LocalDate today = LocalDate.now();
return "/storage/" + today.getYear() + "/" + String.format("%02d", today.getMonthValue()) + "/" + String.format("%02d", today.getDayOfMonth());
// return "/storage/" + DateTimeFormatter.ofPattern("yyyy/MM/dd").format(today);
}
String.format("%02d, today.getMonthValue( )): 2자리 정수인데 모자르면 0으로 채워라. / getMonth아니고 getMonthValue인 거 주의String.format("%02d", today.getDayOfMonth()): 마찬가지로 2자리 정수, 모자르면 0 채우기 / getDayOfMonth()로 불러와야 1~31로 값이 나온다. // 파일이 저장될 이름 반환하기
public String getFilesystemName(String originalName) {
/* UUID.확장자 */
String extName = null;
if(originalName.endsWith("tar.gz")) { // 확장자에 마침표가 포함되는 예외 경우를 처리한다.
extName = "tar.gz";
} else {
String[] arr = originalName.split("\\."); // [.] 또는 \\.
extName = arr[arr.length - 1];
}
return UUID.randomUUID().toString().replace("-", "") + "." + extName;
}
filesystemName : 파일이 저장될 때 이름originalName : 원래 이름 (업로드할 때 이름)ㅍㅊUUID를 사용해서 filesystemName으로 저장하면 된다. (UUID : 중복 없는 값을 임의로 만들어주는 자바 클래스)endsWith 뭘로 끝나는지 판단.gz가 나오니까 확장자를 찾을 수 없다? 그래서 tar.gz는 확장자에 마침표가 포함되는 예외상황이라 처리를 해주고 있음...[.] 또는 \\. (원래는 \.인데 자바에서 역슬래시 인식하려면 두번 적어줘야함) <div>
<h3>MVC 파일첨부</h3>
<form method="post" action="${contextPath}/upload.do" enctype="multipart/form-data">
<div>
<input type="file" name="files" class="files" multiple>
</div>
<div>
<button type="submit">업로드</button>
</div>
</form>
</div>
method="post", enctype="multipart/form-data" 필수@RequiredArgsConstructor
@Controller
public class FileController {
private final FileService fileService;
@RequestMapping(value="/upload.do", method=RequestMethod.POST)
public String upload(MultipartHttpServletRequest multipartRequest, RedirectAttributes redirectAttributes) {
int addResult = fileService.upload(multipartRequest);
redirectAttributes.addFlashAttribute("addResult", addResult);
return "redirect:/main.do";
}
}
MultipartHttpServletRequest를 쓴다. public int upload(MultipartHttpServletRequest multipartRequest);
@RequiredArgsConstructor
@Service
public class FileServiceImpl implements FileService {
private final MyFileUtil myFileUtil;
@Override
public int upload(MultipartHttpServletRequest multipartRequest) {
// 첨부된 파일들의 목록
List<MultipartFile> files = multipartRequest.getFiles("files");
// 순회
for(MultipartFile multipartFile : files) {
// 첨부 여부 확인
if(multipartFile != null && !multipartFile.isEmpty()) {
try {
// 첨부 파일이 저장될 경로 가져오기
String path = myFileUtil.getPath();
// 저장될 경로의 디렉터리 만들기
File dir = new File(path);
if(!dir.exists()) {
dir.mkdirs();
}
// 첨부 파일의 원래 이름 알아내기
String originalName = multipartFile.getOriginalFilename();
// 첨부 파일이 저장될 이름 가져오기
String filesystemName = myFileUtil.getFilesystemName(originalName);
// 첨부 파일의 File 객체
File file = new File(dir, filesystemName);
// 첨부 파일 저장하기
multipartFile.transferTo(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return 0;
}
}
MultipartFile : 스프링에서 첨부된 파일을 뜻함 (import 필요)transferTo라는 파일 저장 코드로 쉽게 해결된다. 
파일 여러개 선택해서 업로드해준 결과 날짜 폴더에 잘 저장됐다. 이름도 랜덤으로 잘 설정됨.
3교시부터 정리하면 댐