Bereitstellungsdeskriptor: web.xml

Regions-ID

REGION_ID ist ein abgekürzter Code, den Google anhand der Region zuweist, die Sie beim Erstellen Ihrer Anwendung ausgewählt haben. Der Code bezieht sich nicht auf ein Land oder eine Provinz, auch wenn einige Regions-IDs häufig verwendeten Länder- und Provinzcodes ähneln können. Das Einbinden von REGION_ID.r in App Engine-URLs ist für vorhandene Anwendungen optional und wird bald für alle neuen Anwendungen erforderlich sein.

Für einen reibungslosen Übergang wird App Engine nach und nach für die Verwendung von Regions-IDs aktualisiert. Wenn Ihr Google Cloud-Projekt noch nicht aktualisiert wurde, wird für Ihre Anwendung keine Regions-ID angezeigt. Da die ID für vorhandene Anwendungen optional ist, müssen Sie keine URLs aktualisieren oder andere Änderungen vornehmen, wenn die Regions-ID für Ihre vorhandenen Anwendungen verfügbar wird.

Hier finden Sie weitere Informationen zu Regions-IDs.

Mithilfe einer Bereitstellungsdeskriptordatei ermitteln Java-Webanwendungen unter anderem, wie URLs den Servlets zugeordnet sind und welche URLs eine Authentifizierung voraussetzen. Diese Datei heißt web.xml und befindet sich im WAR der Anwendung unter dem WEB-INF/-Verzeichnis. web.xml ist Teil des Servletstandards für Webanwendungen.

Weitere Informationen zum web.xml-Standard finden Sie im Metawerx web.xml-Referenz-Wiki und in der Servlet-Spezifikation.

Deployment-Deskriptoren

Der Bereitstellungsdeskriptor einer Webanwendung beschreibt die Klassen, Ressourcen und Konfiguration der Anwendung und gibt außerdem an, wie der Webserver diese verwendet, um Webanfragen nachzukommen. Wenn der Webserver eine Anfrage für die Anwendung erhält, ordnet er die Anfragen-URL mithilfe des Bereitstellungsdeskriptors dem Code zu, der die Anfrage zu verarbeiten hat.

Die Einrichtungsbeschreibung ist eine Datei namens web.xml. Diese befindet sich im WAR der Anwendung unter dem WEB-INF/-Verzeichnis. Die Datei ist eine XML-Datei mit dem Stammelement <web-app>.

Im Folgenden finden Sie ein einfaches web.xml-Beispiel, in dem alle URL-Pfade (/*) der Servletklasse mysite.server.ComingSoonServlet zugeordnet werden:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>comingsoon</servlet-name>
        <servlet-class>mysite.server.ComingSoonServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>comingsoon</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Servlets und URL-Pfade

web.xml definiert Zuordnungen zwischen URL-Pfaden und den Servlets, die Anfragen an diese Pfade bearbeiten. Anhand dieser Konfiguration identifiziert der Webserver das Servlet zur Verarbeitung einer bestimmten Anfrage und ruft die Klassenmethode auf, die der Anfragenmethode entspricht, Beispiel: Die doGet()-Methode für HTTP GET-Anfragen.

Für die Zuordnung einer URL zu einem Servlet deklarieren Sie das Servlet mithilfe des <servlet>-Elements und definieren dann eine Zuordnung von einem URL-Pfad zu einer Servletdeklaration unter Verwendung des <servlet-mapping>-Elements.

Das <servlet>-Element deklariert das Servlet, einschließlich eines Namens, mit dem andere Elemente in der Datei auf das Servlet verweisen, der Klasse, die für das Servlet verwendet werden soll, sowie Initialisierungsparametern. Sie können mehrere Servlets mit derselben Klasse, aber unterschiedlichen Initialisierungsparametern deklarieren. Der Name jedes Servlets darf innerhalb des Bereitstellungsdeskriptors nur einmal vorkommen.

    <servlet>
        <servlet-name>redteam</servlet-name>
        <servlet-class>mysite.server.TeamServlet</servlet-class>
        <init-param>
            <param-name>teamColor</param-name>
            <param-value>red</param-value>
        </init-param>
        <init-param>
            <param-name>bgColor</param-name>
            <param-value>#CC0000</param-value>
        </init-param>
    </servlet>

    <servlet>
        <servlet-name>blueteam</servlet-name>
        <servlet-class>mysite.server.TeamServlet</servlet-class>
        <init-param>
            <param-name>teamColor</param-name>
            <param-value>blue</param-value>
        </init-param>
        <init-param>
            <param-name>bgColor</param-name>
            <param-value>#0000CC</param-value>
        </init-param>
    </servlet>

Das <servlet-mapping>-Element gibt ein URL-Muster sowie den Namen eines deklarierten Servlets an, das für Anfragen verwendet werden soll, deren URL dem Muster entspricht. Am Anfang oder Ende des URL-Musters kann ein Sternchen (*) stehen, um null oder mehr Vorkommen eines beliebigen Zeichens anzugeben. Im Standard werden weder Platzhalter in der Mitte eines Strings noch mehrere Platzhalter innerhalb eines Musters unterstützt. Das Muster gleicht den vollständigen Pfad der URL ab und beginnt mit dem Schrägstrich (/) gefolgt vom Domainnamen. Der URL-Pfad darf nicht mit einem Punkt (.) beginnen.

    <servlet-mapping>
        <servlet-name>redteam</servlet-name>
        <url-pattern>/red/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>blueteam</servlet-name>
        <url-pattern>/blue/*</url-pattern>
    </servlet-mapping>

In diesem Beispiel eine Anfrage für die URL http://www.example.com/blue/teamProfile wird von bearbeitet TeamServlet mit dem teamColor Parameter gleich blue und die bgColor Parameter gleich #0000CC. Das Servlet kann den Teil des URL-Pfads abrufen, der vom Platzhalter mithilfe der getPathInfo()-Methode des ServletRequest-Objekts gefunden wurde.

Das Servlet kann durch Abrufen seiner Servletkonfiguration mithilfe seiner eigenen getServletConfig()-Methode und Aufrufen der getInitParameter()-Methode für das Konfigurationsobjekt unter Verwendung des Parameternamens als Argument auf seine Initialisierungsparameter zugreifen.

String teamColor = getServletConfig().getInitParameter("teamColor");

JSPs

Eine Anwendung kann JavaServer Pages (JSPs) für die Implementierung von Webseiten verwenden. JSP-Dateien sind Servlets, die mithilfe von statischem Inhalt wie HTML in Kombination mit Java-Code definiert werden.

App Engine unterstützt die automatische Kompilierung und URL-Zuordnung für JSPs. Eine JSP-Datei im WAR der Anwendung (außerhalb von WEB-INF/), deren Dateiname auf .jsp endet, wird automatisch in eine Servletklasse kompiliert und dem URL-Pfad zugeordnet, der dem Pfad zur JSP-Datei aus dem WAR-Stamm entspricht. Beispiel: Wenn die JSP-Datei einer Anwendung den Namen start.jsp trägt und sich in einem Unterverzeichnis des WARs mit dem Namen register/ befindet, wird diese von App Engine kompiliert und dem URL-Pfad /register/start.jspzugeordnet.

Wenn Sie mehr Kontrolle darüber möchten, wie die JSP einer URL zugeordnet wird, können Sie die Zuordnung explizit durch Deklaration eines <servlet>-Elements in der Deployment-Deskriptor festlegen. Geben Sie dann anstelle eines <servlet-class>-Elements ein <jsp-file>-Element mit dem Pfad zur JSP-Datei aus dem WAR-Stamm an. Das <servlet>-Element für die JSP kann Initialisierungsparameter enthalten.

    <servlet>
        <servlet-name>register</servlet-name>
        <jsp-file>/register/start.jsp</jsp-file>
    </servlet>

    <servlet-mapping>
        <servlet-name>register</servlet-name>
        <url-pattern>/register/*</url-pattern>
    </servlet-mapping>

Sie können JSP-Tag-Bibliotheken mithilfe des <taglib>-Elements installieren. Eine Tag-Bibliothek hat einen Pfad zur TLD-Datei (JSP Tag Library Descriptor) (<taglib-location>) und einen URI, mit dem JSPs die Bibliothek zum Laden auswählen (<taglib-uri>). Beachten Sie, dass App Engine die JavaServer Pages Standard Tag Library (JSTL) bereitstellt und Sie diese nicht installieren müssen.

    <taglib>
        <taglib-uri>/escape</taglib-uri>
        <taglib-location>/WEB-INF/escape-tags.tld</taglib-location>
    </taglib>

Sicherheit und Authentifizierung

Eine App Engine-Anwendung kann Google-Konten zum Zweck der Nutzerauthentifizierung verwenden. Mithilfe der Google Accounts API kann die Anwendung feststellen, ob der Nutzer angemeldet ist, die E-Mail-Adresse des aktuell angemeldeten Nutzers abrufen und Anmelde- und Abmelde-URLs generieren. Über den Bereitstellungsdeskriptor hat eine Anwendung außerdem die Möglichkeit, Zugriffsbeschränkungen für URL-Pfade auf Basis von Google Konten anzugeben.

Das <security-constraint>-Element definiert eine Sicherheitsbeschränkung für URLs, die einem bestimmten Muster entsprechen. Wenn ein Nutzer auf einen URL-Pfad mit einer Sicherheitsbeschränkung zugreift und nicht angemeldet ist, leitet App Engine diesen Nutzer auf die Anmeldeseite von Google Konten weiter. Nach erfolgreicher Anmeldung oder Registrierung eines neuen Kontos wird der Nutzer von Google Konten wieder zurück zur Anwendungs-URL geleitet. Die Anwendung muss nichts weiter tun, um zu gewährleisten, dass nur angemeldete Nutzer auf die URL zugreifen können.

Eine Sicherheitsbeschränkung enthält eine Autorisierungsbeschränkung, die festlegt, welche Nutzer von Google Konten auf den Pfad zugreifen können. Wenn die Autorisierungsbeschränkung als Nutzerrolle * festlegt, kann jeder angemeldete Nutzer mit einem Google-Konto die URL aufrufen. Wenn die Einschränkung die User-Rolle admin angibt, können nur registrierte Entwickler der Anwendung auf die URL zugreifen. Mithilfe der admin-Rolle können Sie ganz einfach Bereiche auf Ihrer Website erstellen, die nur Administratoren vorbehalten sind.

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>profile</web-resource-name>
            <url-pattern>/profile/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>admin</web-resource-name>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>

App Engine unterstützt keine benutzerdefinierten Sicherheitsrollen (<security-role>) oder alternative Authentifizierungsmechanismen (<login-config>) im Deployment-Deskriptor.

Sicherheitsbeschränkungen gelten für statische Dateien und Servlets.

Sichere URLs

Google App Engine unterstützt sichere Verbindungen über HTTPS für URLs, die die REGION_ID.r.appspot.com-Domain verwenden. Wenn eine Anfrage über HTTPS auf eine URL zugreift und diese URL in der web.xml-Datei für die Verwendung von HTTPS konfiguriert ist, werden sowohl die Anfrage- als auch die Antwortdaten vom Absender vor der Übertragung verschlüsselt und nach Erhalt vom Empfänger wieder entschlüsselt. Sichere Verbindungen verbessern den Schutz von Kundendaten wie Kontaktinformationen, Passwörtern und privaten Nachrichten.

Um zu deklarieren, dass HTTPS für eine URL verwendet werden soll, richten Sie im Deployment-Deskriptor (wie unter Sicherheit und Authentifizierung beschrieben) eine Sicherheitsbeschränkung mit einem <user-data-constraint> ein, dessen <transport-guarantee> CONFIDENTIAL. Beispiel:

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>profile</web-resource-name>
            <url-pattern>/profile/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

Anfragen, die das nicht sichere HTTP für URLs verwenden, deren Transportgarantie CONFIDENTIAL ist, werden automatisch über HTTPS zur selben URL weitergeleitet.

Jede URL kann die Transportgarantie CONFIDENTIAL verwenden, einschließlich JSPs und statische Dateien.

Der Entwicklungs-Webserver unterstützt keine HTTPS-Verbindungen. Er ignoriert die Transportgarantie, sodass Pfade, für die HTTPS vorgesehen ist, unter Verwendung regulärer HTTP-Verbindungen zum Entwicklungs-Webserver getestet werden können.

Wenn Sie die HTTPS-Handler Ihrer Anwendung mit der versionierten appspot.com-URL, wie etwa https://1.latest.your_app_id.REGION_ID.r.appspot.com/, testen, erhalten Sie von Ihrem Browser eine Warnung, dass das HTTPS-Zertifikat für diesen Domain-Pfad nicht signiert wurde. Nachdem Sie das Zertifikat für diese Domain akzeptiert haben, werden die Seiten erfolgreich geladen. Beim Aufrufen von https://your_app_id.REGION_ID.r.appspot.com/ wird diese Zertifikatswarnung nicht angezeigt.

Sie können auch eine alternative Form der versionierten appspot.com-URL verwenden, um dieses Problem zu vermeiden, indem Sie die Punkte, die die Subdomain-Komponenten trennen, durch den String "-dot-" ersetzen. Auf das vorherige Beispiel kann beispielsweise ohne Zertifikatswarnung unter https://VERSION_ID-dot-default-dot-PROJECT_ID.REGION_ID.r.appspot.com zugegriffen werden.

Google Kontenanmeldung- und -abmeldungen werden immer über eine sichere Verbindung ausgeführt und haben nichts mit der Konfiguration der URLs Ihrer Anwendung zu tun.

Wie oben bereits erwähnt, gelten Sicherheitsbeschränkungen sowohl für statische Dateien als auch Servlets. Dies umfasst auch die Transportgarantie.

Hinweis: Google empfiehlt die Verwendung des HTTPS-Protokolls, um Anfragen an Ihre App zu senden. Google stellt keine SSL-Zertifikate für Domains mit doppelten Platzhaltern aus, die unter appspot.com gehostet werden. Daher müssen Sie bei HTTPS, wie in den Beispielen unten gezeigt, zum Trennen von Subdomains den String "-dot-" anstelle von "." verwenden. Für Ihre eigenen benutzerdefinierten Domains oder für HTTP-Adressen können Sie einen einfachen Punkt (".") verwenden.

Element "welcome-file-list"

Wenn die URLs für Ihre Website Pfade zu statischen oder JSP-Dateien in Ihrem WAR-Verzeichnis darstellen, bietet es sich häufig an, auch bei Pfaden zu Verzeichnissen etwas Sinnvolles vorzusehen. Ein Nutzer, der den URL-Pfad /help/accounts/password.jsp mit Informationen zu Kontopasswörtern aufruft, versucht möglicherweise, /help/accounts/ aufzurufen, um eine Seite mit einer Einführung in die Kontosystemdokumentation zu finden. Für solche Fälle kann im Bereitstellungsdeskriptor eine Liste mit Dateinamen angegeben werden, die der Server bei einem Zugriff des Nutzers auf einen Pfad zu einem WAR-Unterverzeichnis, das nicht bereits explizit einem Servlet zugeordnet ist, verwenden soll. Im Servlet-Standard heißt diese Liste "welcome-file-list".

Wenn ein Nutzer beispielsweise auf den URL-Pfad /help/accounts/ zugreift, wird der Server durch das folgende <welcome-file-list>-Element in der Deployment-Deskriptor aufgefordert, zuerst help/accounts/index.jsp und help/accounts/index.html zu prüfen, bevor er meldet, dass die URL nicht existiert:

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

Filter

Ein Filter ist eine Klasse, die sich wie ein Servlet auf eine Anfrage auswirkt, allerdings die weitere Verarbeitung der Anfrage mit anderen Filtern oder Servlets zulassen kann. Mit einem Filter lassen sich zusätzliche Aufgaben wie Protokollierung, spezielle Authentifizierungen oder Annotationen der Anfrage- oder Antwortobjekte vor dem Aufruf des Servlets ausführen. Filter ermöglichen Ihnen, Anfragenverarbeitungsaufgaben über den Bereitstellungsdeskriptor zu erstellen.

Eine Filterklasse implementiert die javax.servlet.Filter-Schnittstelle, einschließlich der doFilter()-Methode. Im Folgenden finden Sie eine einfache Filterimplementierung, die eine Nachricht protokolliert und die Steuerung entlang der Kette untergeordneter Objekte weitergibt, wobei es sich gemäß den Vorgaben im Bereitstellungsdeskriptor um weitere Filter oder ein Servlet handeln kann:

package mysite.server;

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LogFilterImpl implements Filter {

    private FilterConfig filterConfig;
    private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws IOException, ServletException {
        log.warning("Log filter processed a " + getFilterConfig().getInitParameter("logType")
            + " request");

        filterChain.doFilter(request, response);
    }

    public FilterConfig getFilterConfig() {
        return filterConfig;
    }

    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    public void destroy() {}

}

Ähnlich wie Servlets können Sie auch einen Filter in der Deployment-Deskriptor konfigurieren. Deklarieren Sie den Filter mithilfe des <filter>-Elements und weisen Sie ihn dann mithilfe des <filter-mapping>-Elements einem URL-Muster zu. Sie können Filter auch direkt anderen Servlets zuordnen.

Das <filter>-Element enthält einen <filter-name>, eine <filter-class> sowie optionale <init-param>-Elemente.

    <filter>
        <filter-name>logSpecial</filter-name>
        <filter-class>mysite.server.LogFilterImpl</filter-class>
        <init-param>
            <param-name>logType</param-name>
            <param-value>special</param-value>
        </init-param>
    </filter>

Das <filter-mapping>-Element weist einen <filter-name> auf, der dem Namen eines deklarierten Filters entspricht, sowie entweder ein <url-pattern>-Element für die Anwendung von Filtern auf URLs oder ein <servlet-name>-Element, das dem Namen eines deklarierten Servlets entspricht und den Filter immer dann anwendet, wenn das Servlet aufgerufen wird.

    <!-- Log for all URLs ending in ".special" -->
    <filter-mapping>
        <filter-name>logSpecial</filter-name>
        <url-pattern>*.special</url-pattern>
    </filter-mapping>

    <!-- Log for all URLs that use the "comingsoon" servlet -->
    <filter-mapping>
        <filter-name>logSpecial</filter-name>
        <servlet-name>comingsoon</servlet-name>
    </filter-mapping>

Fehlerhandler

Mithilfe des Bereitstellungsdeskriptors können Sie selbst festlegen, was der Server beim Auftreten eines Fehlers an den Nutzer sendet. Der Server kann eine alternative Seitenadresse anzeigen, wenn ein bestimmter HTTP-Statuscode gesendet wird oder ein Servlet eine bestimmte Java-Ausnahme auslöst.

Das <error-page>-Element enthält entweder ein <error-code>-Element mit einem HTTP-Fehlercodewert (z. B. 500) oder ein <exception-type>-Element mit dem Klassennamen der erwarteten Ausnahme (z. B. java.io.IOException). Es enthält auch ein <location>-Element, das den URL-Pfad der Ressource enthält, die angezeigt wird, wenn der Fehler auftritt.

    <error-page>
        <error-code>500</error-code>
        <location>/errors/servererror.jsp</location>
    </error-page>

Nicht unterstützte web.xml-Funktionen

Folgende web.xml-Funktionen werden von App Engine nicht unterstützt:

  • App Engine unterstützt das <load-on-startup>-Element für Servletdeklarationen. das Laden erfolgt jedoch erst, wenn die erste Anfrage von der Webserverinstanz bearbeitet wird, nicht vorher.
  • Einige Elemente im Bereitstellungsdeskriptor können einen für Menschen lesbaren Anzeigenamen, eine Beschreibung sowie ein Symbol zur Verwendung in IDEs annehmen. App Engine verwendet diese nicht und ignoriert sie.
  • App Engine unterstützt keine JNDI-Umgebungsvariablen (<env-entry>).
  • App Engine unterstützt keine EJB-Ressourcen (<resource-ref>).
  • Benachrichtigungen über das Löschen von Servlets, Servlet-Kontexten oder Filtern werden nicht unterstützt.
  • Das <distributable>-Element wird ignoriert.
  • Eine Servletplanung mit <run-at> wird nicht unterstützt.