티스토리 뷰
개인적으로 만들어보고 있는 자바 스프링 프로젝트에서 외부 리소스 파일을 읽어야 할 일이 있어 찾아보는데 정말 내가 잘못된 개념을 알고 있었던 것 같아 적용하는데 골머리를 앓았고, 또 그만큼 엄청난 것을 깨달았다.
상대경로 표현에서
./
이 것이 현재 디렉토리를 나타내는 표현이라는 것은 어렵지 않게 알 수 있다.
그런데,
그 현재 디렉토리라는 것이 대체 어디인가?
나는 정말로 모르고 있었다.
그것은 바로..
jar을 실행시킨 위치!!
(이는 "현재 작업 디렉토리(Working Directory)"라는 표현과 동일하다.)
스프링 부트의 경우 jar 파일을 만들어서 배포하기 때문에
java -jar 명령어를 이용해 jar을 실행시킨 위치가 바로 현재 디렉토리(작업 디렉토리)의 위치가 되는 것이었다.
근데 배포된 jar 파일을 어디서 실행시킬지 까지 개발 시점에 다 예측하고 하드코딩을 해둘 수는 없는 노릇이다.
그렇기에 jar을 어디서 실행시켰는지 몰라도 코드로도 내 현재 프로젝트의 경로를 확인할 수 있다.
1. System.getProperty
public static void main(String[] args) {
String path = System.getProperty("user.dir");
System.out.println(path);
}
2. 상대경로를 먼저 얻은 다음에 절대경로로 변환
public static void main(String[] args) {
Path path = Paths.get("");
System.out.println(path.toAbsolutePath().toString());
}
둘 다 동일한 결과를 반환한다. 개인적으로는 2번이 좋아보인다.
그렇다면 외부 리소스 파일을 읽을 때 어떻게 접근할 수 있을까?
마찬가지로 상대경로로 먼저 리소스 파일의 위치를 잡은 다음에 이를 절대경로로 변환하는 방법으로 해보자.
public static void main(String[] args) {
Path path = Paths.get("storage/init/regionList.csv");
System.out.println(path.toAbsolutePath().toString());
}
(맨 앞에 ./ 는 생략 가능하다)
1. 윈도우 환경
./storage/init/regionList.csv를 하면 어떻게 파일을 접근하는 것인가?
IDE가 jar 파일을 실행시킨 위치가 .../Capstone/smartnotice/ 이고 (현재 작업 디렉토리)
거기에 상대경로로 만들어진 storage/init/regionList.csv 경로를 붙이면 절대경로로 된 파일을 얻을 수 있게 된다.
2. 리눅스(EC2) 환경
프로젝트 작업 디렉토리: /home/ec2-user/app/test/test2/ (절대 경로)
외부 리소스 파일 경로: storage/init/regionList.csv (상대 경로)
두개를 합쳐서 위와 같이 나오는 것!!
그리고 해당 절대 경로 위치에 파일이 존재하고 있어야 해당 파일을 읽을 수 있다는 것이다. 당연한 얘기다.
요런 느낌으로다가 jar 파일을 실행시킨 디렉토리에 외부 리소스 폴더가 같이 붙어다니는 그림으로 생각하면 되겠다.
물론 폴더 구성은 만드는 사람이나 환경에 따라 제각각이겠지만 이 개념 하나만 잘 알고가면 응용하는 것은 큰 문제가 없을 것이라 생각한다.
(+) 부록
왜 외부 리소스 폴더를 별도로 사용하는지?
- src/main/resources 디렉토리 내부에다 넣어두고 jar 파일에 같이 묶어서 배포하면 안되나?
> resources 폴더 내에 넣으면 내부 리소스 파일이 수정됐을 때 다시 빌드를 해야 해당 수정사항을 반영할 수 있다.
> 하지만 외부 폴더에 따로 빼놓으면 빌드 없이도 자유롭게 변경사항을 즉시 적용할 수 있다.
> 게시판 만들기에서 첨부파일을 서버에 저장할 때와 같은 경우 꼭 외부에 폴더를 따로 빼서 저장해야 한다. 이것도 위에 얘기를 생각해보면 당연한 얘기다. 사용자가 첨부파일을 업로드 했는데 해당 파일을 빌드를 한 이후에 다시 받을 수 있다고 생각하면 말이 안된다.
정말 윈도우 환경에서 그냥 스프링 이니셜라이저가 만들어준대로 그저 그런가보다 하고 만들다보니 이런 기초적인 것 조차 모르고 있었다...
오늘 정말 큰걸 배운 것 같아 뜻깊은 하루였다.
'웹 > Spring' 카테고리의 다른 글
@Valid를 이용한 회원가입 입력값 검증 - 1단계 (0) | 2022.10.19 |
---|---|
Swagger (Springfox)를 이용해 스프링 프로젝트의 API 문서 만들어보기 (0) | 2022.09.08 |
application.properties 설정 파일 분리해보기 (0) | 2022.08.24 |
스프링 부트 | Port 8080 was already in use 해결 (0) | 2022.08.22 |
스프링 볶음밥 - 8, 9장 (0) | 2022.07.12 |