GetResourceAsStream() всегда возвращает null

У меня есть следующая структура в веб-приложении Java:

TheProject
  -- [Web Pages]
  -- -- [WEB-INF]
  -- -- -- abc.txt
  -- -- index.jsp
  -- [Source Packages]
  -- -- [wservices]
  -- -- -- WS.java

В WS.java, я использую следующий код в веб-методе:

InputStream fstream = this.getClass().getResourceAsStream("abc.txt");

Но он всегда возвращает нуль. Мне нужно прочитать из этого файла, и я прочитал, что если вы поместите файлы в WEB-INF, вы можете получить к ним доступ с помощью getResourceAsStream, но метод всегда возвращает null.

Любые идеи о том, что я могу делать неправильно?

Кстати, странно, что это работало, но после того, как я выполнил Clean and Build в проекте, он внезапно прекратил работу:/

Ответ 1

Насколько мне известно, файл должен быть прав в папке, где находится класс 'this', т.е. не в WEB-INF/classes, но вложен еще глубже (если вы не пишете в пакете по умолчанию):

net/domain/pkg1/MyClass.java  
net/domain/pkg1/abc.txt

Ввод файла в ваши java-источники должен работать, компилятор копирует этот файл вместе с файлами классов.

Ответ 2

Вызов Class#getResourceAsStream(String) делегатов загрузчика классов и поиск ресурса в пути к классу. Другими словами, текущий код не будет работать, и вы должны поместить abc.txt в WEB-INF/classes или в WEB-INF/lib, если он упакован в файл jar.

Или используйте ServletContext.getResourceAsStream(String), который позволяет контейнерам сервлета предоставлять доступный ресурс сервлету из любого места, без использования загрузчика классов. Поэтому используйте это из сервлета:

this.getServletContext().getResourceAsStream("/WEB-INF/abc.txt") ;

Но есть ли способ, который я могу вызвать getServletContext из моей веб-службы?

Если вы используете JAX-WS, вы можете получить WebServiceContext:

@Resource
private WebServiceContext wsContext;

И затем получите ServletContext от него:

ServletContext sContext= wsContext.getMessageContext()
                             .get(MessageContext.SERVLET_CONTEXT));

Ответ 3

Вместо

InputStream fstream = this.getClass().getResourceAsStream("abc.txt"); 

использование

InputStream fstream = this.getClass().getClassLoader().getResourceAsStream("abc.txt");

Таким образом, он будет выглядеть из корня, а не из пути текущего вызывающего класса

Ответ 4

Я так думаю, что вы можете получить файл из "где угодно" (включая расположение серверов), и вам не нужно заботиться о том, куда его поместить.

Обычно это плохая практика, которая должна заботиться о таких вещах.

Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties");

Ответ 5

Я не знаю, относится ли это к JAX-WS, но для JAX-RS я смог получить доступ к файлу, введя ServletContext и затем вызвав getResourceAsStream() на нем:

@Context ServletContext servletContext;
...
InputStream is = servletContext.getResourceAsStream("/WEB-INF/test_model.js");

Обратите внимание, что, по крайней мере, в GlassFish 3.1, путь должен быть абсолютным, т.е. начинаться с косой черты. Подробнее здесь: Как использовать файл свойств с jax-rs?

Ответ 6

У меня была такая же проблема, когда я перешел из Websphere 8.5 в WebSphere Liberty.

Я использовал FileInputStream вместо getResourceAsStream(), потому что по какой-то причине WebSphere Liberty не может найти файл в папке WEB-INF.

script:

FileInputStream fis = new FileInputStream(getServletContext().getRealPath("/") 
                        + "\WEBINF\properties\myProperties.properties")

Примечание: Я использовал этот script только для разработки.

Ответ 7

У меня была аналогичная проблема, и я долго искал решение: Похоже, что строковый параметр чувствителен к регистру. Поэтому, если ваше имя файла abc.TXT, но вы ищете abc.txt, eclipse найдет его - исполняемый JAR файл не будет.