Il descrittore di deployment: web.xml

ID regione

REGION_ID è un codice abbreviato assegnato da Google in base alla regione selezionata quando crei l'app. Il codice non corrisponde a un paese o a una provincia, anche se alcuni ID regione possono sembrare simili ai codici di paesi e province di uso comune. Per le app create dopo febbraio 2020, REGION_ID.r è incluso negli URL di App Engine. Per le app esistenti create prima di questa data, l'ID regione è facoltativo nell'URL.

Scopri di più sugli ID regione.

Le applicazioni web Java utilizzano un file descrittore di deployment per determinare la modalità di mappatura degli URL ai servlet, gli URL che richiedono l'autenticazione e altre informazioni. Questo file è denominato web.xml e fa parte della specifica del servlet per le applicazioni web. Per ulteriori informazioni sul descrittore di deployment web.xml, consulta specifiche di servlet.

Se stai eseguendo la migrazione da Java 8 e devi utilizzare il ai servizi in bundle legacy con l'ultima versione di Java supportata, devi aggiungere il <app-engine-apis> e impostalo su true nel file web.xml:

<app-engine-apis>true</app-engine-apis>

Descrittori di deployment

Il descrittore di deployment di un'applicazione web descrive le classi, le risorse dell'applicazione e il modo in cui il server web le utilizza per la pubblicazione richieste. Quando il server web riceve una richiesta per l'applicazione, utilizza il descrittore di deployment per mappare l'URL della richiesta al codice che deve per gestire la richiesta.

Il descrittore di deployment è un file denominato web.xml. Si trova nella cartella WAR dell'app nella directory WEB-INF/. Il file è un file XML il cui elemento principale è <web-app>.

Il seguente esempio web.xml mappa tutti i percorsi dell'URL (/*) alla classe servlet mysite.server.ComingSoonServlet per la versione 21 e successive su EE10 (predefinita), la versione 21 su EE8 e la versione 17 e precedenti. Per utilizzare l'ultima versione supportata su devi aggiornare i servlet delle applicazioni per includere lo spazio dei nomi Jakarta. Per scoprire di più sulle opzioni di configurazione, consulta Eseguire l'upgrade di un'applicazione esistente.

v21 e successive (EE10)

<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
     version="6.0">
    <runtime>java21</runtime> <!-- or another supported version -->
    <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>

v21 (EE8)

<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">
   <runtime>java21</runtime>

  <system-properties> <!-- run your apps on EE8  -->
      <property name="appengine.use.EE8" value="true"/>
  </system-properties>

    <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>

v17 e versioni precedenti

  <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">
      <runtime>java17</runtime>
      <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>

Se scomponi la tua applicazione nei servizi, ogni servizio ha il proprio parametri di configurazione.

Servlet e percorsi URL

web.xml definisce le mappature tra i percorsi dell'URL e i servlet che gestiscono richieste con quei percorsi. Il server web utilizza questa configurazione per identificare il servlet da utilizzare per gestire una determinata richiesta e chiamare il metodo di classe corrispondente al metodo della richiesta. Ad esempio: il metodo doGet() per HTTP GET richieste.

Per mappare un URL a un servlet, devi dichiarare il servlet con l'elemento <servlet>, quindi definisci una mappatura da un percorso URL a una dichiarazione servlet con Elemento <servlet-mapping>.

L'elemento <servlet> dichiara il servlet, incluso un nome utilizzato per fare riferimento al servlet da altri elementi del file, la classe da utilizzare per il servlet e i parametri di inizializzazione. Puoi dichiarare più servlet utilizzando la stessa classe con parametri di inizializzazione diversi. Il nome di ogni servlet deve essere univoco nel descrittore di deployment.

    <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>

L'elemento <servlet-mapping> specifica un pattern URL e il nome di un servlet dichiarato da utilizzare per le richieste il cui URL corrisponde al pattern. URL utilizzare un asterisco (*) all'inizio o alla fine del pattern per indicare zero o più caratteri. Il pattern URL non supporta i caratteri jolly nel mezzo di una stringa e non consente più caratteri jolly in un pattern. Il pattern corrisponde al percorso completo dell'URL, iniziando con la barra (/) che segue il nome di dominio e includendola. Il percorso dell'URL non può iniziano con un punto (.).

    <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 questo esempio, una richiesta per l'URL http://www.example.com/blue/teamProfile viene gestita dalla classe TeamServlet, con il parametro teamColor uguale a blue e il parametro bgColor uguale a #0000CC. Il servlet può ottenere la parte del percorso dell'URL corrispondente al carattere jolly utilizzando il metodo getPathInfo() dell'oggetto ServletRequest.

Il servlet può accedere ai parametri di inizializzazione ottenendo il suo servlet utilizzando il proprio metodo getServletConfig(), quindi chiamando il metodo getInitParameter() nell'oggetto di configurazione utilizzando il nome del come argomento.

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

JSP

Un'app può utilizzare JSP (JavaServer Pages) per implementare le pagine web. Le JSP sono servlet definiti utilizzando contenuti statici, come HTML, combinati con codice Java.

App Engine supporta la compilazione automatica e la mappatura degli URL per JSP. Un file JSP nella WAR dell'applicazione (all'esterno di WEB-INF/) il cui nome file termina con .jsp viene compilata automaticamente in una classe servlet e mappata al percorso dell'URL equivalente al percorso del file JSP dalla radice WAR. Ad esempio, se un'app ha un file JSP denominato start.jsp in una sottodirectory denominata register/ nella relativa WAR, App Engine lo compila e lo mappa al percorso dell'URL /register/start.jsp.

Se desideri maggiore controllo su come il JSP viene mappato a un URL, puoi specificare il mapping in modo esplicito dichiarandolo con un elemento <servlet> nel descrittore di deployment. Anziché un elemento <servlet-class>, specifica un elemento <jsp-file> con il percorso del file JSP dalla radice WAR. La L'elemento <servlet> per JSP può contenere parametri di inizializzazione.

    <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>

Puoi installare le librerie di tag JSP con l'elemento <taglib>. Una libreria di tag ha un percorso al file TLD (TLD, descrittore della libreria di tag JSP) (<taglib-location>) e un URI utilizzato dalle JSP per selezionare la libreria da caricare (<taglib-uri>). Tieni presente che App Engine fornisce la libreria di tag standard JavaServer Pages (JSTL) e non devi installarla.

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

Sicurezza e autenticazione

Un'applicazione App Engine può utilizzare gli Account Google per l'autenticazione degli utenti. L'app può utilizzare l'API Account Google per rilevare se l'utente ha eseguito l'accesso, recuperare l'indirizzo email dell'utente che ha eseguito l'accesso e generare URL di accesso e di uscita. Un'app può anche specificare limitazioni di accesso per i percorsi degli URL in base agli Account Google, utilizzando il descrittore di deployment.

L'elemento <security-constraint> definisce un vincolo di sicurezza per gli URL che corrispondono a uno schema. Se un utente accede a un URL il cui percorso ha un vincolo di sicurezza e se l'utente non ha eseguito l'accesso, App Engine lo reindirizza alla piattaforma Google Pagina di accesso degli account. Gli Account Google reindirizzano l'utente all'URL dell'applicazione dopo aver eseguito l'accesso o aver registrato un nuovo account. L'app non deve fare altro per assicurarsi che solo gli utenti che hanno eseguito l'accesso possano accedere all'URL.

Una limitazione di sicurezza include una limitazione di autorizzazione che specifica gli utenti degli Account Google che possono accedere al percorso. Se la limitazione di autorizzazione specifica un ruolo utente *, tutti gli utenti che hanno eseguito l'accesso con un Account Google possono accedere all'URL. Se la limitazione specifica un ruolo utente admin, solo gli sviluppatori registrati dell'applicazione possono accedere all'URL. Il ruolo admin semplifica la creazione di sezioni del sito riservate agli amministratori.

    <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 non supporta i ruoli di sicurezza personalizzati (<security-role>) o i meccanismi di autenticazione alternativi (<login-config>) nel descrittore di deployment.

I vincoli di sicurezza si applicano ai file statici e ai servlet.

URL protetti

App Engine supporta le connessioni sicure con HTTPS per gli URL che utilizzano il dominio REGION_ID.r.appspot.com. Quando una richiesta accede a un URL utilizzando HTTPS e l'URL è configurato per utilizzare HTTPS nel file web.xml, sia i dati della richiesta sia i dati della risposta vengono criptati dal mittente prima di essere trasmessi e decriptati dal destinatario dopo essere stati ricevuti. Le connessioni sicure sono utili per proteggere i dati dei clienti, come dati di contatto, password e messaggi privati.

Per dichiarare che per un URL deve essere utilizzato HTTPS, devi configurare un vincolo di sicurezza nel descrittore di deployment (come descritto in Sicurezza e autenticazione) con un <user-data-constraint> il cui <transport-guarantee> è CONFIDENTIAL. Ad esempio:

    <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>

Le richieste che utilizzano HTTP (non sicuro) per gli URL la cui garanzia di trasporto è CONFIDENTIAL vengono reindirizzate automaticamente allo stesso URL utilizzando HTTPS.

Qualsiasi URL può utilizzare la garanzia di trasporto CONFIDENTIAL, inclusi JSP e file statici.

Il server web di sviluppo non supporta le connessioni HTTPS. Ignora la garanzia di trasporto, pertanto i percorsi destinati all'utilizzo con HTTPS possono essere testati utilizzando connessioni HTTP regolari al server web di sviluppo.

Quando testi i gestori HTTPS dell'app utilizzando l'URL appspot.com con versione, come https://1.latest.your_app_id.REGION_ID.r.appspot.com/, il browser ti avvisa che il certificato HTTPS non è stato firmato per quel percorso del dominio specifico. Se accetti il certificato per quel dominio, le pagine si caricano correttamente. Gli utenti non vedranno l'avviso relativo al certificato quando accedono https://your_app_id.REGION_ID.r.appspot.com/.

Puoi anche utilizzare una forma alternativa dell'URL appspot.com con versione progettata per evitare questo problema sostituendo i punti che separano i componenti del sottodominio con la stringa "-dot-". Ad esempio, all'esempio precedente è possibile accedere senza un avviso sul certificato all'indirizzo https://VERSION_ID-dot-default-dot-PROJECT_ID.REGION_ID.r.appspot.com.

L'accesso e la disconnessione dall'Account Google vengono sempre eseguiti utilizzando un sistema e non è correlata alla configurazione degli URL dell'applicazione.

Come accennato in precedenza, i vincoli di sicurezza si applicano ai file statici e ai servlet. È inclusa la garanzia di trasporto.

Nota: Google consiglia con il protocollo HTTPS per inviare richieste alla tua app. Google non rilascia SSL certificati per domini con doppio carattere jolly ospitati all'indirizzo appspot.com. Di conseguenza, con HTTPS devi utilizzare la stringa "-dot-" anziché "." per separare i sottodomini, come mostrato negli esempi di seguito. Puoi utilizzare un semplice "." con il tuo dominio personalizzato o con indirizzi HTTP.

L'elenco dei file di benvenuto

Se gli URL del tuo sito rappresentano percorsi di file statici o JSP nella WAR, spesso è una buona idea che anche i percorsi verso le directory facciano qualcosa di utile. Un utente che visita il percorso dell'URL /help/accounts/password.jsp per informazioni sulle password dell'account potrebbe provare a visitare /help/accounts/ per trovare una pagina che presenti la documentazione del sistema dell'account. Il descrittore di deployment può specificare un elenco di nomi file che il server deve provare quando l’utente accede a un percorso che rappresenta una sottodirectory WAR non ancora mappata in modo esplicito a un servlet. La specifica del servlet definisce questo elemento come welcome file list.

Ad esempio, se l'utente accede al percorso dell'URL /help/accounts/, il seguente elemento <welcome-file-list> nel descrittore di implementazione indica al server di verificare la presenza di help/accounts/index.jsp e help/accounts/index.html prima di segnalare che l'URL non esiste:

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

Filtri

Un filtro è una classe che agisce su una richiesta come un servlet, ma può Consentire alla gestione della richiesta di continuare con altri filtri o servlet. R di rete può eseguire un'attività ausiliaria, come il logging, l'esecuzione dei controlli di autenticazione o annotare gli oggetti di richiesta o risposta prima per chiamare il servlet. I filtri ti consentono di comporre attività di elaborazione delle richieste dal descrittore di deployment.

Il seguente esempio di implementazione del filtro registra un messaggio e passa il controllo lungo la catena, che può includere altri filtri o un servlet, come descritto dal descrittore di deployment per la versione 21 e successive su EE10 (predefinito), la versione 21 su EE8 e la versione 17 e precedenti. Per utilizzare l'ultima versione supportata su devi aggiornare i servlet delle applicazioni per includere lo spazio dei nomi Jakarta. Per saperne di più sulle opzioni di configurazione, consulta Eseguire l'upgrade di un'applicazione esistente.

v21 e successive (EE10)

Questa classe di filtro implementa l'interfaccia jakarta.servlet.Filter con il metodo doFilter().

package mysite.server;

import java.io.IOException;
import java.util.logging.Logger;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.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() {}

}

Versione 21 (EE8)

Questa classe di filtro implementa l'interfaccia javax.servlet.Filter con Metodo doFilter().

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() {}

}

v17 e versioni precedenti

Questa classe di filtro implementa l'interfaccia javax.servlet.Filter con il metodo doFilter().

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() {}

}

Analogamente ai servlet, configuri un filtro nel descrittore di deployment dichiarando il filtro con l'elemento <filter> e associandolo a un URL con l'elemento <filter-mapping>. Puoi anche mappare i filtri direttamente ad altri servlet.

L'elemento <filter> contiene <filter-name>, <filter-class> e elementi <init-param> facoltativi.

    <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>

L'elemento <filter-mapping> contiene un <filter-name> che corrisponde al nome di un filtro dichiarato e un elemento <url-pattern> per l'applicazione filtrare in base agli URL o a un elemento <servlet-name> che corrisponde al nome di un servlet dichiarato per l'applicazione del filtro ogni volta che viene chiamato il servlet.

    <!-- 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>

Gestione degli errori

Puoi personalizzare ciò che il server invia all'utente quando si verifica un errore, utilizzando il descrittore di deployment. Il server può mostrare una posizione della pagina alternativa quando sta per inviare un determinato codice di stato HTTP o quando un servlet genera una determinata eccezione Java.

L'elemento <error-page> contiene un elemento <error-code> con un valore del codice di errore HTTP (ad esempio 500) o un elemento <exception-type> con il nome della classe dell'eccezione prevista (ad esempio java.io.IOException). Contiene inoltre un elemento <location> contenente il percorso dell'URL della risorsa da mostrare quando si verifica l'errore.

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

Non puoi configurare gestori degli errori personalizzati per il seguente errore condizioni:

  • Pagina di risposta 404 quando non è definita alcuna mappatura del servlet per un URL.
  • 403 pagina di errore di quota
  • Pagina di errore del server 500 visualizzata dopo un errore interno di App Engine.

Funzionalità web.xml non supportate

Le seguenti funzionalità web.xml non sono supportate da App Engine:

  • App Engine supporta l'elemento <load-on-startup> per le dichiarazioni dei servlet. Tuttavia, il caricamento si verifica effettivamente durante la prima richiesta gestita dal web un'istanza del server, non la precedente.
  • Alcuni elementi descrittore di deployment possono assumere un nome visualizzato leggibile, descrizione e icona da usare negli IDE. App Engine non le utilizza e le ignora.
  • App Engine non supporta le variabili di ambiente JNDI (<env-entry>).
  • App Engine non supporta le risorse EJB (<resource-ref>).
  • La notifica relativa all'eliminazione di servlet, contesto servlet o filtri è non supportati.
  • L'elemento <distributable> viene ignorato.
  • La pianificazione del servlet con <run-at> non è supportata.