2010-05-09 31 views
39

Ich habe die folgende Struktur in einer Java-Web-Anwendung:getResourceAsStream() immer null Rückkehr

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

In WS.java, ich den folgenden Code in einer Web-Methode verwendet:

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

Aber es gibt immer eine Null zurück. Ich muss von dieser Datei lesen, und ich lese, dass wenn Sie die Dateien in WEB-INF setzen, können Sie auf sie mit getResourceAsStream zugreifen, aber die Methode gibt immer eine null zurück.

Irgendwelche Ideen, was ich falsch machen könnte?

Btw, das Merkwürdige ist, dass dies funktioniert, aber nachdem ich ein Clean and Build auf dem Projekt durchgeführt, es funktioniert plötzlich:/

Antwort

35

Mein Wissen der Datei in dem Ordner, rechts sein muss, wo die 'this' Klasse befindet, also nicht in WEB-INF/classes sondern verschachtelt noch tiefer (es sei denn, Sie in einem Standard-Paket schreiben):

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

in die Datei Putting sollte auf Ihre Java-Quellen arbeiten, Compiler Kopien, die zusammen mit Klassendateien Datei.

+0

+1 Prost Mate, es hat funktioniert. Ich habe die Datei nach 'wservices' verschoben und sie funktioniert jetzt –

+3

Wenn Sie Eclipse verwenden, müssen Sie auch 'F5' (aktualisieren) drücken, damit Ihre 'abc.txt' im Paket-Explorer erscheint, andernfalls gibt getResource() immer null zurück . –

+0

Ich fand Unit Tests waren mehr verzeihend für den Speicherort der Datei in Eclipse/Maven, aber wenn gepackt und bereitgestellt die Datei funktionierte nur, wenn ich es verschoben, um den Speicherort der Klasse entsprechen diese Antwort empfohlen. –

28

Ein Anruf an Class#getResourceAsStream(String) Delegaten an den Klassenlader und die Ressource wird im Klassenpfad gesucht. Mit anderen Worten, Ihr aktueller Code funktioniert nicht und Sie sollten abc.txt in WEB-INF/classes oder in WEB-INF/lib, wenn in einer JAR-Datei verpackt, setzen.

Oder Verwendung ServletContext.getResourceAsStream(String) die Servlet-Container ermöglichen eine Ressource zur Verfügung zu einem Servlet von jedem Ort aus zu machen, ohne einen Klassenlader zu verwenden. Also diese verwenden, um von einem Servlet:

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

Aber ist es eine Möglichkeit, ich getServletContext von meinem Web-Service anrufen kann?

Wenn Sie JAX-WS verwenden, dann können Sie eine WebServiceContext erhalten injiziert:

@Resource 
private WebServiceContext wsContext; 

Und dann die ServletContext von ihm bekommen:

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

Aber kann ich 'getServletContext' von meinem Web Service aus aufrufen? –

5

Ich weiß nicht, ob das gilt für JAX-WS, aber für JAX-RS konnte ich auf eine Datei zugreifen, indem ich einen ServletContext injizierte und getResourceAsStream() darauf aufruft:

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

Beachten Sie, dass zumindest in GlassFish 3.1 der Pfad absolut sein musste, d. H. Mit Schrägstrich beginnen. Mehr hier: How do I use a properties file with jax-rs?

6

Ich denke, auf diese Weise können Sie die Datei von "überall" (einschließlich Server-Standorten) und Sie brauchen nicht zu kümmern, wo es zu setzen.

Es ist normalerweise eine schlechte Übung, sich um solche Dinge kümmern zu müssen.

1

Ich hatte das gleiche Problem, als ich von Websphere 8.5 zu WebSphere Liberty wechselte.

I verwendet FileInputStream statt getResourceAsStream(), weil aus irgendeinem Grunde WebSphere Freiheit die Datei in dem Ordner WEB-INF nicht finden kann.

Das Drehbuch war:

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

Hinweis: ich das Skript für die Entwicklung nur dann verwendet.

8

Statt

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

Verwendung

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

Auf diese Weise es von der Wurzel aussehen wird, nicht vom Pfad der aktuellen rufenden Klasse

0

Ich hatte ein ähnliches Problem und Ich suchte nach der Lösung für eine ganze Weile: Es scheint, dass der String-Parameter Groß-und Kleinschreibung ist. Wenn Ihr Dateiname also abc.TXT lautet, Sie aber nach abc.txt suchen, wird Eclipse es finden - die ausführbare JAR-Datei nicht.