Hallo liebes Java-Forum,
ich habe einen Tomcat 7 als Applikationsserver laufen auf dem ich mein .war-Verzeichnis deployed habe. Mein Programm hat fünf Schichten:
1. Schicht und 2. Schicht sind nur Datenbank + Zugriff, deswegen habe ich die hier weggelassen.
3. Schicht: Logik
4. Schicht: Logikzugriffsschicht für die Servlets
5. Schicht: Servlets
Ich biete verschiedene Services an, die alle XML oder KML Daten zurückliefern. Die Architektur ist so gedacht auch jeder anders später neue Services implementieren kann, dazu muss er einfach ein eigenes Servlet schreiben, das von meinem TestServlet erbt. Die Klasse TestServlet ergänzt eigentlich die Basis-Servlet Klasse nur um eine Funktion
, die von allen Servlets implementiert sein muss, da ich hierüber Informationen über den Service sammele.
Ich habe mir das so gedacht, dass wenn der Service AllCapabilititiesGetServlet aufgerufen wird, alle Pakete der 5. Schicht durchlaufen werden und für jedes Servlet die Funktion getCapability() aufgerufen wird. Die Funktion schreibt nämlich jedes mal einen Eintrag in ein Array und dieses Arry liefert mein AllCapabilititesGetServlet als XML-File zurück.
Durch die Struktur will ich sicher stellen, dass sobald ein neues Servlet von wem auch immer geschrieben wurde und dann die Capabilitites ausgelesen werden sollen, auch die neu angelegten Servlets berücksichtigt werden und direkt in das Array geschrieben werden.
Dazu habe ich folgende relevante Klassen:
5. Schicht: AllCapabiltiitesGetServlet:
4. Schicht: AllCapabilititesGet
3. Schicht: Manager:
Das Problem ist jetzt, dass lokal alles wunderbar funktioniert und ich die Packete auslesen, die Klassen erzeugen und die Funktionen aufrufen kann. Auf dem Server allerdings die URL in meiner Manager - findClassNames immer leer ist (Zeile 126). Das liegt daran das der Pfad irgendwie nicht stimmt. Der Pfad ist WEB-INF/classes/de/test/XXX (das XXX steht für die jeweiligen Klassen). Ich habe schon versucht über ServletContext getResource und getRealPath zu arbeiten, jedoch ohne Erfolg. Ich sitze schon mehrere Tage an diesem einen Problem.
Hat von euch jemand eine Idee wie ich an den Pfad komme und die dynamisch Klassen auslesen kann?
Ich wäre über jede Art von Tipp dankbar.
Viele Grüße,
Thomas.
ich habe einen Tomcat 7 als Applikationsserver laufen auf dem ich mein .war-Verzeichnis deployed habe. Mein Programm hat fünf Schichten:
1. Schicht und 2. Schicht sind nur Datenbank + Zugriff, deswegen habe ich die hier weggelassen.
3. Schicht: Logik
4. Schicht: Logikzugriffsschicht für die Servlets
5. Schicht: Servlets
Ich biete verschiedene Services an, die alle XML oder KML Daten zurückliefern. Die Architektur ist so gedacht auch jeder anders später neue Services implementieren kann, dazu muss er einfach ein eigenes Servlet schreiben, das von meinem TestServlet erbt. Die Klasse TestServlet ergänzt eigentlich die Basis-Servlet Klasse nur um eine Funktion
Java:
public void getCapability()
Ich habe mir das so gedacht, dass wenn der Service AllCapabilititiesGetServlet aufgerufen wird, alle Pakete der 5. Schicht durchlaufen werden und für jedes Servlet die Funktion getCapability() aufgerufen wird. Die Funktion schreibt nämlich jedes mal einen Eintrag in ein Array und dieses Arry liefert mein AllCapabilititesGetServlet als XML-File zurück.
Durch die Struktur will ich sicher stellen, dass sobald ein neues Servlet von wem auch immer geschrieben wurde und dann die Capabilitites ausgelesen werden sollen, auch die neu angelegten Servlets berücksichtigt werden und direkt in das Array geschrieben werden.
Dazu habe ich folgende relevante Klassen:
5. Schicht: AllCapabiltiitesGetServlet:
Java:
package de.test.servlets.get;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import de.test.get.AllCapabilitiesGet;
import de.test.servlets.help.TestServlet;
/**
* Servlet implementation class AllCapabilitites
*/
public class AllCapabilititiesGetServlet extends TestServlet {
private static final long serialVersionUID = 1L;
private AllCapabilitiesGet ref;
private String answer;
/**
* @see HttpServlet#HttpServlet()
*/
public AllCapabilititiesGetServlet() {
super();
}
public void init() throws ServletException {
ref = new de.test.get.AllCapabilitiesGet();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/xml");
response.setHeader("Content-Disposition", "attachment; filename=AllCapabilities.xml");
answer = ref.getAllCapabilities();
PrintWriter out = response.getWriter();
out.println(answer);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
public void getCapability() {
//Hier steht nichts drin weil dieser Service alle Capabilities liefert
}
}
4. Schicht: AllCapabilititesGet
Java:
package de.test.get;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import de.testrest.datalogic.Manager;
@Path("/GET/AllCapabilities")
public class AllCapabilitiesGet {
@GET
@Produces(MediaType.TEXT_XML)
public String getAllCapabilities(){
String testString = Manager.getInstance().getAllCapabilities();
return testString;
}
}
3. Schicht: Manager:
Java:
package de.testrest.datalogic;
import java.io.File;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.sql.*;
import java.util.ArrayList;
import java.util.Set;
import javax.servlet.ServletContext;
import org.jdom.*;
import org.jdom.output.*;
import sun.misc.Launcher;
import de.micromata.opengis.kml.v_2_2_0.*;
/**
* Diese Klasse ist die Basislogik und stellt somit die Basisfunktionalitäten der Services zur Verfügung
*
*/
public class Manager {
...
//verwaltet alle Capabilities (Capabilitites ist eine eigene Klasse)
ArrayList<Capability> allCapabilities = new ArrayList<Capability>();
/**
* Liefert alle Capabilitites zurück (nutzt Java Reflection)
* @return String im XML-Format mit allen Capabilitites
*/
public String getAllCapabilities(){
//ArrayList für alle vorhandenen Klassen
ArrayList<String> allClasses = new ArrayList<String>();
//Hilfs-ArrayListen die jeweils alle Klassen der vier aufgezeigten Pakete enthalten
ArrayList<String> getAL = findClassNames("de.test.servlets.get");
ArrayList<String> delAL = findClassNames("de.test.servlets.delete");
ArrayList<String> putAL = findClassNames("de.test.servlets.put");
ArrayList<String> postAL = findClassNames("de.test.servlets.post");
//Jede ArrayList wird mit ihrer Länge durchlaufen und allClasses hinzugefügt
//Danach hat man nur noch die Main-ArrayList die alle vorhanden Klassennamen enthält
//Den Umweg musste man gehen, da die Pakete unterschiedliche Länge haben können
for (int i = 0; i<getAL.size();i++){
allClasses.add("de.test.servlets.get."+getAL.get(i));
}
for (int i = 0; i<delAL.size();i++){
allClasses.add("de.test.servlets.delete."+delAL.get(i));
}
for (int i = 0; i<putAL.size();i++){
allClasses.add("de.test.servlets.put."+putAL.get(i));
}
for (int i = 0; i<postAL.size();i++){
allClasses.add("de.test.servlets.post."+postAL.get(i));
}
//Für jeden Eintrag in allClasses...
for(int i = 0;i<allClasses.size();i++){
//...wird sich der Name geholt...
String className = (String) allClasses.get(i);
//..dann wird eine Class deklariert...
@SuppressWarnings("rawtypes")
Class cls;
try {
//...und diese Klasse wird initialisiert und instanziiert mit dem entsprechenden Name...
cls = Class.forName(className);
Object obj = cls.newInstance();
//...dann werden alle Methoden dieser Klasse durchlaufen...
for(java.lang.reflect.Method method : obj.getClass().getMethods()) {
//...und sobald diese Methode getCapabilitiy heißt
if(method.getName().equals("getCapability")){
//wird diese angestoßen (jedes Servlet muss diese abstrakte Funktion getCapabilitis implementieren
method.invoke(obj,null);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return generateCapabilitiesXML();
}
/**
* Hilfsfunktion für getAllCapabilitis
* Findet zu einem gegebenen Paketname die einzelnen Klassennamen
* @return ArrayList<String> alle Klassennamen des jeweiligen Pakets
*/
public static ArrayList<String> findClassNames(String pckgname) {
//ArrayList für alle Klassennamen wird erzeugt
ArrayList<String> classnames = new ArrayList<String>();
//Falls der package-Name nicht mit einem "/" beginnt wird eins davor gesetzt
String name = new String(pckgname);
if (!name.startsWith("/")) {
name = "/" + name;
}
//danach erden alle "." durch "/" ersetzt
name = name.replace('.','/');
// Es wird sich ein File-Objekt erzeugt
URL url = Launcher.class.getResource(name);
//TODO: Die Ressource ist auf dem Server leer!!! lokal nicht!
File directory = new File(url.getFile());
//Falls es ein directory gibt...
if (directory.exists()) {
//...hole den Inhalt...
String [] files = directory.list();
for (int i=0;i<files.length;i++) {
//...nimm nur die Inhalt mit .class am Ende...
if (files[i].endsWith(".class")) {
//...und ziehe die letzten sechs Zeichen ab (wegen .class)
String classname = files[i].substring(0,files[i].length()-6);
//Falls der Klassenname ungleich AllCapabilititesGetServlet ist, füge den Name der ArrayList classnames hinzu
if(!(classname.equals("AllCapabilititiesGetServlet")))
classnames.add(classname);
}
}
}
//gibt die ArrayList mit allen Klassennamen zurück
return classnames;
}
}
Das Problem ist jetzt, dass lokal alles wunderbar funktioniert und ich die Packete auslesen, die Klassen erzeugen und die Funktionen aufrufen kann. Auf dem Server allerdings die URL in meiner Manager - findClassNames immer leer ist (Zeile 126). Das liegt daran das der Pfad irgendwie nicht stimmt. Der Pfad ist WEB-INF/classes/de/test/XXX (das XXX steht für die jeweiligen Klassen). Ich habe schon versucht über ServletContext getResource und getRealPath zu arbeiten, jedoch ohne Erfolg. Ich sitze schon mehrere Tage an diesem einen Problem.
Hat von euch jemand eine Idee wie ich an den Pfad komme und die dynamisch Klassen auslesen kann?
Ich wäre über jede Art von Tipp dankbar.
Viele Grüße,
Thomas.