fileName당신이 통과 하는 방법에 대한 미묘한 차이점이 있습니다 . 기본적으로, 당신은 2 개 가지 방법이 있습니다 ClassLoader.getResourceAsStream()와 Class.getResourceAsStream(). 이 두 가지 방법은 리소스를 다르게 찾습니다.
에서 Class.getResourceAsStream(path), 경로는 당신이에서 호출하는 클래스의 패키지 로컬 경로로 해석됩니다. 예를 들어, 호출 String.getResourceAsStream("myfile.txt")은 다음 위치에서 클래스 경로에서 파일을 찾습니다 "java/lang/myfile.txt". 경로가로 시작 /하면 절대 경로로 간주되며 클래스 경로의 루트에서 검색을 시작합니다. 따라서 전화 String.getResourceAsStream("/myfile.txt")는 수업 경로에서 다음 위치를 봅니다 ./myfile.txt.
ClassLoader.getResourceAsStream(path)모든 경로를 절대 경로로 간주합니다. 그래서 호출 String.getClassLoader().getResourceAsStream("myfile.txt")및 String.getClassLoader().getResourceAsStream("/myfile.txt")것이다 다음 위치에서 클래스 경로에있는 파일 모두보기 : ./myfile.txt.
이 게시물에서 위치를 언급 할 때마다 리소스를로드하는 Class 및 / 또는 ClassLoader에 따라 파일 시스템 자체 또는 해당 jar 파일 내의 위치 일 수 있습니다.
귀하의 경우 Application Server에서 클래스를로드하므로 Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)대신 대신 사용해야 합니다 this.getClass().getClassLoader().getResourceAsStream(fileName). this.getClass().getResourceAsStream()작동합니다.
특정 문제에 대한 자세한 정보는 이 기사 를 읽으십시오 .
Tomcat 7 이하 사용자에게 경고
이 질문에 대한 답변 중 하나는 Tomcat 7에 대한 설명이 올바르지 않은 것 같습니다. 나는 왜 그런지 알기 위해 주위를 둘러 보았습니다.
그래서 Tomcat의 WebAppClassLoader여러 버전에 대한 Tomcat의 소스 코드를 살펴 보았습니다 . findResource(String name)Tomcat 6과 Tomcat 7에서는 구현이 요청 된 자원에 대한 URL을 생성하는 데 가장 큰 책임이 있습니다. 그러나 Tomcat 8에서는 다릅니다.
버전 6 및 7에서는 구현시 자원 이름을 정규화하지 않습니다. 즉,이 버전에서는 Javadoc이 지정하는 것이므로 이벤트 classLoader.getResourceAsStream("/resource.txt")와 동일한 결과를 생성하지 못할 수도 있습니다 classLoader.getResourceAsStream("resource.txt"). [소스 코드]
그러나 버전 8에서는 자원 이름의 절대 버전이 사용되는 것을 보장하기 위해 자원 이름이 정규화됩니다. 따라서 Tomcat 8에서 위에서 설명한 두 호출은 항상 동일한 결과를 반환해야합니다. [소스 코드]
따라서 Tomcat 8 이전 버전을 사용 ClassLoader.getResourceAsStream()하거나 사용할 때는 각별히주의 Class.getResourceAsStream()해야합니다. 또한 class.getResourceAsStream("/resource.txt")실제로 전화를 걸면됩니다 classLoader.getResourceAsStream("resource.txt")(리딩 /은 제거됨).
getClass().getResourceAsStream("/myfile.txt")과 다르게 행동 한다고 확신합니다getClassLoader().getResourceAsStream("/myfile.txt").