Planung Serversoftware mit Spring als Framework, wie Spring einsetzen?

DarthShader

Erfahrenes Mitglied
Hallo,

ich würde gerne eine Serversoftware schreiben, die auf dem Spring Framework basiert. Ich stand vor der Entscheidung, on Spring oder JBoss, und fahre nun lieber eine etwas leichtgewichtigere Lösung.

Die Serversoftware soll mit Clients kommunizieren, aber es soll eine lose Kopplung sein, also keine Aufrufe z.B. per RMI. Ich möchte eher über TCP/IP XML Daten hin- und herschicken (wie eine Art von Webservice, es soll aber erstmal kein WS sein).

Spring bietet ja die Kommunikation über Hessian, ich denke das ist für mich der richtige Weg (Hessian kann man ja auch ohne Webservice in Java nutzen, wenn ich da jetzt richtig informiert bin). Später soll die Serversoftware möglicherweise auch dazu eingesetzt werden, HTML Seiten zu generieren, also ein Webfrontend, vielleicht eine Art von Admin-Bereich für das System, wofür Spring ja das Web MVC anbietet.

Worüber ich mir jedoch nun nicht im Klaren bin ist, wie Spring auf dem Server läuft. Ich habe da zwei Vorstellungen, von denen ich nicht weiß, welche richtig ist:

a) Ich schreibe einfach meine Serversoftware, die horcht ganz klassisch per TCP Sockets auf einem Port nach Verbindungen. Das Programm nutzt Spring, z.B. als IoC Container. Kann mir Spring hier schon dieses typische Serversocket erstellen, Verb. entgegennehmen, Threads dafür erstellen etc. abnehmen?

b) Ich setze ein Tomcat auf, in dem meine Spring Applikation läuft. Muss das sein? Oder benötige ich das nur, wenn ich z.B. per Webservice auf den Server zugreifen will, also per HTTP?


Ich würde mich sehr freuen, wenn Ihr mit mir ein paar Gedanken teilt - sind meine Aussagen so nachvollziehbar, oder habe ich einen Denk- oder Planungsfehler? Wie steht es mit den beiden Fragen a) und b), was ist da richtig?


Über eine Antwort würde ich mich sehr freuen


Vielen Dank!
 
Wenn du jetzt schon weißt, dass es ein HTML Frontend geben soll würde ich den Tomcat wählen. Jetty tut es evtl. auch, wenn die Anwendung im überschaubaren Rahmen bleibt.

Es macht evtl. Sinn, die Anwendung in zwei (Eclipseprojekte) aufzuteilen. Ein normales Java / Springprojekt, dass du so programmierst, dass man es von der Kommandozeile starten kann (eine einfache Klasse mit einer main-Methode, die deine application-context.xml und damit deine Applikation lädt). Das zweite könnte ein Webprojekt sein, dass das ganze als WAR deploybar macht. Es reicht da ja in der web.xml einfach deine application-context.xml zu laden. Damit erhältst du dir die größtmögliche Variabilität.

Bzgl. des Remotings glaub ich hast du noch ein kleines Verständnisproblem:

Die Serversoftware soll mit Clients kommunizieren, aber es soll eine lose Kopplung sein, also keine Aufrufe z.B. per RMI. Ich möchte eher über TCP/IP XML Daten hin- und herschicken (wie eine Art von Webservice, es soll aber erstmal kein WS sein).
1. Der Grad der Kopplung hängt sich nicht an der Technologie auf
2. RMI ist ein Protokoll und macht, wenn du XML per RMI verschickst genau das: XML über TCP/IP über die Leitung schicken
3. Ein WebService setzt meist auf einem Higherlevel Protokoll auf (HTTP, JMS, SMTP o.ä.)
4. Hessian ist nichts anderes als RMI nur anders, sprich du bist damit nicht weniger gekoppelt, nicht mehr WebService als mit RMI usw.

Bissl durcheinander der Absatz ;). Vielleicht da nochmal ne Minute drüberdenken, sonst fällst ne Entscheidung auf ziemlich komischer Grundlage.

Gruß
Ollie
 
Hallo Oliver,

wiedermal vielen Dank für Deine Antwort :) Ich konnte in den letzten Tagen leider immer nur sehr spät antworten, sorry.


Es macht evtl. Sinn, die Anwendung in zwei (Eclipseprojekte) aufzuteilen. Ein normales Java / Springprojekt, dass du so programmierst, dass man es von der Kommandozeile starten kann (eine einfache Klasse mit einer main-Methode, die deine application-context.xml und damit deine Applikation lädt). Das zweite könnte ein Webprojekt sein, dass das ganze als WAR deploybar macht. Es reicht da ja in der web.xml einfach deine application-context.xml zu laden. Damit erhältst du dir die größtmögliche Variabilität.

Das ist eine gute Idee, werde ich mal so angehen.


Bzgl. des Remotings glaub ich hast du noch ein kleines Verständnisproblem:

1. Der Grad der Kopplung hängt sich nicht an der Technologie auf
2. RMI ist ein Protokoll und macht, wenn du XML per RMI verschickst genau das: XML über TCP/IP über die Leitung schicken
3. Ein WebService setzt meist auf einem Higherlevel Protokoll auf (HTTP, JMS, SMTP o.ä.)
4. Hessian ist nichts anderes als RMI nur anders, sprich du bist damit nicht weniger gekoppelt, nicht mehr WebService als mit RMI usw.


Hm, also das Thema ist etwas schwierig abzugrenzen. Ich empfand den Begriff der Kopplung immer als etwas schwammig. Für mich ist z.B. eine lose Kopplung, wenn es sich um ein Message-System handelt, also asynchrone Kommunikation z.B. über einen Message Broker. Wenn ich aber über RMI entfernte Methoden aufrufe, dann ist das für mich synchron, und schon sehr gekoppelt, erstmal aufgrund der Synchronität, und auf der anderen Seite muss ich meine Schnittstelle, also die Methodennamen selbst, preisgeben.

Lange Rede, kurzer Sinn: Ich weiß momentan immer noch nicht, was ich mache. Welche Technologie bzw. Protokoll ich einsetzen soll. In wie fern unterstützt mich Spring denn bei der Geschichte, muss ich um XML DAten zu versenden immernoch selbst nen ServerSocket aufmachen oder über einen Socket in den Datenstrom schreiben, oder kapselt Spring das für mich?


Nochmals vielen Dank für Deine weitere Hilfe
 
Hm, also das Thema ist etwas schwierig abzugrenzen. Ich empfand den Begriff der Kopplung immer als etwas schwammig. Für mich ist z.B. eine lose Kopplung, wenn es sich um ein Message-System handelt, also asynchrone Kommunikation z.B. über einen Message Broker. Wenn ich aber über RMI entfernte Methoden aufrufe, dann ist das für mich synchron, und schon sehr gekoppelt, erstmal aufgrund der Synchronität, und auf der anderen Seite muss ich meine Schnittstelle, also die Methodennamen selbst, preisgeben.
Okay, aber da unterscheide sich Hessian nicht von RMI und das wiederum nicht von WebServices. Alles synchrone Calls.

Lange Rede, kurzer Sinn: Ich weiß momentan immer noch nicht, was ich mache. Welche Technologie bzw. Protokoll ich einsetzen soll. In wie fern unterstützt mich Spring denn bei der Geschichte, muss ich um XML DAten zu versenden immernoch selbst nen ServerSocket aufmachen oder über einen Socket in den Datenstrom schreiben, oder kapselt Spring das für mich?

Indirekt. Die Entscheidung ob Asynchronität notwendig ist, musst du selbst treffen. Wenn nicht, kannst du eine beliebige Remotekommunikation einfach per Konfiguration erzielen indem du die entsprechenden Exporter bzw. ProxyFactoryBeans benutzt. Der Wechsel von Hessian zu RMI zu Burlap ist dabei eine Sache der Konfiguration.

Für asynchrone Calls per JMS gibt es auch jede Menge Support: das JmsTemplate (analog zu anderen Templateklassen von Spring) bzw. die EndpointFactories auf Serverseite. Allerdings benötigst du dann auf jeden Fall eine MessageQueue (ActiveMQ z.B.) als Middleware, was die Komplexität natürlich nicht verringert ;). Allerdings ermöglicht es Spring wieder die gewählte Technologie komplett vor dem geschäftscode zu verstecken.

Gruß
Ollie
 
Hallo Oliver,

vielen Dank für Deine Antwort.

Ich habe mir nun die komplette Spring Referenz zum Thema Remoting durchgelesen, Kapitel 17 "Remoting and web services using Spring". Es ist ja bemerkenswert, wie einfach es Spring macht, seine Services per RMI zu "veröffentlichen".

Nun bin ich jemand, der aus seiner "kleinen Nicht-JEE Welt" kommt, und sich bisher die Kommunikation so vorgestellt hat:


Beispiel Anwendungsfall: Client will Dokument in Form von XML Daten an den Server senden, Server soll XML entgegen nehmen und (via JPA) in DB schreiben.

Code:
CLIENT                          SERVER
___________________________________________________________

(1) TCP/IP Verbindungsaufbau  ___
                                 \
(2)                               \_ Verb. akzeptieren
                                  /
(3) Sendet Authentifizierungs-  _/
    daten, Benutzername und PW   \
(4)                               \_ Überprüft Daten, sendet
                                  /  "authed" zurück.
(5) Sendet XML Dokument  ________/
                                 \
                                  \_ Nimm Dokument entgegen,
(6)                               /  speichert es in der DB,
                                 /   sendet "success".
(7) Baut verbindung ab  ________/

Das ist so meine klassische Vorstellung. Nun komme ich in die Spring Welt, und möchte eben Spring dafür nutzen. Wie bilde ich nun das obige diagramm auf diese neuen JEE Konzepte mit Spring ab?

Ich nehme mal an, dass (5) und (6) als RMI quasi der Aufruf an meine Service Methode ist, sowas wie "saveDocument", und als Parameter übergibt der Client einfach die XML Daten. Speziell interessiert mich aber (3) und (4), wie kann man das machen? Denn wenn ich über RMI eine entfernte Methode aufrufe, dann wird doch eine TCP/IP Verbindung aufgebaut, die Methode aufgerufen, und die Verbindung wieder abgebaut. Ich kann die Authentifizierungsinformationen also nicht als "Sessiondaten" für die Dauer der Verbindung nehmen, denn mit RMI würde hier nach Punkt (4) die Verbindung wieder abgebaut. Ist meine Vorstellung so korrekt? Wie würde ich dann aber die Authentifizierung machen, müsste ich vielleicht bei jedem Aufruf Benutzername+PW mitschicken?


Ich würde mich über weitere Hilfe sehr freuen


Vielen dank!
 
Zuletzt bearbeitet:
Diese expliziten Schritte brauchst du gar nicht selbst implementieren. Konzentrier dich auf die fachlichkeit (immer eine gute Idee) ;).

Das Interface deines Servers braucht eine Methode saveDocument(String xmlContent). Dann konfigurierst du mit Spring Security deinen Client und fügst deiner RmiProxyFactoryBean die ContextPropagatingRemoteInvocationFactory (aus SpringSecurity context.rmi Package) hinzu. Die sorgt dafür, dass der SecurityContext mit dem RMI call an den Server propagiert wird. Auf der Serverseite reicht dann MethodBasedSecurity (auch wieder SpringSecurity) und es fliegt eine Exception, wenn der User auf der Serverseite nicht die nötigen Rechte besitzt oder erst gar nicht authentifiziert ist.

Gruß
Ollie
 
Hallo Oliver,

Deine Antworten auf meine Fragen lösen bei mir immer eine Flut von Lese-Stunden und Buchkäufen aus :) Deine Stichworte sind wirklich klasse, ich kann mit diesen selbst stets weiterlernen und mir die Informationen aus verschiedenen Quellen ziehen.

Was nur manchmal schwierig ist, das "big picture" von gewissen Prozessen zu bekommen. Das stellt sich wiederum sicher mit der Erfahrung ein, die man im Laufe der Zeit mit der Technologie macht.

Ich denke ich habe nun das Konzept von Spring Security verstanden, wie es via Interceptoren bzw. Spring AOP die Fachlichen Klassen mit Sicherheitsmerkmalen ausstatten kann, ohne dass sich der fachliche Code mit infrastrukturellem Code vermischen muss. Ich konfiguriere mir also die Sicherheit, und suche mir einen entspr. SecurityProvider, der mir z.B. Benutzernamen und PW aus einer Datenbank rauszieht.


Vielleicht darf ich dennoch einmal folgendes nachfragen:

1) Spring Security ist/war doch Acegi, richtig? Wenn ich mich jetzt in Acegi 1.0 einarbeite, aber Spring Security 2.0 fertig ist, habe ich dann "Altlasten" erlernt? :) Oder sind die Veränderungen nicht so gravierend?

2) Wenn ich über RMI meine XML Daten versende, sagen wir über eine sehr schmale Bandbreite wie bei GPRS, und das Senden dauert seine Zeit - wie kann ich dann den Fortschritt mitbekommen? Für mich ist das jetzt nur ein Methodenaufruf (z.B. saveDocument(String xmlData)). Im klassischen Socket-Sinn bekomme ich ja die in den Stream gesendeten Datenmengen mit. Wie schaut es bei der Spring / RMI Sache aus, habe ich dort einen Einfluss auf das Senden/Empfangen?


Ich bitte um Nachsicht und weitere Geduld mit mir :)


Vielen Dank!
 
1) Spring Security ist/war doch Acegi, richtig? Wenn ich mich jetzt in Acegi 1.0 einarbeite, aber Spring Security 2.0 fertig ist, habe ich dann "Altlasten" erlernt? :) Oder sind die Veränderungen nicht so gravierend?
Aktuelle Spring Security Version ist 2.0.3. Siehe http://www.springframework.org/download/

2) Wenn ich über RMI meine XML Daten versende, sagen wir über eine sehr schmale Bandbreite wie bei GPRS, und das Senden dauert seine Zeit - wie kann ich dann den Fortschritt mitbekommen? Für mich ist das jetzt nur ein Methodenaufruf (z.B. saveDocument(String xmlData)). Im klassischen Socket-Sinn bekomme ich ja die in den Stream gesendeten Datenmengen mit. Wie schaut es bei der Spring / RMI Sache aus, habe ich dort einen Einfluss auf das Senden/Empfangen?

Für einen Handyclient würde ich eher auf HTTP als Übertragungsprotokoll setzen. Das ist auf den Endgeräten einfacher zu implementieren und lässt sich überdessen wesentlich besser monitoren.

Gruß
Ollie
 
Hallo Oliver,

Für einen Handyclient würde ich eher auf HTTP als Übertragungsprotokoll setzen. Das ist auf den Endgeräten einfacher zu implementieren und lässt sich überdessen wesentlich besser monitoren.

Meine Applikation läuft nicht auf einem Handy, sondern auf einem Industrienotebook mit einem ordinären Windows XP.

Ist es denn überhaupt möglich, das Senden/Empfangen bei RMI mit Spring zu überwachen?
 
Zurück