Zusammenfassung Im ersten Teil dieser Übersicht (das JavaEE6-Backend) habe ich eine kleine Anwendung getestet, bei der es sich um einen JSON-REST-Dienst handelt, der als Backend für ein JavaFX-Frontend verwendet werden soll. Meine vorläufige Schlussfolgerung ist, dass JavaEE6 eine Menge neuer Funktionen bietet, die die Verwendung von Java EE ohne zusätzliche Bibliotheken wie Spring, Seam oder Resteasy erheblich erleichtern. Ich war in der Lage, eine Backend-Anwendung zu erstellen, die bei geringem Overhead in Bezug auf Bandbreite und CPU-Auslastung bemerkenswert schnell war. Einleitung Auf der Suche nach der derzeit besten Technologieplattform baue ich eine kleine reale Anwendung für den persönlichen Gebrauch in verschiedenen Sprachen und Frameworks. Den Anfang machen Java EE 6 und JavaFX 1.3. Ich denke, diese Übersicht kann auch für andere hilfreich sein. Wenn Sie nur die Implementierung sehen wollen, können Sie die funktionalen und technischen Anforderungen überspringen. Wenn Sie an der Anwendung interessiert sind und bei der Erstellung der neuen Version helfen möchten, schicken Sie mir bitte eine Antwort:-).
Funktionale Anforderungen Ich verwende derzeit eine Anwendung zur Verwaltung meiner persönlichen Finanzen. Diese Anwendung wurde in Java Swing mit einer darunter liegenden Hsql-Datenbank erstellt. Die Anwendung funktioniert gut, ist aber nur für eine Person gleichzeitig nutzbar und die Hsql-Datenbank ist nicht ideal. Ich habe diese Anwendung erstellt, weil ich keine andere Anwendung zur Verwaltung meiner persönlichen Finanzen finden konnte, die die folgenden Funktionen (und mehr) bietet:
- Registrieren Sie kommende Transaktionen auf Budgets
- Einmalige Transaktionen
- Wiederholte Transaktionen (derzeit mit einer Cron-Syntax)
- In der Lage sein, über selbst definierte Zeiträume zu berichten
- Der Zeitraum kann durch ein Startdatum und die Unix cron-Syntax definiert werden
- Die Periodenberichte zeigen
- Das Budget für diesen Zeitraum (basierend auf allen kommenden Transaktionen) für jeden Budgeteintrag
- Der Gesamtbetrag der Ausgaben für diesen Zeitraum
- Der für diesen Zeitraum auszugebende Betrag
- Der Unterschied zwischen dem Budget und der Realität
- Der Mehrperiodenbericht zeigt
- Für den definierten Zeitraum werden die Summen in den Periodenberichten angezeigt
- Mit diesem Bericht können Sie sich über Ihre finanzielle Situation in den kommenden Monaten informieren.
- In der Lage sein, Transaktionen zu registrieren
- Transaktionen importieren können (derzeit nur von einer Bank)
Um mehr Benutzern die Möglichkeit zu geben, diese Anwendung zu nutzen, überlege ich, sie neu zu erstellen.
![]() ![]() |
Technologieanforderungen Ich habe einige spezifische Anforderungen an die Technologien, die ich für diese neue Version verwenden werde:
- Verfügen Sie über eine Baumdatentabelle (in Flex wird sie als erweiterte Datentabelle bezeichnet) zur Visualisierung einer hierarchischen Datenstruktur.
- Geringe Ressourcenauslastung auf der Serverseite, um die Kosten für den Betrieb des Servers zu senken
- Auch auf Mobiltelefonen lauffähig sein (vielleicht eine Basisversion)
- Verwenden Sie ein extrem skalierbares Backend, um eine große Anzahl von Benutzern zu bedienen.
- Sie müssen in der Lage sein, Anzeigen im Frontend zu schalten, um die Kosten für das Hosting zu decken.
Java EE6 und JavaFX Da JEE6 kommt und die ersten Beta-Versionen von Glassfish und Netbeans verfügbar sind, dachte ich mir, dass ich versuche, nur Java EE6-Technologien zu verwenden und einen grundlegenden Testaufbau einschließlich Client-Server-Kommunikation und grundlegender Sicherheit zu erstellen. Dies wird mir auch die Möglichkeit geben, einen kleinen Überblick über die neue Java EE Edition zu geben. In der Vergangenheit habe ich viele verschiedene Technologien verwendet, um eine Art von Dependency Injection (DI) nutzen zu können:
- Selbst erstellter DI-Rahmen (2003)
- Spring Framework(2006)
- Seam Framework (2007)
JEE6 ist die erste Java EE-Edition, die ein DI-Framework bereitstellt, das anscheinend keine zusätzlichen Frameworks benötigt. Ich werde also das Injection-Framework von JEE6 für Dependency Injection verwenden. Für den Client wähle ich JavaFX. Derzeit befindet sich JavaFX 1.3 in der Betaphase, aber auf den ersten Blick scheint es meinen Anforderungen zu entsprechen. Für die Kommunikation zwischen JavaFX und JavaEE verwende ich JSON mit JAX-RS (neu in EE6). Auf diese Weise hoffe ich, eine geringe Bandbreite und einen geringen CPU-Overhead zu erhalten. Ich habe JSON schon früher verwendet, aber damals war das Protokoll brandneu. Jetzt ist es in JavaEE integriert. Die Backend-Anwendung Zur Erstellung der Backend-Anwendung habe ich ein Netbeans 6.9 Beta-Webprojekt gestartet. Ich gab dem Projekt lediglich einen Namen, wählte den internen Glassfish 3.0.1b14 Server und das JEE6 Profil. Zuerst habe ich ein User-Objekt erstellt, mit dem ich Daten vom Server zum Client übertragen kann. [java] @XmlRootElement public class User { private String username; private String password; public User(){} // public User(String username, String password){ this.username = username; this.password = password; } ...Getter und Setter für den Benutzernamen und das Passwort } [/java] Das Einzige, was ich tun musste, um dieses Objekt in der JSON-Kommunikation zu verwenden, ist das Hinzufügen der @XmlRootElement-Annotation. Das ist ganz einfach und spart eine Menge Arbeit. Als nächstes habe ich einen Dienst zum Abrufen von Kontoinformationen erstellt [java] @SessionScoped public class UserService implements Serializable{ public UserService() {} private User user; public boolean login(String username,String password) { this.user = new User(username,password); return true; } public boolean isLoggedIn(){ return(this.user != null); } public User getUser(){ return user; } } [/java] Hier musste ich der Bean nur einen Bereich geben. Da diese Bean für die Anmeldung und die Speicherung der Kontoinformationen verwendet wird, mache ich sie zu einer Session scoped Bean. Wie Sie sehen können, habe ich sie nicht mit einem echten Backend verbunden, da ich das Backend später auswählen werde. Ich habe jetzt einen Anmeldedienst, den ich mit einem Sicherheitsmechanismus verbinden muss. Da ich keine externen Frameworks verwenden möchte, habe ich die Basic-Authentifizierung verwendet. Das funktioniert gut, weil es sich gut in JavaFX integrieren lässt. Für mehr Sicherheit kann ich Transport Layer Security (https) verwenden. Für die Authentifizierung habe ich einen Servlet-Filter erstellt [java] @WebFilter("/services/private/") public class SecurityFilter implements Filter { @Inject UserService userService; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; if (userService.isLoggedIn()) { chain.doFilter(Anfrage, Antwort); zurück; } sonst { String username = null; String password = null; // Holen Sie den Autorisierungs-Header, falls einer angegeben wurde. String authHeader = req.getHeader("Authorization"); if (authHeader != null) { java.util.StringTokenizer st = new java.util.StringTokenizer(authHeader); if (st.hasMoreTokens()) { String basic = st.nextToken(); if (basic.equalsIgnoreCase("Basic")) { String credentials = st.nextToken(); sun.misc.BASE 64 Decoder decoder = new sun.misc.BASE 64 Decoder(); String userPass = new String(decoder.decodeBuffer(credentials)); int p = userPass.indexOf(":"); wenn (p != -1) { username = userPass.sub string(0, p); password = userPass.sub string(p + 1); } } } } if (username != null && password != null && !"".equals(username) && !"".equals(password)) { if (userService.login(benutzername, passwort)) { chain.doFilter(Anfrage, Antwort); zurück; } } } HttpServletResponse res = (HttpServletResponse) response; String s = "Basic realm="Login Rest Services - PersonalFinance""; res.setHeader("WWW-Authenticate", s); res.setStatus(401); } } [/java] Wie Sie sehen, ist der Großteil des Codes recht einfach und wird nur für die Dekodierung des grundlegenden Authentifizierungsbereichs benötigt. Der interessante JavaEE6-Teil ist die @WebFilter("/services/private/") Annotation. Mit dieser Annotation können Sie festlegen, wo der Filter verwendet werden soll. Es ist nicht mehr erforderlich, den Filter in einer web.xml-Datei zu definieren. Die andere interessante Annotation ist die @Inject UserService userService; mit dieser Annotation wird der UserService-Dienst injiziert. Da der UserService eine @SessionScoped-Annotation hat, wird dieser Dienst immer eine Instanz für jede Sitzung sein. Der einzige Teil des Back-Ends, der übrig bleibt, ist der Rest Service selbst. Dieser Dienst gibt die aktuelle Benutzer-Bohne über JSON über REST zurück. [java] @Path("privat/account/") @RequestScoped public class Accounts implements Serializable{ @Inject UserService userService; @GET @Path("show") @Produces("application/json") public User show(){ return userService.getUser(); [/java] } } Wie wir sehen, ist die Implementierung von JSON über REST einfach. Die Implementierung von REST erfolgt über die Anmerkungen @Path("private/account/") ,@GET und @Path("show"). Dies erzeugt eine Url /private/account/show für die Funktion show. Diese akzeptiert die HTTP GET-Methode. Um die JSON-Ausgabe zu liefern, musste ich nur die @Produces("application/json") Annotation hinzufügen und sicherstellen, dass das User-Objekt mit der @XmlRootElement Annotation annotiert ist. Um dieses einfache Back-End zu testen, habe ich die Anwendung auf dem Glassfish-Server installiert, indem ich mit der rechten Maustaste auf das Projekt geklickt und deploy gewählt habe. Nach der Installation können wir das Back-End direkt testen: Wie Sie sehen können, müssen wir uns anmelden. Nach der Eingabe eines Benutzernamens und eines Passworts sehen wir die JSON-Ausgabe. Die Anforderung, ein Minimum an Bandbreiten-Overhead zu haben, wird erfüllt. Die JSON-Ausgabe ist sehr klein. Um die Leistung zu testen, habe ich einen einfachen Jmeter-Test erstellt, der lediglich einen korrekten REALM an login sendet und die JSON-Ausgabe anzeigt. Die Ergebnisse waren recht gut.
![]() ![]() |
Ich erhielt 307 Anfragen pro Sekunde mit 90% der Anfragen innerhalb von 37 Millisekunden, ohne irgendetwas zu tunen und mit 10 gleichzeitigen Threads in Jmeter. Die CPU-Auslastung lag zu diesem Zeitpunkt bei 40% (Core i7 QC820). Das beweist für mich, dass der Overhead gering ist. In diesem Fall habe ich ein schlimmeres Szenario simuliert, bei dem jede Anfrage eine neue Sitzung ist, da ich keinen Cookie-Manager in Jmeter verwendet habe.
Schlussfolgerungen Die Verwendung von JavaEE6 für das Backend ist eine gute Wahl. Es ist möglich, sehr schnell zu entwickeln (ich habe die gesamte Demo ohne jegliche Kenntnisse der neuen Funktionen von JEE6 in weniger als 2 Stunden erstellt). Und es erfüllt die technischen Anforderungen in Bezug auf den Overhead. Im nächsten Teil werde ich über das Front-End in JavaFX 1.3 bloggen.
Verfasst von
Mark Bakker
Unsere Ideen
Weitere Blogs
Contact







