두 손끝의 창조자

jar 파일내 resource 접근 본문

프로그래밍언어/Java

jar 파일내 resource 접근

codinglog 2021. 9. 11. 06:46

jar 파일 내 resource가 있을 때, 예를 들면 스프링부트로 말아서 서비스를 돌리는데 그 안에 리소스를 참조해야하는 경우 리소스를 stream으로 가져오면 사용할 수 있다.

getClass().getResourceAsStream("리소스이름");

문제는 classpath에 서브 디렉토리가 있고 그 안에 리소스가 있는데 정확한 경로를 모르는 경우이다.
스트림이 아니라 파일로 가져올 수 있다면 파일 객체에서 isDirectory() 로 디렉토리를 확인 한 후에 서브 디렉토리를 다시 뒤지는 형태로 Walk가 가능한데 스트림은 그렇게 할 수 없다.

스프링에서는 여러가지 형태로 저장된 리소스를 패턴으로만 찾아서 가져올 수 있도록 도구를 제공한다.

Resource[] resources = ResourcePatternUtils
    .getResourcePatternResolver(new DefaultResourceLoader())
    .getResources("classpath*:msg/**");

패턴으로 리소스 전체 리스트를 배열로 가져올 수 있다. 이것을 이용해서 모든 리소스에 접근을 할 수 있다.
그러면 이거는 어떻게 동작을 하는가?

jar 파일내 리소스는 파일 시스템에서 접근할 수 없는 자원이기 때문에 File로 가져올 수 없었다.

java.net.URL 는 접근하고자 하는 리소스와 연결할 수 있도록 기능을 제공하는데 jar 파일은 java.net.JarURLConnection 을 반환한다.
이 커넥션으로 JAR 파일 내부 리소스에 접근한다.

스프링은 이 커넥션을 이용해서 jar 파일 내 접근을 하고 패턴 매칭으로 클라이언트에서 원하는 파일을 추출해온다.

참조 클래스

org.springframework.core.io.support.ResourcePatternUtils
org.springframework.core.io.DefaultResourceLoader
org.springframework.core.io.support.PathMatchingResourcePatternResolver
org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources
java.net.URL
java.net.JarURLConnection

https://stackoverflow.com/questions/49774517/reading-files-in-a-springboot-2-0-1-release-app

반응형
Comments