Guide sur les annotations liées à Java EE Web

1. Vue d'ensemble

Les annotations Java EE facilitent la vie des développeurs en leur permettant de spécifier le comportement des composants d'application dans un conteneur. Ce sont des alternatives modernes pour les descripteurs XML et permettent d'éviter le code standard.

Dans cet article, nous nous concentrerons sur les annotations introduites avec l'API Servlet 3.1 dans Java EE 7. Nous examinerons leur objectif et examinerons leur utilisation.

2. Annotations Web

L'API Servlet 3.1 a introduit un nouvel ensemble de types d'annotations pouvant être utilisés dans les classesServlet:

  • @WebServlet

  • @WebInitParam

  • @WebFilter

  • @WebListener

  • @ServletSecurity

  • @HttpConstraint

  • @HttpMethodConstraint

  • @MultipartConfig

Nous les examinerons en détail dans les sections suivantes.

3. @WebServlet

En termes simples, cette annotation nous permet de déclarer les classes Java en tant que servlets:

@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. Utilisation des attributs de l'annotation@WebServlet

@WebServlet a un ensemble d'attributs qui nous permettent de personnaliser le servlet:

  • name

  • la description

  • urlPatterns

  • initParams

Nous pouvons les utiliser comme indiqué dans l'exemple ci-dessous:

@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'attributname remplace le nom de servlet par défaut qui est le nom de classe complet par défaut. Si nous voulons fournir une description de ce que fait le servlet, nous pouvons utiliser l'attributdescription.

L'attributurlPatterns est utilisé pour spécifier la ou les URL sur lesquelles le servlet est disponible (plusieurs valeurs peuvent être fournies à cet attribut comme indiqué dans l'exemple de code).

4. @WebInitParam

Cette annotation est utilisée avec l'attributinitParams de l'annotation@WebServlet et les paramètres d'initialisation du servlet.

Dans cet exemple, nous définissons un paramètre d'initialisation de servlettype, à la valeur de «économies»:

@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

Si nous voulons modifier la requête et la réponse d'un servlet sans toucher à sa logique interne, nous pouvons utiliser l'annotationWebFilter. Nous pouvons associer des filtres à une servlet ou à un groupe de servlets et à un contenu statique en spécifiant un modèle d'URL.

Dans l'exemple ci-dessous, nous utilisons l'annotation@WebFilter pour rediriger tout accès non autorisé à la page de connexion:

@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

Si nous voulons savoir ou contrôler comment et quand un servlet et ses requêtes sont initialisés ou modifiés, nous pouvons utiliser l'annotation@WebListener.

Pour écrire un auditeur Web, nous devons étendre une ou plusieurs des interfaces suivantes:

  • NotificationsServletContextListener – for sur le cycle de vie deServletContext

  • NotificationsServletContextAttributeListener – for lorsqu'un attributServletContext est modifié

  • NotificationsServletRequestListener – for chaque fois qu'une demande de ressource est faite

  • NotificationsServletRequestAttributeListener – for lorsqu'un attribut est ajouté, supprimé ou modifié dans unServletRequest

  • NotificationsHttpSessionListener – for lorsqu'une nouvelle session est créée et détruite

  • NotificationsHttpSessionAttributeListener – for lorsqu'un nouvel attribut est ajouté ou supprimé d'une session

Voici un exemple de la façon dont nous pouvons utiliser unServletContextListener pour configurer une application 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

Lorsque nous voulons spécifier le modèle de sécurité de notre servlet, y compris les rôles, le contrôle d'accès et les exigences d'authentification, nous utilisons l'annotation@ServletSecurity.

Dans cet exemple, nous allons restreindre l'accès à nosAccountServlet en utilisant l'annotation@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();
    }
}

Dans ce cas, lors de l'appel duAccountServlet,, le navigateur affiche un écran de connexion pour que l'utilisateur saisisse un nom d'utilisateur et un mot de passe valides.

Nous pouvons utiliser les annotations@HttpConstraint et@HttpMethodConstraint pour spécifier les valeurs des attributsvalue ethttpMethodConstraints, de l'annotation@ServletSecurity.

L'annotation@HttpConstraint s'applique à toutes les méthodes HTTP. En d'autres termes, il spécifie la contrainte de sécurité par défaut.

@HttpConstraint a trois attributs:

  • valeur

  • rôlesAutorisé

  • transportGarantie

Parmi ces attributs, l'attribut le plus couramment utilisé estrolesAllowed. Dans l'exemple d'extrait de code ci-dessus, les utilisateurs appartenant au rôleMember sont autorisés à appeler toutes les méthodes HTTP.

L'annotation@HttpMethodConstraint nous permet de spécifier les contraintes de sécurité d'une méthode HTTP particulière.

@HttpMethodConstraint possède les attributs suivants:

  • valeur

  • emptyRoleSemantic

  • rôlesAutorisé

  • transportGarantie

Dans l'exemple d'extrait de code ci-dessus, il montre comment la méthodedoPost est limitée uniquement pour les utilisateurs qui appartiennent au rôleAdmin, permettant à la fonction de dépôt d'être effectuée uniquement par un utilisateurAdmin.

8. @MultipartConfig

Cette annotation est utilisée lorsque nous devons annoter un servlet pour gérer les requêtesmultipart/form-data (généralement utilisé pour un servlet de téléchargement de fichier).

Cela exposera les méthodesgetParts() etgetPart(name) desHttpServletRequest pouvant être utilisées pour accéder à toutes les parties ainsi qu'à une partie individuelle.

Le fichier téléchargé peut être écrit sur le disque en appelant leswrite(fileName) de l'objet Part.

Nous allons maintenant regarder un exemple de servletUploadCustomerDocumentsServlet qui démontre son utilisation:

@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 a quatre attributs:

  • fileSizeThreshold - Il s'agit du seuil de taille lors de l'enregistrement temporaire du fichier téléchargé. Si la taille du fichier téléchargé est supérieure à ce seuil, il sera stocké sur le disque. Sinon, le fichier est stocké en mémoire (taille en octets)

  • maxFileSize - Il s'agit de la taille maximale du fichier téléchargé (taille en octets)

  • maxRequestSize - Il s'agit de la taille la plus élevée de la demande, y compris les fichiers téléchargés et d'autres données de formulaire (taille en octets)

  • location - Le est le répertoire dans lequel les fichiers téléchargés sont stockés

9. Conclusion

Dans cet article, nous avons examiné certaines annotations Java EE introduites avec l'API Servlet 3.1, ainsi que leur objectif et leur utilisation.

Le code source lié à cet article peut être trouvéover on GitHub.