2009-08-31 2 views
23

Ich würde gerne wissen, wie kann ich von einer EJB 3 Bean auf das Dateisystem zugreifen?Wie kann ich von einem EJB 3 auf das Dateisystem zugreifen?

Ich suchte im Internet nach dem Thema und habe keine gute Antwort gefunden.

Einige schlagen vor, java.io/java.nio zu verwenden, obwohl die Spezifikation diese Verwendung verbietet. Die meisten Anwendungsserver scheinen den Zugriff auf diese API trotzdem zuzulassen.

Eine andere Idee wäre die Verwendung eines JCA-Connectors für den Zugriff auf das Dateisystem oder ein LDAP-Verzeichnis.

Was ich tun möchte, um die Verwendung von BLOB in der Datenbank zu vermeiden, wenn eine einfache Datei eine viel bessere Lösung in Bezug auf Leistung und verwendete Ressourcen wäre.

Wie würden Sie dieses Problem lösen?

+1

Sie müssen kein BLOB in der Datenbank haben. SQL Server 2008 unterstützt Filestream-Speicher, der die Datei im Wesentlichen in einen Ordner auf dem DB-Server ablegt, ihn jedoch über die Datenbank verfügbar macht. http://blogs.msdn.com/rdoherty/archive/2007/10/12/getting-traction-with-sql-server-2008-filestream.aspx – pjp

Antwort

9

Der Grund, dass Sie von Dateisystemzugriff in EJBs nicht zulässig ist, dass Sie keine Kontrolle darüber, wie Ihre Anwendung läuft innerhalb eines (Java EE) Container. Zum Beispiel kann Ihre Anwendung über einen Cluster von Servern laufen, in welchem ​​Fall das Speichern eines Objekts in ein Verzeichnis auf einem Server wahrscheinlich wenig nützlich ist. (Sie können natürlich ein Netzwerk-Dateisystem haben, so dass die Einschränkung möglicherweise nicht gilt).

Eine Option kann Nutzen sein die JNDI Implementierung, die mit Ihrem Container kommt. Sie werden in der Lage, wahrscheinlich ein rohes byte[] Array an einem gewissen JNDI Ort zu speichern, so kann man immer die serialisierte Form des Objekts speichert unten:

ByteArrayOutputStream baos= new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(baos); 
oos.writeObject(myObj); 

//Now save into JNDI 
new InitialContext().bind("path/to/myobject", baos.toByteArray()); 

Diese später nachgeschlagen werden kann und in das Objekt erneut konvertiert:

byte[] bs = (byte[]) new InitialContext().lookup("path/to/myobject"); 
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bs)); 
MyObj myObj = (MyObj) ois.readObject(); 

Alternativ könnten Sie den java.beanspersistenten XML verwenden (dh XMLDecoder, XMLEncoder) Ihre Instanz als XML-String zu kodieren ein, dass in JNDI speichern.

+0

Ist dies die empfohlene Methode zum Schreiben von Dateien aus einem EJB? Wird die Datei für jeden Knoten in einem Cluster verfügbar sein (ich denke, JNDI ist tatsächlich so geclustert, wahrscheinlich ja)? Das letzte Lesen (oder Schreiben von) JNDI ist transaktional? –

+0

"Sie sind nicht erlaubt" - Sie sind nicht länger nicht berechtigt, auf das Dateisystem zuzugreifen, und es war NIEMALS beabsichtigt, dass dies nur für die EJB-Spezifikation galt. Wer das zu der Zeit schrieb, täuschte, dass EJB die Grundlage aller Java EE wäre und daher ziemlich genau mit Java EE vergleichbar wäre. –

7

Wenn Sie wissen, dass Sie Ihre Anwendung niemals gruppieren werden (oder dass Sie das Laufwerk mit dem Netzwerk verbinden können), verwenden Sie einfach java.io. *.

Stellen Sie sicher, dass die richtige Konfiguration bezüglich des Stammverzeichnisses Ihres Dateispeichers vorgenommen wird.

+0

+1 Diese Antwort ist nur * gesunder Menschenverstand *. Wenn die Datei von einem anderen Programm (das EJB nicht entspricht) gefüllt wird, gibt es keine schnellere und * klare * Möglichkeit, dies zu tun. – ATorras

+2

Wenn Sie eine Anwendung schreiben, die nicht der Java EE-Spezifikation entspricht, können Sie nicht sicher sein, dass sie tragbar und wartbar ist. Zum Beispiel haben Sie dieses Projekt in 12 Monaten mit einer großen Überraschung für die arme Person hinter sich gelassen, die die Aufgabe hatte, Ihre App zu gruppieren. Oder es in einen anderen Container portieren. –

+7

* "Wenn Sie wissen, dass Sie Ihre Bewerbung niemals bündeln werden" * - wenn Sie feststellen, dass Sie in die Zukunft blicken können, denken Sie vielleicht, dass es eine lukrativere Karriere in der Glücksspielbranche gibt. –

5

Kapsulieren Sie Ihren Zugriff auf Dateidaten. Dann könnten Sie eine der oben beschriebenen Methoden verwenden. Benutze sogar eine Datenbank. Messen Sie die Leistung Ihres Systems. Wenn es die Anforderungen erfüllt, sind Sie fertig. Wenn nicht, ist Ihr Dateizugriff an einer Stelle lokalisiert und Sie können eine andere Lösung einsetzen. Gleicher Vorteil, wenn die Software in einen anderen Container portiert werden muss und/oder von jemand anderem gewartet werden muss.

+0

+1 für die Kapselung – flybywire

1

Der einfache Dateizugriff ist nicht transaktionsbezogen. Wenn Sie keine Unterstützung für Transaktionsoperationen erstellen (ich weiß nicht, wie - das ist die Aufgabe eines Ressourcenmanagers), müssen Sie sich Gedanken über die transaktionale Semantik der Operation machen, die Sie ausführen. Wenn Sie die Transaktionsunterstützung einbinden, haben Sie nur sehr wenig an Leistung gewonnen (ein Teil des Leistungsverlustes in Datenbanken ist auf die gesamte Buchhaltung zurückzuführen, die vom Ressourcenmanager durchgeführt wird). Und vergessen Sie nicht die enge Verwandtschaft des Transaktionsmanagements - Nebenläufigkeit.Sofern Sie nicht für jede Anfrage in eine neue Datei schreiben, werden Nebenläufigkeitsprobleme Sie mehr oder weniger beißen.

Sie finden viele weitere Informationen in der Sun Blueprint's FAQ on EJB restrictions.

Sofern Sie nicht mit einer guten technischen Begründung im Klartext sind, sollten Sie nicht versuchen, von EJBs auf das Dateisystem zuzugreifen. Ein sehr gutes Beispiel wäre ein Framework für die Protokollierung (nicht für die Überwachung) - der Zugriff auf das Dateisystem zum Schreiben von Protokolldateien ist relativ wenig schädigend, da die Protokollierung keine Transaktionsoperation sein muss, dh Sie müssen keine Schreiboperationen auf a ausführen Logdatei; nicht, dass es akzeptabel ist, partielle Schreibvorgänge zu haben.

+0

Das lokale Cachen von Dateien über einen Singleton/Timer ist ein weiteres Beispiel für eine Operation, die praktisch immer sicher ist. –

+1

"Es sei denn, [...] sollten Sie nicht versuchen, von EJBs aus auf das Dateisystem zuzugreifen" - es gibt keinen bestimmten Grund, warum dies nur für EJBs gelten sollte. Man sollte vorsichtig sein, wenn man IO von * jeder Art von Bohnen * macht, nicht nur Bohnen, die zufällig EJB-Bohnen sind. –

Verwandte Themen