서블릿 기반 애플리케이션에서 구성 자원 파일을 배치하는 위치 및 방법은 무엇입니까?


222

내 웹 응용 프로그램에서와 같은 미리 정의 된 사용자 집합에게 전자 메일을 보내야 finance@xyz.com하므로 .properties파일 에 추가하고 필요할 때 액세스하고 싶습니다 . 올바른 절차입니까? 그렇다면이 파일을 어디에 배치해야합니까? 소스 및 JSP 파일을위한 두 개의 별도 폴더가있는 Netbeans IDE를 사용하고 있습니다.


JNDI는 아마도 해결책일까요?
Basil Bourque

답변:


464

당신의 선택입니다. Java 웹 애플리케이션 아카이브 (WAR)에는 기본적으로 세 가지 방법이 있습니다.


1. 클래스 패스에 넣습니다

ClassLoader#getResourceAsStream()클래스 경로 상대 경로를 사용하여 로드 할 수 있습니다 .

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

여기 foo.properties에는 webapp /WEB-INF/lib/WEB-INF/classesserver /lib, 또는 JDK / JRE 와 같은 webapp의 기본 클래스 경로에 포함되는 루트 중 하나에 배치됩니다 /lib. propertiesfile이 webapp 전용 인 경우에 배치하는 것이 가장 좋습니다 /WEB-INF/classes. IDE에서 표준 WAR 프로젝트를 개발하는 경우 src폴더 (프로젝트의 소스 폴더)에 놓으십시오 . Maven 프로젝트를 사용하는 경우 /main/resources폴더에 놓으십시오 .

또는 기본 클래스 경로 외부에 배치하고 해당 경로를 앱 서버의 클래스 경로에 추가 할 수도 있습니다. 예를 들어 Tomcat에서는 shared.loader속성을 다음과 같이 구성 할 수 있습니다Tomcat/conf/catalina.properties .

foo.properties와 같은 Java 패키지 구조에 배치 한 경우 com.example아래와 같이로드해야합니다.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...

컨텍스트 클래스 로더의이 경로는로 시작해서는 안됩니다 /. 와 같은 "상대적"클래스 로더를 사용하는 경우에만 SomeClass.class.getClassLoader()실제로로 시작해야합니다 /.

ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...

그러나 특성 파일의 가시성은 해당 클래스 로더에 따라 다릅니다. 클래스를로드 한 것과 동일한 클래스 로더에서만 볼 수 있습니다. 따라서 클래스가 webapp classloader 대신 server common classloader에 의해로드되고 속성 파일이 webapp 자체에있는 경우 보이지 않습니다. 컨텍스트 클래스 로더는 가장 안전한 방법이므로 클래스 파일의 "모든 위치"에 속성 파일을 배치하거나 웹 응용 프로그램에서 서버가 제공 한 파일을 재정의 할 수 있습니다.


2. webcontent에 넣으십시오

ServletContext#getResourceAsStream()webcontent 기준 경로를 사용하여 로드 할 수 있습니다 .

InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...

파일을 /WEB-INF폴더 에 저장 하는 방법을 시연했습니다 . 그렇지 않으면 모든 웹 브라우저에서 공개적으로 액세스 할 수 있습니다. 또한이 있습니다 ServletContext어떤에 HttpServlet상속에 의해 단지 접근 클래스 GenericServlet#getServletContext()와에 Filter의해 FilterConfig#getServletContext(). 서블릿 클래스에없는 경우 일반적으로을 통해 주입 할 수 @Inject있습니다.


3. 로컬 디스크 파일 시스템에 넣습니다.

java.io절대 로컬 디스크 파일 시스템 경로를 사용 하여 일반적인 방법으로 로드 할 수 있습니다 .

InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...

절대 경로를 사용하는 것이 중요합니다. 상대 로컬 디스크 파일 시스템 경로는 Java EE 웹 응용 프로그램에서 절대적으로 필요하지 않습니다. 아래의 첫 번째 "참조"링크도 참조하십시오.


어느 것을 선택해야합니까?

유지 보수성 에 대한 자신의 의견으로 장단점을 측정하십시오 .

특성 파일이 "정적"이고 런타임 중에 변경할 필요가없는 경우 WAR에 보관할 수 있습니다.

매번 WAR을 다시 빌드하고 재배치 할 필요없이 웹 애플리케이션 외부에서 특성 파일을 편집 할 수있는 경우 프로젝트 외부의 클래스 경로에 배치하십시오 (필요한 경우 디렉토리를 클래스 경로에 추가).

Properties#store()메소드를 사용하여 웹 애플리케이션 내부에서 프로그래밍 방식으로 특성 파일을 편집 할 수있게하려면 웹 애플리케이션 외부에 배치하십시오. (가)로 Properties#store()이 필요합니다 Writer, 당신은 디스크 파일 시스템 경로를 사용하여 주변에 갈 수 없습니다. 이 경로는 VM 인수 또는 시스템 속성으로 웹 응용 프로그램에 전달 될 수 있습니다. 예방책으로 절대로 사용 하지 마십시오getRealPath() . 배포 폴더의 모든 변경 사항은 변경 사항이 원래 WAR 파일에 다시 반영되지 않기 때문에 재배치시 손실됩니다.

또한보십시오:


2
"개인적으로 프로젝트 외부의 클래스 경로에 넣는 것을 선호합니다 (클래스 경로에 새로운 경로 추가)"라고 혼동을 겪을 수 있습니까?
Blankman

4
@Blankman 그는 아마도 새 폴더를 만들고 모든 사용자 정의 구성 파일을 거기에 넣고 해당 폴더를 클래스 경로에 추가하는 것을 의미합니다. 따라서 : 1) 어딘가에 'appconfs'라는 폴더를 만드십시오 ( /etc/appconfs2 일 수도 있습니다 ) 해당 폴더를 앱 서버 / 도메인의 클래스 경로에 추가하십시오. 두 번째 단계는 앱 서버마다 다르며 일반적인 예는 없다고 생각합니다.
Tuukka Mustonen

재 : 2 : 왜 둘 것 "WEB-INF/filename.properties""/WEB-INF/filename.properties"(통지 /일 시작 부분에서)? 다른 것을 선호하는 이유가 있습니까?
Mr_and_Mrs_D

지난 하루 동안이 문제가 해결되었습니다. 속성 파일을로드 할 수 없습니다. 두 곳에서로드 할 수 있습니다. 하나는 시스템 디렉토리이고 다른 하나는 로컬 드라이브입니다. localhost와 함께 작동합니다. 그러나 아마존에 배포하고 싶습니다.
Arun Raja

netbeans IDE를 사용 중이며 등록 정보 파일을 웹 페이지 / 자원에 보관합니다. "./Web Pages / resources / config.properties"로 액세스하려고합니다. 액세스 할 수 없습니다. 도와주세요.
Arun Raja

9

경고 : 구성 파일을 WEB-INF/classes폴더에 넣고 IDE (예 : Eclipse)가 정리 / 재 구축을 수행하면 Java 소스 디렉토리에 있지 않은 한 conf 파일을 압축합니다. BalusC의 훌륭한 답변은 옵션 1의 답변을 암시하지만 강조하고 싶습니다.

Eclipse에서 웹 프로젝트를 "복사"하면 소스 폴더에서 정리 / 재 구축을 수행하는 어려운 방법을 배웠습니다. 필자의 경우 POJO Java 라이브러리에서 "linked source dir"을 추가하면 WEB-INF/classes폴더로 컴파일됩니다 . 웹 프로젝트가 아닌 해당 프로젝트에서 정리 / 재 구축을 수행해도 동일한 문제가 발생했습니다.

POJO src 폴더에 conf를 넣는 것에 대해 생각했지만이 conf는 폴더에있는 타사 라이브러리 (예 : Quartz 또는 URLRewrite)에 대한 WEB-INF/lib것이므로 의미가 없습니다. 나는 그것을 돌아갈 때 웹 프로젝트 "src"폴더에 넣는 것을 테스트 할 계획이지만 그 폴더는 현재 비어 있으며 conf 파일을 가지고있는 것은 우아하지 않은 것 같습니다.

에서의 conf 파일을 착용하는 I 투표 그래서 WEB-INF/commonConfFolder/filename.properties, 다음 Balus 옵션 2 클래스 폴더에.


1
구성 파일을 WEB_INF의 하위 폴더에 넣으면 어떻게 도달합니까? 나는 'configFiles / prop.properties'라고 말하지 않았다
JesseBoyd

좋아, 이것은 속성 파일을 'Java Resources / src /'에 넣는 것으로 작동합니다. 내 패키지 중 하나에서 작동하지 않으며 src의 루트에 있어야합니다. 클래스 폴더가 숨겨지는 것에 대한 경고는 유효한 문제입니다.
JesseBoyd

6

예 : web.xml 파일에서 태그

<context-param>
        <param-name>chatpropertyfile</param-name>
        <!--  Name of the chat properties file. It contains the name and description                   of rooms.-->     
        <param-value>chat.properties</param-value>
    </context-param>

그리고 chat.properties는 다음과 같이 속성을 선언 할 수 있습니다

예를 들어 :

Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.

5

클래스 경로에 있어야합니다 (빌드의 일부로 .war의 / WEB-INF / classes 아래에 있는지 확인하십시오).


아이디어에 감사드립니다, 그러나 그것은 지정된 파일을 찾을 수 없다는 것을 말해줍니다. 예, 경로 문제는 경로를 제공하는 방법
sansknwoledge

3

소스 폴더를 사용하면 빌드 할 때마다 해당 파일이 클래스 디렉토리에 자동으로 복사됩니다.

특성 파일을 사용하는 대신 XML 파일을 사용하십시오.

데이터가 너무 작 으면 web.xml을 사용하여 속성에 액세스 할 수도 있습니다.

이러한 접근 방식 중 하나라도 변경 사항을 반영하려면 앱 서버를 다시 시작해야합니다.


웹 페이지 폴더에 배치했지만 파일에 액세스 할 수 없습니다. 파일을 찾을 수 없습니다. 오류는 경로를 설정하는 방법입니다.
sansknwoledge

1
파일이 WEB-INF / classes 폴더에 있으면 자동으로 classpath로 설정됩니다
Kalpak

2

코드가 app.properties 파일을 찾고 있다고 가정하십시오. 이 파일을 임의의 디렉토리에 복사하고 tomcat의 bin 디렉토리에 setenv.sh를 작성하여이 디렉토리를 클래스 경로에 추가하십시오.

tomcat의 setenv.sh에서 (이 파일이 존재하지 않으면 하나를 작성하십시오. tomcat은이 setenv.sh 파일을로드합니다. #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

./webapps//WEB-INF/classes/app.properties에 특성 파일이 없어야합니다.

Tomcat 클래스 로더는 WEB-INF / classes /의 것으로 로더를 대체합니다.

좋은 읽을 거리 : https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.