Un'applicazione Web Java senza un file web.xml

1. Panoramica

In questo tutorial, creiamo un'applicazione web Java utilizzando Servlet 3.0+.

Daremo uno sguardo a tre annotazioni - @WebServlet , @WebFilter e @WebListener - che possono aiutarci a eliminare i nostri file web.xml .

2. La dipendenza da Maven

Per poter utilizzare queste nuove annotazioni, dobbiamo includere la dipendenza javax.servlet-api :

 javax.servlet javax.servlet-api 4.0.1 

3. Configurazione basata su XML

Prima di Servlet 3.0, configuravamo un'applicazione web Java in un file web.xml :

  com.baeldung.servlets3.web.listeners.RequestListener   uppercaseServlet com.baeldung.servlets3.web.servlets.UppercaseServlet   uppercaseServlet /uppercase   emptyParamFilter com.baeldung.servlets3.web.filters.EmptyParamFilter   emptyParamFilter /uppercase  

Iniziamo sostituendo ogni sezione di configurazione con le rispettive annotazioni introdotte in Servlet 3.0.

4. Servlet

JEE 6 fornito con Servlet 3.0 che ci consente di utilizzare annotazioni per le definizioni di servlet, riducendo al minimo l'uso di un file web.xml per un'applicazione web.

Ad esempio, possiamo definire un servlet ed esporlo con l' annotazione @WebServlet

Definiamo un servlet per il pattern URL / maiuscolo . Trasformerà il valore del parametro della richiesta di input in maiuscolo:

@WebServlet(urlPatterns = "/uppercase", name = "uppercaseServlet") public class UppercaseServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { String inputString = request.getParameter("input").toUpperCase(); PrintWriter out = response.getWriter(); out.println(inputString); } }

Notare che abbiamo definito un nome per il servlet ( uppercaseServlet) a cui ora possiamo fare riferimento. Ne faremo uso nella prossima sezione.

Con l' annotazione @WebServlet , stiamo sostituendo le sezioni servlet e servlet-mapping dal file web.xml .

5. Filtri

Un filtro è un oggetto utilizzato per intercettare richieste o risposte, eseguendo attività di pre o post-elaborazione.

Possiamo definire un filtro con l' annotazione @WebFilter .

Creiamo un filtro per verificare se il parametro di richiesta di input è presente:

@WebFilter(urlPatterns = "/uppercase") public class EmptyParamFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String inputString = servletRequest.getParameter("input"); if (inputString != null && inputString.matches("[A-Za-z0-9]+")) { filterChain.doFilter(servletRequest, servletResponse); } else { servletResponse.getWriter().println("Missing input parameter"); } } // implementations for other methods }

Con l' annotazione @WebFilter , stiamo sostituendo le sezioni filter e filter-mapping dal file web.xml .

6. Ascoltatori

Spesso avremo bisogno di attivare azioni in base a determinati eventi. È qui che gli ascoltatori vengono in soccorso. Questi oggetti ascolteranno un evento ed eseguiranno il comportamento da noi specificato.

Come in precedenza, possiamo definire un listener con l' annotazione @WebListener .

Creiamo un listener che conti ogni volta che eseguiamo una richiesta al server. Implementeremo ServletRequestListener , ascoltando ServletRequestEvent s:

@WebListener public class RequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent event) { HttpServletRequest request = (HttpServletRequest)event.getServletRequest(); if (!request.getServletPath().equals("/counter")) { ServletContext context = event.getServletContext(); context.setAttribute("counter", (int) context.getAttribute("counter") + 1); } } // implementations for other methods }

Tieni presente che stiamo escludendo le richieste al pattern / contatore URL .

Con l' annotazione @WebListener , stiamo sostituendo la sezione listener dal file web.xml .

7. Compila ed esegui

Per coloro che seguono, nota che per il test, c'è un secondo servlet che abbiamo aggiunto per l' endpoint / counter che restituisce semplicemente l' attributo di contesto del servlet counter .

Quindi, usiamo Tomcat come server delle applicazioni.

Se stiamo utilizzando una versione di maven-war-plugin precedente alla 3.1.0, dovremo impostare la proprietà failOnMissingWebXml su false .

Ora possiamo distribuire il nostro file .war a Tomcat e accedere ai nostri servlet.

Proviamo il nostro endpoint / maiuscolo :

curl //localhost:8080/spring-mvc-java/uppercase?input=texttouppercase TEXTTOUPPERCASE

E dovremmo anche vedere come appare la nostra gestione degli errori:

curl //localhost:8080/spring-mvc-java/uppercase Missing input parameter

E infine, un rapido test del nostro ascoltatore:

curl //localhost:8080/spring-mvc-java/counter Request counter: 2

8. XML ancora necessario

Anche, con tutte le funzionalità introdotte in Servlet 3.0, ci sono alcuni casi d'uso in cui avremo ancora bisogno di un file web.xml , tra cui:

  • Non possiamo definire l'ordine del filtro con le annotazioni : abbiamo ancora bisogno del file sezione se abbiamo più filtri che dobbiamo applicare in un ordine particolare
  • Per definire un timeout di sessione, dobbiamo ancora utilizzare il file sezione
  • Abbiamo ancora bisogno del file elemento per l'autorizzazione basata sul contenitore
  • E per specificare i file di benvenuto, avremo ancora bisogno di un file sezione

Oppure, Servlet 3.0 ha anche introdotto un supporto programmatico tramite ServletContainerInitializer , che può anche colmare alcune di queste lacune.

9. Conclusione

In questo tutorial, abbiamo configurato un'applicazione web Java senza utilizzare il file web.xml esercitando le annotazioni equivalenti.

Come sempre, il codice sorgente di questo tutorial può essere trovato su GitHub. Inoltre, su GitHub è possibile trovare anche un'applicazione che utilizza il tradizionale file web.xml.

Per un approccio basato su Spring, vai al nostro tutorial web.xml vs. Initializer with Spring.