포스트

09. 이미지 올리기

1. 세팅하기

1) 사이트 접속하여 fileupload 검색
https://mvnrepository.com/

2) Apache Commons FileUpload에서 1.4버전

3) pom.xml에 라이브러리 추가

4) root-context.xml 등록

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!--
  파일 업로드를 위한 MutipartResolver 구현체 CommonsMultipartResolver를
  bean으로 등록
  -> CommonsMultipartResolver를 bean으로 등록하면
  multipart/form-data 형식으로 요청 시  input type="file" 태그를 자동적으로
  인식하여 MultipartFile 객체로 반환하고
  파일 외의 데이터(정수, 문자열 등의 텍스트 데이터)는 기존처럼 사용 가능
  (MultipartRequest 필요 없음)
-->
<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>

<!--
  104857600 byte == 100MB
  20971520 byte == 20MB
  
  maxUploadSize
  : 한 요청당 업로드가 허용되는 최대 용량을 바이트 단위로 설정.
  -1 은 제한이 없다는 뜻으로 이 프로퍼티를 지정하지 않을때 기본값.
  
  maxUploadSizePerFile
  : 한 파일당 업로드가 허용되는 최대 용량을 바이트 단위로 설정.
  -1 은 제한이 없다는 뜻으로 이 프로퍼티를 지정하지 않을때 기본값.
  
  maxInMemorySize
  : 디스크에 저장하지 않고 메모리에 유지하도록
  허용하는 바이트 단위의 최대 용량을 설정.
  
  사이즈가 이보다 클 경우 이 사이즈 이상의 데이터는 파일에 저장됩니다.
  기본값은 10240 바이트.
  
  임시 저장 공간,
  디비에는 안들어가도 서버단에는 파일이 올라갈 수 있다. 그러면 메모리 낭비가 심함
  그래서 성공할 때만 파일을 저장하게하는 것
  임시 저장된 공간의 허용치를 넘어가면 자동으로 서버에 저장됨
-->

2. Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@PostMapping("/profile")
public String updateProfile( 
    @ModelAttribute("loginMember") Member loginMember,// session에 올라간 회원 정보 
    @RequestParam("uploadImage") MultipartFile uploadImage, // 업로드 파일
    @RequestParam Map<String, Object> map, // 모든 파라미터를 저장
    HttpServletRequest req, // 파일 저장 경로 탐색용
    RedirectAttributes ra) throws IOException {

  // 경로 작성하기
  
  // 1) 웹 접근 경로 (/comm/resuources/images/memberProfile/)
  String webPath = "/resources/images/memberProfile/";
  
  // 2) 서버 저장 폴더 경로
  // C:\workspace\07_framework\comm\src\main\webapp\resources\images\memberProfile
  Strng folderPath = req.getSession().getServletContext().getRealPath(webPath);
  
  // 경로 2개, 이미지, delete, 회원번호 map에 담기
  // delete는 이미 맵에 들어가져 있는 상태
  map.put("webPath", webPath);
  map.put("folderPath", folderPath);
  map.put("uploadImage", uploadImage);
  map.put("memberNo", memberNo);
  
  int result = service.updateProfile(map);
  
  String message = null;
  
  if(result > 0) {
    message = "프로필 이미지가 변경되었습니다";
  
    // DB - 세션 동기화
    loginMember.setProfileImage((String)map.get("profileImage"));
  } else {
    message = "프로필 이미지 변경 실패";
  }
  
  ra.addFlashAttribute("message", message);
  
  return "redirect:profile";
}

3. ServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Override
public int updateProfile(Map<String, Object> map) throws IOException {
  // webPath, folderPath, uploadImage, delete, memberNo
  
  // 자주 쓰는 값 변수 저장
  MultipartFile uploadImage = (MultipartFile)map.get("uploadImage");
  String delete = (String)map.get("delete"); // "0" (변경) / "1" (삭제)
  
  // 프로필 이미지 삭제 여부를 확인해서
  // 삭제가 아닌 경우 (== 새 이미지로 변경) -> 업로드된 파일명을 변경
  // 삭제가 된 경우 -> NULL 값을 준비 (DB update)
  
  String renameImage = null; // 변경된 파일명 저장
  
  if(delete.equals("0")) { // 이미지가 변경된 경우
  
    // 파일명 변경
    // uploadImage.getOriginalFilename() : 원본 파일명
    renameImage = Util.fileRename(uploadeImage.getOriginalFilename());
    // 2023042815432.png
    
    map.get("profileImage", map.get("webPath") + renameImage);
    // /resources/images/memberProfile/2023042815432.png
  
  } else {
    map.put("profileImage", null);
  }
  
  // DAO를 호출해서 프로필 이미지 수정
  int result = dao.updateProfile(map);
  
  // DB 수정 성공 시 메모리에 임시 저장되어있는 파일을 서버에 저장
  if(result > 0 && map.get("profileImage") != null) {
    uploadImage.transferTo(new File(map.get("folderPath") + renameImage));
  }
  
  return result;
}

4. DAO

1
2
3
public int updateProfile(Map<String, Object> map) {
  return sqlSession.update("mypageMapper.updateProfile", map);
}

5. mapper.xml

1
2
3
4
5
<update id = "updateProfile">
  UPDATE MEMBER_S SET
  PROFILE_IMG = #{profileImage}
  WHERE MEMBER_NO = ${memberNo}
</update>