[GWT] Relative Pfade auf dem Server

kirdie

Bekanntes Mitglied
Ich bin wieder mal am verzweifeln mit GWT, mein derzeitiges Problem ist der Dateizugriff vom Server aus.
Ich habe meine Anwendung unter /home/someuser/projekte/java/meinprojekt/war/meinprojekt-version/WEB-INF/classes.
Jetzt habe ich eine Ressource, sagen wir mal /home/someuser/projekte/java/meinprojekt/war/meinprojekt-version/WEB-INF/classes/myresource.txt" auf die ich gerne zugreifen würde. Jetzt benutze ich "mvn gwt:run" um meine GWT Anwendung im hosted mode zu starten. Aber da ich das letztendlich auf einem webserver habe, kann ich natürlich nicht den absoluten Pfad benutzen, sondern nur den Relativen. Ich gehe also davon aus, dass ich mit "new File("myresource.txt")" auf die Datei zugreifen kann - geht aber nicht (FileNotFoundException). Wenn ich allerdings auf dem Server "String x = new File(".").getAbsolutePath()" mache, dann bekomme ich zurück " /home/someuser/projekte/java/meinprojekt/" was mich sehr verwundert. Da sich ja die Versionsnummer ändern kann, möchte ich nicht jedesmal einen anderen Pfad einstellen, nur wenn ich eine Datei einlesen möchte und wenn ich am Ende die Applikation auf einem richtigen Server habe, dürfte ich ja sowieso nur alles unterhalb des WEB-INF/classes oder wenigstens des meinprojekt-version-Ordners haben.

Die Frage ist jetzt also, wie ich den Pfad zu meinen ganzen Dateien bekomme, kann mir da jemand helfen? Ich bin ziemlich neu mit GWT aber ich finde zu dieser absoluten Grundlagenfrage irgendwie überhaupt nichts. Ich habe beim googlen etwas von "getServletContext().getContextPath()" gelesen, aber da kommt nur ein Leerstring raus.
 
@Bierhumpen: hat er doch geschrieben

@kirdie: Eine Lösung (weis nicht wie gut im Web-bereich) wäre:
Java:
return getClass().getResource("../../../../user.txt").getPath();
Die ganzen [c]../[/c] sollten selbsterklärend sein: da liegen ein paar packages dazwischen. Aber ich kann so meine user.txt abrufen.

MFG

Tomate_Salat
 
@Tomate_Salat: Also wenn du eine Klasse myClass im Package net.mypackage hast, würdest du in der Klasse myClass getClass().getResource("../../user.txt") machen? Das probier ich mal. Aber gibt es auch eine elegantere Lösung?
@Bierhumpen: Wieso nicht? Auf dem Server läuft doch ganz normales Java, warum soll das keine Dateien lesen können?
 
getClass().getResource("../../user.txt") machen
ja, mit [c]..[/c] springst du immer eine Ebene zurück. Wie elegant diese Methode ist, keine Ahnung, beschäftige mich gerade selbst neu im Webbereich.

Also getRealPath(".") wenn ich was direkt aus WEB-INF/classes haben will?
Nein, bei mir geht das auf das war-verzeichnis, aber nicht auf die WEB-INF/classes/... Hier musst du den Pfad halt erweitern.
Java:
getServletContext().getRealPath("/WEB-INF/classes/haumich.tod");
 
Also erstmal danke an alle, das Laden der Propertyfiles funktioniert mit getResources.

Jetzt weiß ich aber nicht, wie ich folgenden Code übersetzen soll:

Java:
public String[] getListOfDataFiles()
{
		File folder = new File("datafiles/");
		if(!folder.exists()) folder.mkdir();
		SortedSet<String> files = new TreeSet<String>(Arrays.<String>asList(folder.list()));
		return files.toArray(new String[0]);
}
und
Java:
public void safeDataFile(String filename, String data) throws Exception
{
	 try
	 {
		File f = new File("datafiles/"+filename);
		PrintWriter out;
		out = new PrintWriter(f);
		Properties p = new Properties();		
		p.put("data", data);
		p.store(out,"my data file");
		out.close();
	}
	catch (IOException e)
	{
		throw new Exception(e);
	}
}
Mit den Streams kann ich ja keine Dateilisten anzeigen oder Dateien erzeugen...
@Noctarius: Mit Ausprobieren merke ich ja nur, ob es überhaupt funktioniert aber nicht, ob das auch immer noch die optimale oder eleganteste Lösung ist.
 
Ok,
Java:
return getServletContext().getRealPath(".")
liefert mir den Pfad "/home/someuser/projekte/java/meinprojekt/war/meinprojekt-version/", was schon mal super ist,
Java:
getServletContext().getContextPath()
allerdings immer noch nur einen Leerstring. Müsste getContextPath nicht das gleiche zurückgeben wie getRealPath(".")?

P.S.: Was ist denn die richtige Position für meine Ressourcen, unter .../war/meinprojekt-version/WEB-INF/classes oder direkt unter .../war/meinprojekt-version/? Es sind ja Dateien und keine Klassen.
 
Zuletzt bearbeitet:
Hm, jetzt geht es auf einmal nicht mehr. Ich hatte den Aufruf von "getServletContext().getRealPath(".")" in einer Methode, die erst später per RPC aufgerufen wurde, wenn ich den Aufruf jedoch im Konstruktor habe, bekomme ich eine Nullpointerexception.
Wird der Context erst später, nach dem Konstruktor, initialisiert? Was kann ich da machen?

Java:
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService
{
[...]
	final String resourcePath;

	public GreetingServiceImpl()
	{
		resourcePath = getServletContext().getRealPath(".")+"WEB-INF/classes/";
	}
[...]
führt zu
Java:
java.lang.NullPointerException
	at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:160)
	at net.saim.gwt.server.GreetingServiceImpl.(GreetingServiceImpl.java:64)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[...]
 
Theoretisch kann es da noch nicht initialisiert sein, weil es ja irgendwo herkommen muss. Da du es nicht im Constructor als Parameter hast, kann die Superclass es da auch nicht aus dem Constructor holen.

Liegt die Vermutung nahe (und ich meine es auch schon mal gelesen zu haben), dass der ServletContext erst in der init-Methode gesetzt wird. (Glaub das war sogar bei allen Servlets so).
 
Vielen Dank! Es ist mir zwar ein Rätsel, warum im Superkonstruktor nicht die Initmethode aufgerufen wird sondern erst später aber so funktioniert es:

Java:
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService
{
[...]
    String resourcePath = null;

	@Override
	public void init() throws ServletException
	{
		super.init();
		resourcePath = getServletContext().getRealPath(".")+"WEB-INF/classes/";
	}
[...]

Blöd ist nur, dass ich jetzt resourcePath nicht mehr als final deklarieren kann aber damit muss ich halt leben.
 

Zurück
Oben