Una guida alle annotazioni relative al Web Java EE

1. Panoramica

Le annotazioni Java EE semplificano la vita degli sviluppatori consentendo loro di specificare come devono comportarsi i componenti dell'applicazione in un contenitore. Queste sono alternative moderne per i descrittori XML e fondamentalmente consentono di evitare il codice boilerplate.

In questo articolo, ci concentreremo sulle annotazioni introdotte con Servlet API 3.1 in Java EE 7. Esamineremo il loro scopo e guarderemo il loro utilizzo.

2. Annotazioni web

Servlet API 3.1 ha introdotto un nuovo set di tipi di annotazioni che possono essere utilizzati nelle classi Servlet :

  • @WebServlet
  • @WebInitParam
  • @WebFilter
  • @WebListener
  • @ServletSecurity
  • @HttpConstraint
  • @HttpMethodConstraint
  • @MultipartConfig

Li esamineremo in dettaglio nelle prossime sezioni.

3. @WebServlet

In poche parole, questa annotazione ci consente di dichiarare le classi Java come servlet :

@WebServlet("/account") public class AccountServlet extends javax.servlet.http.HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // ... } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { // ... } }

3.1. Utilizzando Attributi di @WebServlet annotazione

@WebServlet ha una serie di attributi che ci consentono di personalizzare il servlet:

  • nome
  • descrizione
  • urlPatterns
  • initParams

Possiamo usarli come mostrato nell'esempio seguente:

@WebServlet( name = "BankAccountServlet", description = "Represents a Bank Account and it's transactions", urlPatterns = {"/account", "/bankAccount" }, initParams = { @WebInitParam(name = "type", value = "savings")}) public class AccountServlet extends javax.servlet.http.HttpServlet { String accountType = null; public void init(ServletConfig config) throws ServletException { // ... } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // ... } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { // ... } }

L' attributo name sovrascrive il nome del servlet predefinito che è il nome completo della classe per impostazione predefinita. Se vogliamo fornire una descrizione di ciò che fa il servlet, possiamo usare l' attributo description .

L' attributo urlPatterns viene utilizzato per specificare gli URL in cui è disponibile il servlet (è possibile fornire più valori a questo attributo come mostrato nell'esempio di codice).

4. @WebInitParam

Questa annotazione viene utilizzato con l'initParams attributo della @WebServlet annotazione e parametri di inizializzazione del servlet.

In questo esempio, impostiamo un tipo di parametro di inizializzazione servlet , sul valore di 'risparmio':

@WebServlet( name = "BankAccountServlet", description = "Represents a Bank Account and it's transactions", urlPatterns = {"/account", "/bankAccount" }, initParams = { @WebInitParam(name = "type", value = "savings")}) public class AccountServlet extends javax.servlet.http.HttpServlet { String accountType = null; public void init(ServletConfig config) throws ServletException { accountType = config.getInitParameter("type"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { // ... } }

5. @WebFilter

Se vogliamo modificare la richiesta e la risposta di un servlet senza toccare la sua logica interna, possiamo utilizzare l' annotazione WebFilter . Possiamo associare filtri a un servlet o a un gruppo di servlet e contenuto statico specificando un pattern URL.

Nell'esempio seguente stiamo utilizzando l' annotazione @WebFilter per reindirizzare qualsiasi accesso non autorizzato alla pagina di accesso:

@WebFilter( urlPatterns = "/account/*", filterName = "LoggingFilter", description = "Filter all account transaction URLs") public class LogInFilter implements javax.servlet.Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; res.sendRedirect(req.getContextPath() + "/login.jsp"); chain.doFilter(request, response); } public void destroy() { } }

6. @WebListener

Se vogliamo conoscere o controllare come e quando un servlet e le sue richieste vengono inizializzate o modificate, possiamo usare l' annotazione @WebListener .

Per scrivere un listener web dobbiamo estendere una o più delle seguenti interfacce:

  • ServletContextListener: per le notifiche sul ciclo di vita di ServletContext
  • ServletContextAttributeListener: per le notifiche quando viene modificato un attributo ServletContext
  • ServletRequestListener: per le notifiche ogni volta che viene effettuata una richiesta per una risorsa
  • ServletRequestAttributeListener - per le notifiche quando un attributo viene aggiunto, rimosso o modificato in un ServletRequest
  • HttpSessionListener: per le notifiche quando viene creata e distrutta una nuova sessione
  • HttpSessionAttributeListener: per le notifiche quando un nuovo attributo viene aggiunto o rimosso da una sessione

Di seguito è riportato un esempio di come possiamo utilizzare un ServletContextListener per configurare un'applicazione web:

@WebListener public class BankAppServletContextListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { sce.getServletContext().setAttribute("ATTR_DEFAULT_LANGUAGE", "english"); } public void contextDestroyed(ServletContextEvent sce) { // ... } }

7. @ServletSecurity

Quando vogliamo specificare il modello di sicurezza per il nostro servlet, inclusi ruoli, controllo di accesso e requisiti di autenticazione, usiamo l'annotazione @ServletSecurity .

In questo esempio limiteremo l'accesso al nostro AccountServlet utilizzando l' annotazione @ServletSecurity :

@WebServlet( name = "BankAccountServlet", description = "Represents a Bank Account and it's transactions", urlPatterns = {"/account", "/bankAccount" }, initParams = { @WebInitParam(name = "type", value = "savings")}) @ServletSecurity( value = @HttpConstraint(rolesAllowed = {"Member"}), httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"Admin"})}) public class AccountServlet extends javax.servlet.http.HttpServlet { String accountType = null; public void init(ServletConfig config) throws ServletException { // ... } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // ... } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { double accountBalance = 1000d; String paramDepositAmt = request.getParameter("dep"); double depositAmt = Double.parseDouble(paramDepositAmt); accountBalance = accountBalance + depositAmt; PrintWriter writer = response.getWriter(); writer.println(" Balance of " + accountType + " account is: " + accountBalance + ""); writer.flush(); } }

In questo caso, quando si richiama AccountServlet, il browser visualizza una schermata di accesso per consentire all'utente di inserire un nome utente e una password validi.

Possiamo usare @HttpConstraint e @HttpMethodConstraint annotazioni per specificare i valori per gli attributi del valore e httpMethodConstraints, di @ServletSecurity annotazione.

L' annotazione @HttpConstraint si applica a tutti i metodi HTTP. In altre parole, specifica il vincolo di sicurezza predefinito.

@HttpConstraint ha tre attributi:

  • valore
  • ruoli consentiti
  • trasportoGaranzia

Out of these attributes, the most commonly used attribute is rolesAllowed. In the example code snippet above, users who belong to the role Member are allowed to invoke all HTTP methods.

@HttpMethodConstraint annotation allows us to specify the security constraints of a particular HTTP method.

@HttpMethodConstraint has the following attributes:

  • value
  • emptyRoleSemantic
  • rolesAllowed
  • transportGuarantee

In the example code snippet above, it shows how the doPost method is restricted only for users who belong to the Admin role, allowing the deposit function to be done only by an Admin user.

8. @MultipartConfig

This annotation is used when we need to annotate a servlet to handle multipart/form-data requests (typically used for a File Upload servlet).

This will expose the getParts() and getPart(name) methods of the HttpServletRequest can be used to access all parts as well as an individual part.

The uploaded file can be written to the disk by calling the write(fileName) of the Part object.

Now we will look at an example servlet UploadCustomerDocumentsServlet that demonstrates its usage:

@WebServlet(urlPatterns = { "/uploadCustDocs" }) @MultipartConfig( fileSizeThreshold = 1024 * 1024 * 20, maxFileSize = 1024 * 1024 * 20, maxRequestSize = 1024 * 1024 * 25, location = "./custDocs") public class UploadCustomerDocumentsServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { for (Part part : request.getParts()) { part.write("myFile"); } } }

@MultipartConfig has four attributes:

  • fileSizeThreshold - Questa è la soglia delle dimensioni quando si salva temporaneamente il file caricato. Se la dimensione del file caricato è maggiore di questa soglia, verrà archiviato sul disco. In caso contrario, il file viene archiviato in memoria (dimensione in byte)
  • maxFileSize - Questa è la dimensione massima del file caricato (dimensione in byte)
  • maxRequestSize - Questa è la dimensione massima della richiesta, inclusi i file caricati e altri dati del modulo (dimensione in byte)
  • location : è la directory in cui vengono archiviati i file caricati

9. Conclusione

In questo articolo, abbiamo esaminato alcune annotazioni Java EE introdotte con Servlet API 3.1 e il loro scopo e il loro utilizzo.

Il codice sorgente relativo a questo articolo può essere trovato su GitHub.