경로
일반적으로 절대 경로와 상대 경로로 구분한다. 절대 경로는 CDN(콘텐츠 전송 네트워크)을 사용하거나, 웹에 올려진 미디어 등을 사용할 때 사용한다. 상대 경로는 디렉토리 내부에서 모듈을 연결하거나, 다른 파일을 import하는 경우에 사용하게 된다.
절대 경로
절대 경로는 파일의 root부터 해당 파일까지의 전체 경로(URL)를 의미한다. 절대 경로는 보통 다른 사람의 문서나 파일을 이용할 때 사용한다. 절대 경로는 어느 곳에서든 경로에 접근할 수 있다는 장점이 존재한다. 그러나 경로가 변경되면 경로를 일일히 수정해야 한다는 단점이 있다.
Ex) C:\Program Files\Git
상대 경로
상대 경로는 현재 파일의 위치를 기준으로 연결하려는 파일의 상대적인 경로를 적는 것을 의미한다. 상대 경로는 주소나 프로젝트 디렉토리 위치가 바뀌어도 내부 구조만 그대로라면 수정없이 그대로 사용할 수 있다는 장점을 가지고 있다. 그러나 자기 자신이 기준이기 때문에 자기 자신의 위치가 바뀌는 것에 취약하다는 단점이 있다.
Ex) ./src/compnents/Counter.js
실습
1. 서버의 정적 리소스 경로에 저장하기
현재 저장할 경로 : C:\app\images\
1) application.yml
spring:
web:
resources:
static-locations: file:///C:/app/images/
2) Service
// 파일이 저장될 기본 경로를 설정 (여기서는 src/main/resources/static/vehicleImage로 설정)
private final String uploadDir = "src/main/resources/static/vehicleImage";
@Override
public int updateVehicleImage(String vehicleCode, MultipartFile file) throws Exception {
// 차량 이미지가 저장될 하위 디렉토리 설정 (Windows 경로)
String subDir = "vehicleImage\\";
// 파일이 저장될 절대 경로 설정 (C 드라이브에 있는 app/images/vehicleImage 폴더에 저장)
String fullPath = "C:\\app\\images\\" + subDir;
// 파일을 저장할 디렉토리 객체 생성
File dir = new File(fullPath).getAbsoluteFile();
// 디렉토리가 존재하지 않는 경우 디렉토리 생성
if (!dir.exists()) {
boolean isDirCreated = dir.mkdirs(); // 디렉토리 및 필요한 모든 상위 디렉토리 생성 시도
if (!isDirCreated) {
// 디렉토리 생성에 실패한 경우 예외 발생
throw new Exception("Failed to create directory: " + fullPath);
}
}
// 파일 이름을 차량 코드와 업로드된 파일의 원본 이름을 조합하여 생성
String fileName = vehicleCode + "_" + file.getOriginalFilename();
// 최종적으로 파일이 저장될 경로 설정
File saveFile = new File(dir, fileName);
try {
// 업로드된 파일을 지정된 경로에 저장
file.transferTo(saveFile);
} catch (IOException e) {
// 파일 저장 중 오류가 발생한 경우 예외 발생
throw new Exception("Failed to save file: " + fileName, e);
}
// 파일 이름을 데이터베이스에 저장하여, 이후에 파일을 참조할 수 있도록 함
return dao.updateVehicleImage(vehicleCode, fileName);
}
3) 테스트 후 저장 위치를 확인해보면 이미지가 올라가 있음
- 화면에서도 IDE 새로고침 없이 이미지 바로 보기 가능
2. Base64Encoded 사용
- 데이터베이스에서 이미지 파일 이름을 가져온 뒤, 해당 이미지를 읽어 Base64 형식으로 인코딩하여 문자열로 반환
- 서버에서 이미지 파일을 직접 서빙하는 대신, Base64 인코딩된 문자열을 HTML로 전달하여 브라우저에서 바로 이미지를 표시할 수 있다.
- 외부 서버에 파일을 업로드하거나 직접 접근할 수 없을 때 사용
@Override
public String selectVehicleImages(String vehicleCodes) {
// 데이터베이스에서 vehicleCode에 해당하는 VehicleVo 객체를 가져옴
VehicleVo vehicleImage = dao.selectVehicleImages(vehicleCodes);
// Base64로 인코딩된 이미지를 저장할 변수를 초기화
String vehicleImgBase64 = "";
// vehicleImage 객체가 null이 아니고, 이미지 파일명이 존재하는지 확인
if (vehicleImage != null && vehicleImage.getVehicleImg() != null) {
// 이미지 파일이 저장된 경로와 파일명을 사용하여 File 객체 생성
File vehicleImgFile = new File(path + "/" + vehicleImage.getVehicleImg());
// FileInputStream을 사용하여 파일을 읽어옴, try-with-resources를 사용하여 자원을 자동으로 해제
try (FileInputStream fileInputStream = new FileInputStream(vehicleImgFile)) {
// 파일 크기만큼의 바이트 배열을 생성하고, 파일 데이터를 읽어옴
byte[] vehicleImgBytes = new byte[(int) vehicleImgFile.length()];
fileInputStream.read(vehicleImgBytes);
// 파일 데이터를 Base64로 인코딩하여 문자열로 변환
String base64Encoded = Base64.getEncoder().encodeToString(vehicleImgBytes);
// 이미지의 확장자를 추출하여 데이터 URL 형식의 문자열 생성
vehicleImgBase64 = "data:image/"
+ (vehicleImage.getVehicleImg().substring(vehicleImage.getVehicleImg().lastIndexOf(".") + 1))
+ ";base64," + base64Encoded;
// 생성된 Base64 문자열을 반환
return vehicleImgBase64;
} catch (IOException e) {
// 파일 읽기 또는 인코딩 중 오류가 발생하면 예외 스택 트레이스를 출력
e.printStackTrace();
}
} else {
// vehicleImage가 null이거나 이미지 파일명이 없을 경우 빈 문자열을 반환
return "";
}
// (사실상 도달할 수 없는 코드지만) 안전을 위해 마지막에 Base64 문자열 반환
return vehicleImgBase64;
}
'SPRING' 카테고리의 다른 글
SPRING :: LoggingAop (0) | 2024.10.08 |
---|---|
SPRING :: LoggingFilter 접속 로그 필터 구현 (0) | 2024.10.08 |
RestTemplate :: HTTP (REST)요청/응답 클래스 (0) | 2024.09.01 |
SPRING :: Security 로그인 구현 03 React 화면 구성 (0) | 2024.08.18 |
SPRING :: Security 로그인 구현 02 SecurityConfig (0) | 2024.08.18 |