프로젝트 당시에 이미지 경로 및 업로드에 문제가 있어서 저장 폴더에 이미지가 어떤 경우엔 올라가고 어떤 경우엔 올라가지 않아서 오늘 다시 한번 복습해보도록 하자...
일단 Spring 프로젝트에서 기본 설정을 해줘야 한다.
<!-- 파일 업로드 라이브러리 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- 파일 업로드를 위한 MutipartResolver 구현체 CommonsMultipartResolver bean 등록 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600"/>
<property name="maxUploadSizePerFile" value="104857600"/>
<property name="maxInMemorySize" value="104857600"/>
</bean>
<property> 부분의 프로퍼티를 이용하여 최대 가능한 업로드 사이즈 등 여러가지를 지정할 수 있다.
JSP에서 <form>태그를 이용하여 이미지를 등록할 때
파일처리를 위해서 form 태그 내에 enctype 및 전송 방식을 설정한다.
enctype 속성을 "multipart/form-data"로 설정
method 속성을 "post"로 설정
<form action="${contextPath}/board/itemUpload" method="post" enctype="multipart/form-data">
...
</form>
프로젝트 당시 판매글을 올릴 때 사진도 같이 올리는 방식으로 하였다.
이 때의 코드를 보면서 복습해보자.
@PostMapping("board/itemUpload")
public String boardWrite(@ModelAttribute("loginMember") Member loginMember,
@RequestParam(value = "images", required = false) List<MultipartFile> imageList,
ItemBoard item,
HttpServletRequest req) throws IOException {
String webPath = "resources/images/items/";
String folderPath = req.getSession().getServletContext().getRealPath(webPath);
int boardNo = service.insertBoard(item, imageList, webPath, folderPath);
String path = null;
if (boardNo > 0) { // 등록 성공 시
path = "../board/detail/" + boardNo;
} else { // 등록 실패 시
path = req.getHeader("referer");
}
return "redirect:" + path;
}
String webPath = "/resources/images/items/";
// webPath 값을 지정하면 해당경로까지의 realPath를 추출하는 코드
String folderPath = req.getSession().getServletContext().getRealPath(webPath);
Controller에서 service를 호출하여 작성하는 부분을 살펴보자.
@Override
public int insertBoard(ItemBoard item, List<MultipartFile> imageList, String webPath, String folderPath,
) throws IOException {
// XSS 방지를 위한 Util에서 만들어둔 메서드 처리하기
item.setBoardTitle(Util.XSSHandling(item.getBoardTitle()));
item.setBoardContent(Util.XSSHandling(item.getBoardContent()));
// 이미지 저장 테이블이 따로 있기 때문에 boardNo를 일단 먼저 구한다.
int boardNo = dao.insertBoard(item);
if (boardNo > 0) { // 이미지를 제외한 게시글 삽입 성공 시
List<BoardImage> boardImageList = new ArrayList<BoardImage>();
List<String> reNameList = new ArrayList<String>();
for (int i = 0; i < imageList.size(); i++) {
if (imageList.get(i).getSize() > 0) { // i번째 요소에 업로드된 이미지가 있을 경우
// 이미지 이름 변경 (날짜 및 시간으로)
String reName = Util.fileRename(imageList.get(i).getOriginalFilename());
reNameList.add(reName);
BoardImage img = new BoardImage();
img.setBoardNo(boardNo);
img.setImageLevel(i);
img.setImageOriginal(imageList.get(i).getOriginalFilename());
img.setImageReName(webPath + reName);
boardImageList.add(img);
}
}
// 분류 작업 종료 후 boardIamgeList가 비어있지 않은 경우 == 파일이 업로드가 된 경우
if (!boardImageList.isEmpty()) {
// 이미지 분류 작언이 된 것들을 DB에 저장
int result = dao.insertBoardImageList(boardImageList);
// result == 삽입 성공한 행의 갯수, 단지 0,1이 아니다.
if (result == boardImageList.size()) { // 삽입된 행의 갯수과 업로드 이미지 수가 같을 경우
// 이제야 서버에 이미지를 저장한다.
for (int i = 0; i < boardImageList.size(); i++) {
int index = boardImageList.get(i).getImageLevel();
imageList.get(index).transferTo(new File(folderPath + reNameList.get(i)));
}
}
}
}
return boardNo;
}
DAO쪽은 단순 insert 처리해주는 부분이므로 생략하도록하자.
앞으론 이미지 경로를 잘못 설정하여 프로젝트 실행 시 이미지가 깨지는 경우는 절대 없도록하자..^^