서브쿼리 / 쇼핑몰 게시판(파일 첨부 기능)
- 쇼핑몰 홈페이지에서 상품과 첨부파일 등록 기능 실행하고자 함.
⭐ 스프링의 파일 업로드
: MultipartFile 인터페이스로 멀티파트 파일을 편리하게 지원
- 웹 클라이언트가 요청을 보낼 때, HTTP 프로토콜의 바디 부분에 데이터를 여러 부분으로 나눠서 보내는 것.
- 웹 클라이언트가 서버에게 파일을 업로드할 때, http 프로토콜의 바디 부분에 파일정보를 담아서 전송을 하는데, 파일을 한 번에 여러개 전송을 하면 body 부분에 파일이 여러개의 부분으로 연결되어 전송됨.
➡️ 이렇게 여러 부분으로 나뉘어서 전송되는 것은 Multipart data라고 하며, 보통 파일을 전송할 때 사용
- 사용자가 업로드한 File을 핸들러에서 손쉽게 다룰 수 있게 도와주는 매개변수 중 하나
- MultipartFile 인터페이스는 스프링에서 업로드 한 파일을 표현할 때 사용되는 인터페이스
- MultipartFile 인터페이스를 이용해서 업로드한 파일의 이름, 실제 데이터, 파일 크기 등을 구할 수 있음.
[참고] https://antstudy.tistory.com/308 [공부하는 개미:티스토리]
@PostMapping("/regItem") public String regItem(ItemVO itemVO, @RequestParam(name = "mainImg") MultipartFile mainImg , @RequestParam(name = "subImgs") MultipartFile[] subImgs){ ➡️ 업로드하는 HTML Form의 name에 맞추어 @RequestParam 적용 ➡️ mainImg(첨부파일1: 메인이미지 1장), subImgs(첨부파일2: 상세이미지 여러장) }
- UUID는 고유한 데이터 또는 리소스를 식별함. 데이터 또는 리소스는 객체, 파일, 문서, 이미지 등이 될 수 있으며, UUID가 광범위하게 사용되는 경우 전역 고유 식별자인 GUID라고 부르기도 함.
- UUID는 32개의 16진수 기반의 문자와 4개의 하이픈(-)으로 구성된 총 36개의 문자. 36개의 문자는 8-4-4-4-12와 같이 표현되며 UUID의 크기는 128 Bit.
- UUID 클래스는 java.util 패키지에 존재함
- ⭐UUID 생성 방법
public static void main(String args[]) { UUID uuid = UUID.randomUUID(); System.out.println(uuid); } ➡️ 실행 결과 585a1429-2a79-4940-9488-6cea5bb9cb95 UUID
- 클래스의 randomUUID() 메서드를 사용하여 UUID를 생성할 수 있음. randomUUID() 메서드는 UUID 타입의 객체를 반환하므로 문자열처럼 사용하려면 문자열로 변환하는 작업 필요.
- ⭐UUID를 문자열로 변환 : toString() 메서드 호출
public static void main(String args[]) { UUID uuid = UUID.randomUUID(); // UUID를 문자열로 변환 System.out.println(uuid.toString()); // 문자열로 변환 후 타입 확인 System.out.println(uuid.toString().getClass().getTypeName()); // 문자열로 변환하기 전 타입 확인 System.out.println(uuid.getClass().getTypeName()); } ➡️ 실행 결과 52588691-d763-45fe-8de6-8a632e08384a java.lang.String java.util.UUID
[참고] https://developer-talk.tistory.com/838 [DevStory:티스토리]
String uuid = UUID.randomUUID().toString(); //랜덤한 문자열 생성(16글자, 중복X)
//파일 첨부와 관련된 기능 모음집 public class UploadUtil { //파일의 확장자를 문자열로 return하는 메소드 public static String getExtension(String fileName){ return fileName.substring(fileName.lastIndexOf(".")); } //uuid를 통한 파일명 생성 public static String getUUID(){ //랜덤으로 만들어진 uuid를 문자열로 리턴 return UUID.randomUUID().toString(); } //단일 파일 업로드 메소드 public static ImgVO uploadFile(MultipartFile uploadFile){ ImgVO imgVO = null; //첨부 파일이 존재할 때만 첨부 기능 실행 if(!uploadFile.isEmpty()){ //객체 생성 imgVO = new ImgVO(); //확장자 추출 String extension = getExtension(uploadFile.getOriginalFilename()); //중복 되지 않는 파일명 생성(파일명: 랜덤한 uuid + 확장자) String fileName = getUUID() + extension; //예외 처리 try { File file1 = new File(ConstantVariable.UPLOAD_PATH + fileName); //경로 및 파일명 uploadFile.transferTo(file1); //첨부 끝난 후 - 첨부파일명, 원본파일명 imgVO.setAttachedFileName(fileName); imgVO.setOriginFileName(uploadFile.getOriginalFilename()); imgVO.setIsMain("Y"); }catch (Exception e){ System.out.println("파일 첨부 중 예외 발생!"); e.printStackTrace(); //오류가 난 위치 및 간략한 원인을 콘솔창에 출력 } } return imgVO; } //다중 첨부 메소드 public static List<ImgVO> multiUploadFile(MultipartFile[] uploadFiles){ List<ImgVO> imgList = new ArrayList<>(); for(MultipartFile uploadFile : uploadFiles){ ImgVO vo = uploadFile(uploadFile); //이미지 하나에 대한 원본 파일명 등 if(vo != null){ vo.setIsMain("N"); imgList.add(vo); } } return imgList; } }
- 상수는 대문자로 작성
final int NUM = 10; NUM = 20; -> 오류 : final int(상수)로 num의 최종값이 정해졌기 때문
- 상수를 저장하고 있는 클래스 생성
public class ConstantVariable { public final static String UPLOAD_PATH = "D:\\01-STUDY\\dev\\workspace_sts\\Shop\\src\\main\\resources\\static\\upload\\"; }
<div class="col-12"> <label for="" class="form-label">상품 대표 이미지</label> <input class="form-control" type="file" name="mainImg"> </div> <div class="col-12"> <label for="" class="form-label">상품 상세 이미지</label> <input class="form-control" type="file" name="subImgs" multiple> </div> <div> <button type="submit" class="btn btn-primary">상품등록</button> </div>
//받는 자료형이 숫자, 문자가 아닌 경우 매개변수로 Multi~ 사용 public String upload(@RequestParam(name = "img1") MultipartFile img1 , @RequestParam(name = "img2") MultipartFile img2){ //.getOriginalFilename() : 첨부한 파일명 String originFileName = img1.getOriginalFilename(); //return type: String System.out.println(originFileName); //업로드 경로 String uploadPath = "D:\\01-STUDY\\dev\\workspace_sts\\Shop\\src\\main\\resources\\static\\upload\\"; //파일 업로드 //업로드할 경로 및 파일명을 하나의 문자열로 나열 String fileName = uploadPath + originFileName; //파일을 업로드 //java.io.file try { File file = new File(fileName); img1.transferTo(file); } catch (IOException e) { System.out.println("!!!!파일 첨부 중 오류 발생!!!!"); throw new RuntimeException(e); } //두번재 파일 업로드 //원본 파일의 확장자만 추출 String secondOriginFileName = img2.getOriginalFilename(); String extension = secondOriginFileName.substring(secondOriginFileName.lastIndexOf(".")); //서버에 저장할 파일명 생성 String uuid = UUID.randomUUID().toString(); //랜덤한 문자열 생성(16글자, 중복X) String attachedFileName = uuid + extension; //예외처리 try { File file1 = new File(uploadPath + attachedFileName); img2.transferTo(file1); }catch (Exception e){ System.out.println("파일 첨부 중 오류 발생!"); e.printStackTrace(); //왜 오류가 나는지 알려줌 } return ""; }