2010-05-09 16 views
39

que tienen la estructura siguiente en una aplicación Web Java:getResourceAsStream() siempre se vuelve nula

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

En WS.java, estoy usando el siguiente código en un método Web:

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

Pero siempre está devolviendo un nulo. Necesito leer de ese archivo, y leí que si coloca los archivos en WEB-INF, puede acceder a ellos con getResourceAsStream, pero el método siempre devuelve null.

¿Alguna idea de lo que puedo estar haciendo mal?

Por cierto, lo extraño es que se trataba de trabajar, pero después he realizado un Clean and Build en el proyecto, que de repente dejó de funcionar:/

Respuesta

35

Que yo sepa, el archivo tiene que estar bien en la carpeta en la 'this' clase reside, es decir, no en WEB-INF/classes pero anida aún más profundo (a menos que se escribe en un paquete predeterminado):

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

Poner el archivo en que sus fuentes java debería funcionar, copias del compilador que presenten junto con los archivos de clase.

+0

+1 Saludos amigo, funcionó. Moví el archivo a 'wservices' y funciona ahora –

+3

Si está utilizando Eclipse, también debe presionar 'F5' (actualizar) para que su 'abc.txt' aparezca en el explorador de paquetes, de lo contrario getResource() siempre devuelve null . –

+0

Encontré que las pruebas de unidad eran más indulgentes con la ubicación del archivo en Eclipse/maven, pero cuando estaba empaquetado e implementado, el archivo funcionaba solo cuando lo movía para que coincidiera con la ubicación de la clase, como recomendaba esta respuesta. –

28

Una llamada al Class#getResourceAsStream(String) delega al cargador de clases y el recurso se busca en la ruta de la clase. En otras palabras, su código actual no funcionará y debe poner abc.txt en WEB-INF/classes, o en WEB-INF/lib si está empaquetado en un archivo jar.

O uso ServletContext.getResourceAsStream(String) cual permite contenedores de servlets para hacer un recurso disponible a un servlet desde cualquier lugar, sin necesidad de utilizar un cargador de clases. Así que utilice esto desde un Servlet:

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

Pero, ¿hay alguna manera de llamar getServletContext de mi servicio web?

Si está utilizando JAX-WS, entonces se puede obtener un WebServiceContext inyectada:

@Resource 
private WebServiceContext wsContext; 

Y a continuación, obtener la ServletContext de ella:

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

¿Pero hay alguna manera de llamar 'getServletContext' desde mi servicio web? –

5

No sé si esto se aplica a JAX-WS, pero para JAX-RS pude acceder a un archivo inyectando un ServletContext y luego llamando a getResourceAsStream() en él:

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

Tenga en cuenta que, al menos en GlassFish 3.1, la ruta debe ser absoluta, es decir, comenzar con barra inclinada. Más aquí: How do I use a properties file with jax-rs?

6

Creo que de esta manera puede obtener el archivo desde "cualquier lugar" (incluidas las ubicaciones de los servidores) y no necesita preocuparse acerca de dónde colocarlo.

Por lo general, es una mala práctica tener que preocuparse por tales cosas.

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

Tuve el mismo problema cuando cambié de Websphere 8.5 a WebSphere Liberty.

Utilicé FileInputStream en lugar de getResourceAsStream(), porque por alguna razón WebSphere Liberty no puede encontrar el archivo en la carpeta WEB-INF.

El guión fue:

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

Nota: He utilizado este script sólo para el desarrollo.

8

En lugar de

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

uso

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

De esta manera se verá a partir de la raíz, no desde el camino de la clase invocación actual

0

He tenido un problema similar y Busqué la solución por bastante tiempo: Parece que el parámetro de cadena distingue entre mayúsculas y minúsculas. Entonces, si su nombre de archivo es abc.TXT pero busca abc.txt, eclipse lo encontrará; el archivo JAR ejecutable no lo hará.

Cuestiones relacionadas