Freitag, 9. Dezember 2011

GWT Debugging mit Eclipse und Tomcat 7 und Benutzen einer MySQL Datenbank

Da ich eine Swing-Desktopanwendung in eine Internetanwendung umprogrammieren wollte, bin ich auf GWT gekommen.  Dort habe ich festgestellt, dass das Debuggen mit dem integrierten Jetty-Server sehr gut funktioniert und diesen Komfort wollte ich auf keinen Fall aufgeben. Um alles richtig zu machen las ich sehr viele Tutorials, wie man denn nun einen MySQL-Pool in Jetty einbinden kann.  Ich probierte alles, aber entweder unterstützte Jetty keine Contents oder als ich dann Jetty nach folgenden Tutorial http://curtstech.blogspot.com/2009/07/gwt-16-hosted-mode-internen-jetty.html konfiguriert hatte, konnte ich mein Modul nicht mehr laden, bekam immer den Fehlercode 503.
Und deshalb entschied ich mich alles über Tomcat 7 laufen zu lassen, da dieser viel leichter zu konfigurieren ist.

Am Ende des Artikels kann man das Eclipse-Projekt herunterladen, allerdings muss die Server.xml Datei für die eigene Datenbank angepasst werden .

Zuerst lädt man Tomcat 7 von Apache herunter: http://tomcat.apache.org/download-70.cgi
Dort wählt man dann je nach Betriebssystem 32-bit Windows.zip oder, wie ich, die 64 bit Version aus. Auf jeden Fall nicht den Windows Service Installer benutzen, diesen hatte ich zuerst installiert, aber dort ging das Debuggen von Eclipse aus nicht.

Als nächstes habe ich Tomcat in C:\ entpackt.

Nun richtet man den Server in Eclipse ein:
Dazu wählt man File -> New -> Other aus, oder drückt einfach Strg+N.
Dann wählt man dort Server -> Server aus:
  
Im nächsten Schritt wählt man dann Apache -> Tomcat v7.0 Server aus und klickt dann weiter unten auf den Link: Configure Runtime Environments oder wenn dieser noch nicht verfügbar ist einfach weiter auf Next >
Im nächsten Schritt wählen Sie dann über den Browse ... Button Ihr Tomcat-Verzeichnis aus, bei mir ist es zum Beispiel:

Danach klicken Sie auf Finish.
Jetzt ist ihr Tomcat7 Server eingerichtet und die Anzeige sieht wie folgt aus:
Da ich einen Datenbankpool zu unserer MySQL-Datenbank herstellen möchte, sehen meine server.xml und context.xml Dateien wie folgt aus:



 server.xml:
<?xml version="1.0" encoding="UTF-8"?>
  <Server port="8005" shutdown="SHUTDOWN">
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener"/>
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
        <Resource type="javax.sql.DataSource"
            name="jdbc/global_SFB799"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://xxxxxx/sfb799"
            username="Michael"
            password="XXX"
            initialSize="10"
            maxActive="100"
            maxIdle="50"
            minIdle="10"
            validationQuery="Select `ID` FROM `users` LIMIT 1"
            testOnBorrow="true"
            testWhileIdle="true"
            timeBetweenEvictionRunsMillis="30000"
   />
   ...
context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <ResourceLink type="javax.sql.DataSource"
                name="jdbc/SFB799"
                global="jdbc/global_SFB799"
    />
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

Jetzt darf man nur nicht vergessen den MySQL-Connector in das Tomcat 7 - Lib- Verzeichnis zu kopieren:


Damit haben wir den Tomcat 7 Server mit MySQL erfolgreich in Eclipse integriert.

Als nächstes erstellen wir ein dynamisches Web-Projekt, welches wir dann mit unserem Tomcat-Server verbinden:
Dazu wählen Sie: File -> New -> Project aus: Und dann unter Web -> Dynamic Web Project:

Geben Sie einen beliebigen Namen ein und wählen als Configuration: Default Tomcat 7 Configuration aus:
Danach klicken Sie zweimal auf Next > und setzen noch einen Haken bei Generate web.xml deployment descriptor

Nun klicken Sie auf Finish.

Jetzt klicken Sie mit der rechten Maustaste auf ihr neues Projekt -> New -> HTML File:

Diesen nennen Sie index.html.



index.html:



<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  <title>Startseite</title>
</head>
<body>
  <h3> Links: </h3>
  <p> <a href="/TestWebApp/SQLServlet">/TestWebApp/SQLServlet</a> </p>
</body>
</html>

Jetzt erstellen Sie ein Servlet, indem Sie wieder mit der rechten Maustaste auf Ihr Projekt klicken -> New -> Servlet
Java Package: servlets
Class Name: SQLServlet


SQLServlet.java:


package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

/**
 * Servlet implementation class SQLServlet
 */
@WebServlet("/SQLServlet")
public class SQLServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    @Override
       public void doGet( HttpServletRequest requ, HttpServletResponse resp )
       throws ServletException, IOException
       {
         
          resp.setStatus(200);
          resp.setContentType( "text/html" );
          PrintWriter out = resp.getWriter();
          try {   
              String jdbcname = "jdbc/SFB799";
              String cmd = "SELECT `name`, `first_name` FROM `users`";
              Context ctx = new InitialContext();
              Context envCtx = (Context)ctx.lookup("java:comp/env");
              DataSource ds = (DataSource)envCtx.lookup(jdbcname);
              Connection conn = ds.getConnection();
              Statement stmt = conn.createStatement();
              ResultSet rs = stmt.executeQuery(cmd);
              ResultSetMetaData rsmd = rs.getMetaData();
              int cols = rsmd.getColumnCount();
              out.println("<table border\"1\">");
              out.println("<tr bgcolor=\"lightGrey\">");
              for (int i = 1; i <= cols; i++) {
                  out.println("<td align=\"center\" width=\"200\"><b>" +
                          rsmd.getColumnName(i) + "</b></td>");
              }
              out.println("</tr>");
              while (rs.next()) {
                  out.println("<tr>");
                  for (int i = 1; i <= cols; i++) {
                      out.println("<td align=\"left\">" +
                              rs.getString(i) + "</td>");
                  }
                  out.println("</tr>");
              }
              out.println("</table>");
          } catch(Exception e) { e.printStackTrace(out);}
          out.close();
       }

}




Zum Testen des Servlets klicken Sie mit der rechten Maustaste auf  Ihr Projekt -> Run As -> Run on Server:

Jetzt kann es sein, dass Sie noch einen Server auswählen müssen:
Und danach auf Finish.

Jetzt startet der Tomcat 7 Server (bei mir kommt noch so eine komische Fehlermeldung, die kann man aber ruhig ignorieren). Wenn man dann auf den Link klickt, bekommt man den Inhalt seiner Datenbank angezeigt:

Damit ist das Servlet konfiguriert, quasi der Teil, der dann die Daten an unsere HTML-Seite sendet.
Als nächstes werden wir jetzt unsere GWT-Anwendung konfigurieren.

Dazu wählen Sie File -> New -> Project -> WindowBuilder -> GWT Designer -> Model -> GWT Java Project aus und klicken auf Next >

Als nächstes geben wir einen Namen ein:
Project Name: GWTView
Location: Location des Dynamic Web Project + "\WebContent\gwt\"
Wobei das "\gwt\" nur da ist, damit die Ordner sauberer aussehen, aber dieses Projekt muss unbedingt in das Verzeichnis WebContent, da man sonst keinen Zugriff auf den Server hat.  Wir könnten zwar auch den Jetty-Server von Google nehmen, dann würden wir auch unsere JavaScript-Seite angezeigt bekommen, aber würden bei response.getStatusCode() immer Null und bei response.getText() immer eine leere Zeichenkette bekommen, da wir mit unserem HTTP-Request auf einen anderen Server zugreifen; dies ist der XSS-Schutz von Google. Jetzt nochmal das Bild:

Jetzt klicken Sie noch zweimal auf Next> und setzen einen Haken bei Create GWT module und geben z.B. als Module name: MainView ein:
Jetzt können Sie auf Finish klicken.

Öffnen Sie jetzt die MainView.java Datei:





MainView.java:

package com.mycompany.project.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.InlineHTML;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class MainView implements EntryPoint {
    private Button clickMeButton;
    public void onModuleLoad() {
        RootPanel rootPanel = RootPanel.get();

        clickMeButton = new Button();
        rootPanel.add(clickMeButton);
        clickMeButton.setText("Click me!");
       
        final InlineHTML inHTML = new InlineHTML("New InlineHTML");
        rootPanel.add(inHTML, 5, 28);
        clickMeButton.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event) {
                Window.alert("Hello, GWT World!");
                String url = "http://localhost:8080/TestWebApp/SQLServlet";
                RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));

                try {
                  builder.setCallback(new RequestCallback() {
                     
                    public void onError(Request request, Throwable exception) {
                       // Couldn't connect to server (could be timeout, SOP violation, etc.)    
                    }

                    public void onResponseReceived(Request request, Response response) {
                       int type = response.getStatusCode();
                        String str = response.getText();
                          inHTML.setHTML(str);
                    }      
                  });
                  builder.send();
                } catch (RequestException e) {
                  // Couldn't connect to server       
                }
            }
        });
    }
}




Jetzt müssen Sie noch das Projekt kompalieren, dazu GWTView im Projekt Explorer auswählen und im Google-Plugin-Menü GWT Compile Project auswählen:


Jetzt wollen wir unseren Server im Debugmodus starten:
Rechtsklick auf TestWebApp -> Debug As -> Debug on Server

 Nun starten wir unsere GWT-Anwendung im Debugmodus:
Mit Rechtsklick auf GWTView -> Debug As -> Web Application (running on external server):
kann dann die GWT-Anwendung im Debugmodus gestartet werden.
Unser Link ist in diesem Fall: http://localhost:8080/TestWebApp/gwt/war/MainView.html
Drücken Sie jetzt noch auf OK.

Jetzt haben Sie den Link kopiert, und können Ihn z.B. in Firefox einfügen:
Und nun können Sie ja mal auf den Knopf drücken, dann öffnet sich das GWT Begrüßungsfenster und danach sehen, den Inhalt der MySQL-Tabelle:
Jetzt ist es möglich in Eclipse ein paar Breakpoints zu setzen, klicken Sie dazu doppelt auf den linken grauen Rand an die Quelltextstelle, wo Sie Ihr Programm begutachten möchten.
Nun klicken Sie in Ihrem Browser auf die Refresh-Taste (in den meisten Fällen F5).  Der Debugger sollte, nun wenn sie alles richtig konfiguriert haben, an den Breakpoints anhalten:
Nun kann es passieren, dass Firefox anfängt mit blinken, dies ist nur so, weil durch Ihre Unterbrechung mit dem Breakpoint, die Skriptausführzeit überschritten wird, klicken Sie einfach auf Weiter ausführen.
Nun können Sie weiter debuggen. Klicken Sie nun auch noch auf den Click Me! Button und Sie werden sehen, dass der Debugger zwischen beiden Projekten, dem GWT und dem Servlet - Projekt, hin- und herwechselt ( achten Sie dazu auf den aktuellen Tab in den folgenden Bildern )
Ich hänge Ihnen mal noch ein paar Bilder an:

Die Eclipse-Projekte sind zu finden unter: https://skydrive.live.com/redir.aspx?cid=67cf68562080921e&resid=67CF68562080921E!351&parid=root

Keine Kommentare:

Kommentar veröffentlichen