2010-05-09 7 views
39

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

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.

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

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

ответ

35

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

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

Ввод файла в ваших исходных файлов Java должны работать, составитель копии, подать вместе с файлами классов.

+0

+1 Cheers mate, это сработало. Я переместил файл в 'wservices' и теперь его работаю –

+3

Если вы используете Eclipse, вам также нужно нажать« F5 »(обновить), чтобы ваш« abc.txt »появился в проводнике пакетов, иначе getResource() всегда возвращает null , –

+0

Я обнаружил, что модульные тесты были более прощающими для местоположения файла в Eclipse/maven, но когда они были упакованы и развернуты, файл работал только тогда, когда я переместил его, чтобы он соответствовал местоположению класса, как рекомендовал этот ответ. –

28

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

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

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

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

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

@Resource 
private WebServiceContext wsContext; 

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

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

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

5

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

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

Обратите внимание, что, по крайней мере, в GlassFish 3.1, путь должен быть абсолютным, то есть начинаться с косой черты. Подробнее здесь: How do I use a properties file with jax-rs?

6

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

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

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

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

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

Сценарий был:

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

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

8

Вместо

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

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

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

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

0

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

Смежные вопросы