반응형
File Upload
pom.xml 파일 설정 : 의존성 주입
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
servlet-context.xml 파일 설정
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="defaultEncoding" value="UTF-8" />
<beans:property name="maxUploadSize" value="52428800" /> <!-- 50MB -->
<beans:property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
</beans:bean>
- maxUploadSize : 최대 업로드 가능한 파일의 바이트 크기
- maxInMemorySize : 디스크에 임시 파일을 생성하기 전에 메모리에 보관할 수 있는 최대 바이트 크기
form 설정
<form id="writeform" class="text-left mb-3" method="post" enctype="multipart/form-data" action="">
<!-- <div class="form-group">
<label for="userid">작성자ID:</label>
<input type="text" class="form-control" id="userid" name="userid" placeholder="작성자ID...">
</div> -->
<div class="form-group">
<label for="subject">제목:</label>
<input type="text" class="form-control" id="subject" name="subject" placeholder="제목...">
</div>
<div class="form-group">
<label for="content">내용:</label>
<textarea class="form-control" rows="15" id="content" name="content"></textarea>
</div>
<div class="form-group" align="left">
<label for="upfile">파일:</label>
<input type="file" class="form-control-file border" name="upfile" multiple="multiple">
</div>
<div class="text-center">
<button type="button" id="registerBtn" class="btn btn-outline-primary">글작성</button>
<button type="reset" class="btn btn-outline-danger">초기화</button>
</div>
</form>
- form의 메서드는 반드시 post로 해줍니다.
- form 태그 안에 enctype="multipart/form-data" 설정을 해줍니다.
- 업로드 할 파일의 input 태그의 타입을 file로 설정합니다.
- 업로드 할 파일을 파라미터로 받아오기 위해 input 태그 안에 name을 설정합니다.
자바 클래스 생성
public class BoardDto {
.....
private List<FileInfoDto> fileInfos;
}
파일을 하나만 저장하려면 FileInfoDto, 여러 개 저장하려면 리스트로 만들어줍니다.
public class FileInfoDto {
private String saveFolder;
private originFile;
private String saveFile;
...(getter, setter 등)
}
- saveFolder : 서버 상의 저장할 폴더
- originFile : 원본 파일의 이름
- saveFile : 실제 저장할 파일의 이름
// controller
@PostMapping("/register")
public String register(BoardDto boardDto, @RequestParam("upfile") MultipartFile[] files, Model model,
HttpSession session, RedirectAttributes redirectAttributes)
throws Exception {
UserDto userDto = (UserDto) session.getAttribute("userinfo");
boardDto.setUserId(userDto.getUserId());
// FileUpload 관련 설정.
logger.debug("MultipartFile.isEmpty : {}", files[0].isEmpty());
if (!files[0].isEmpty()) {
// 내 컴퓨터 경로 밑에 /upload/yyMMdd(파일 이름을 오늘 날짜로 설정) 경로로 파일이 생성됨
String realPath = servletContext.getRealPath("/upload");
// 현재 작업중인 프로젝트의 /resources/img 경로로 파일이 생성됨
// String realPath = servletContext.getRealPath("/resources/img");
String today = new SimpleDateFormat("yyMMdd").format(new Date());
String saveFolder = realPath + File.separator + today;
logger.debug("저장 폴더 : {}", saveFolder);
File folder = new File(saveFolder);
// 폴더가 존재하지 않으면 폴더를 생성
if (!folder.exists())
folder.mkdirs();
List<FileInfoDto> fileInfos = new ArrayList<FileInfoDto>();
// 파일의 개수만큼 반복문을 돌며 파일 업로드 진행
for (MultipartFile mfile : files) {
FileInfoDto fileInfoDto = new FileInfoDto();
String originalFileName = mfile.getOriginalFilename();
if (!originalFileName.isEmpty()) {
String saveFileName = UUID.randomUUID().toString()
+ originalFileName.substring(originalFileName.lastIndexOf('.'));
fileInfoDto.setSaveFolder(today);
fileInfoDto.setOriginFile(originalFileName);
fileInfoDto.setSaveFile(saveFileName);
logger.debug("원본 파일 이름 : {}, 실제 저장 파일 이름 : {}", mfile.getOriginalFilename(), saveFileName);
mfile.transferTo(new File(folder, saveFileName));
}
fileInfos.add(fileInfoDto);
}
boardDto.setFileInfos(fileInfos);
}
guestBookService.registerArticle(guestBookDto);
redirectAttributes.addAttribute("pg", 1);
redirectAttributes.addAttribute("key", "");
redirectAttributes.addAttribute("word", "");
redirectAttributes.addFlashAttribute("msg", "글작성 성공!!!");
return "redirect:/guestbook/list";
// return "redirect:/guestbook/list?pg=1&key=&word=";
}
- /upload/yyMMdd(파일 이름) 경로로 파일이 만들어집니다.
- mfile.transferTo(new File(folder, saveFileName)); -> folder에 saveFileName 이름으로 파일을 전송함
Transactional
// BoardServiceImpl.java
@Override
@Transactional
public void registerArticle(BoardDto boardDto) throws Exception {
if(boardDto.getSubject() == null || boardDto.getContext() ==null) {
throw new Exception();
}
BoardMapper boardMapper = sqlSession.getMapper(BoardMapper.class);
boardMapper.registerArticle(boardDto);
boardMapper.fileRegister(boardDto);
}
@Transactional을 사용하게 되면 Exception 발생 시 자동으로 roll back 되고, Exception이 발생하지 않을 시 자동으로 commit 됩니다.
MyBatis 사용 시 xml을 이용한 파일 업로드
board.xml
<insert id="registerArticle" parameterType="BoardDto">
insert into board (userid, subject, content, regtime)
values (#{userid}, #{subject}, #{content}, now())
<selectKey order="AFTER" resultType="int" keyProperty="articleno">
select last_insert_id()
</selectKey>
</insert>
<insert id="fileRegister" parameterType="BoardDto">
insert into file_info (articleno, savefolder, originfile, savefile)
values
<foreach collection="fileInfos" item="fileinfo" separator=", ">
(#{articleno}, #{fileinfo.saveFolder}, #{fileinfo.originFile}, #{fileinfo.saveFile})
</foreach>
</insert>
<resultMap type="BoardDto" id="boardList">
<result column="articleno" property="articleno"/>
<result column="userid" property="userid"/>
<result column="subject" property="subject"/>
<result column="content" property="content"/>
<result column="regtime" property="regtime"/>
<collection column="articleno" property="fileInfos" javaType="list" ofType="FileInfoDto" select="fileInfoList" />
</resultMap>
BoardDto의 값들이 자동으로 하나씩 들어가게 됩니다. 여기서 정확한 표현은 아니지만,,, 이해하자면 ${} 에는 컬럼명, #{} 에는 Dto에 선언된 변수명이 들어간다는 개념으로 볼 수 있습니다.
반응형
'Spring' 카테고리의 다른 글
[FileUpload] 파일 다운로드 (0) | 2022.04.22 |
---|---|
[Spring Architecture DI] 의존성 주입(DI) (0) | 2022.04.20 |
[Spring Architecture DI] IoC (0) | 2022.04.20 |
[Spring Architecture DI] Container (0) | 2022.04.19 |
[Spring Architecture DI] Spring Framework 구조 (0) | 2022.04.19 |