Exemple Struts 2 Hello World avec annotations et sans fichier struts.xml

De Get Docs
Aller à :navigation, rechercher

Ceci est le deuxième article de la série de tutoriels Struts 2. Si vous êtes directement venu ici, je vous recommande de consulter également le message précédent. Tutoriel pour débutants Struts 2 Dans le dernier tutoriel, nous avons examiné Struts 2 architecture, ses composants et créé une application Web Struts 2 simple avec une configuration basée sur XML (struts.xml). Dans ce didacticiel, nous verrons comment éviter complètement le fichier de configuration struts en utilisant des annotations ou des conventions de dénomination.

Struts 2 Convention Concept

Struts 2 utilise deux méthodologies pour trouver les classes d'action et les classes de résultat. Nous devons utiliser l'API struts2-convention-plugin pour utiliser l'une de ces méthodologies. Si vous avez une application Web normale, vous pouvez télécharger son fichier jar et le placer dans le répertoire lib de l'application Web. Pour les projets Maven, vous pouvez simplement ajouter sa dépendance comme ci-dessous.

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-convention-plugin</artifactId>
    <version>2.3.15.1</version>
</dependency>
  1. Scanning : dans cette méthode, nous spécifions le package qui doit être analysé pour les classes d'action. La configuration doit être effectuée dans web.xml pour le filtre Struts 2, comme ci-dessous.

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.journaldev.struts2.actions</param-value>
        </init-param>
    </filter>

    Struts 2 trouvera les classes d'action en suivant les méthodes.

    • Toute classe annotée avec les annotations @Action ou @Actions.
    • Toute classe implémentant l'interface Action ou étendant la classe ActionSupport.
    • Toute classe dont le nom se termine par Action et contient la méthode execute(). Pour ces classes, la convention de dénomination est utilisée pour déterminer l'action et les résultats.
  2. Convention de dénomination : Struts 2 créera automatiquement une action pour les classes dont le nom se termine par Action. Le nom de l'action est déterminé en supprimant le suffixe Action et en convertissant la première lettre en minuscule. Donc, si le nom de la classe est HomeAction, alors l'action sera "home". Si ces classes ne sont pas annotées avec @Result pour fournir le résultat, les pages de résultats sont examinées dans le répertoire WEB-INF/content et le nom doit être {action}-{return_string}. jsp. Ainsi, si la classe d'action HomeAction renvoie "success", la demande sera transmise à la page WEB-INF/content/home-success.jsp. L'utilisation de la convention de dénomination seule peut être très déroutante et nous ne pouvons pas utiliser la même page JSP pour d'autres classes d'action. Nous devrions donc essayer d'éviter cela et utiliser une configuration basée sur des annotations.

Nous sommes maintenant prêts à créer notre application Hello World struts 2 à l'aide d'annotations et nous n'aurons pas de fichier de configuration struts 2. Créez un projet Web dynamique dans Eclipse Struts2AnnotationHelloWorld et convertissez-le en projet Maven. Le projet final ressemble à l'image ci-dessous.

MavenConfiguration

Nous avons ajouté des dépendances struts2-core et struts2-convention-plugin dans le pom.xml, le code final pom.xml est :

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>Struts2AnnotationHelloWorld</groupId>
    <artifactId>Struts2AnnotationHelloWorld</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.15.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-convention-plugin</artifactId>
            <version>2.3.15.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <warSourceDirectory>WebContent</warSourceDirectory>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>

Configuration du descripteur de déploiement

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>Struts2AnnotationHelloWorld</display-name>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.journaldev.struts2.actions</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

Notez l'élément init-param où nous fournissons un package de classes d'action qui sera analysé par struts 2.

Pages de résultats

Nous avons trois pages de résultats dans notre application. login.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%-- Using Struts2 Tags in JSP --%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Login Page</title>
</head>
<body>
<h3>Welcome User, please login below</h3>
<s:form action="login">
    <s:textfield name="name" label="User Name"></s:textfield>
    <s:textfield name="pwd" label="Password" type="password"></s:textfield>
    <s:submit value="Login"></s:submit>
</s:form>
</body>
</html>

error.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Error Page</title>
</head>
<body>
<h4>User Name or Password is wrong</h4>
<s:include value="login.jsp"></s:include>
</body>
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Welcome Page</title>
</head>
<body>
<h3>Welcome <s:property value="name"></s:property></h3>
</body>
</html>

Créons maintenant nos classes Action que nous allons annoter pour configurer les pages d'action et de résultat.

Classes d'action avec annotations

package com.journaldev.struts2.actions;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Namespaces;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

/**
 * An empty class for default Action implementation for:
 * 
 *  <action name="home">
 *      <result>/login.jsp</result>
 *  </action>
 * HomeAction class will be automatically mapped for home.action
 * Default page is login.jsp which will be served to client
 * @author pankaj
 *
 */

@Namespaces(value={@Namespace("/User"),@Namespace("/")})
@Result(location="/login.jsp")
@Actions(value={@Action(""),@Action("home")})
public class HomeAction extends ActionSupport {
}

Notez que HomeAction est une classe vide dont le seul but est de transmettre la demande à la page login.jsp.

package com.journaldev.struts2.actions;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Namespaces;
import org.apache.struts2.convention.annotation.Result;

/**
 * Notice the @Action annotation where action and result pages are declared
 * Also notice that we don't need to implement Action interface or extend ActionSupport
 * class, only we need is an execute() method with same signature
 * @author pankaj
 *
 */
@Action(value = "login", results = {
        @Result(name = "SUCCESS", location = "/welcome.jsp"),
        @Result(name = "ERROR", location = "/error.jsp") })
@Namespaces(value={@Namespace("/User"),@Namespace("/")})
public class LoginAction {

    public String execute() throws Exception {
        if("pankaj".equals(getName()) && "admin".equals(getPwd()))
        return "SUCCESS";
        else return "ERROR";
    }
    
    //Java Bean to hold the form parameters
    private String name;
    private String pwd;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

Notez l'utilisation des annotations @Action, @Actions, @Result, @Namespace et @Namespaces, l'utilisation est explicite. Maintenant, lorsque nous exécutons notre application, nous obtenons les pages de réponse suivantes. Si vous avez lu le dernier post où nous avons développé la même application avec la configuration struts.xml, vous remarquerez que c'est presque pareil. Le seul changement est la façon dont nous connectons nos classes d'action d'application et nos pages de résultats.

Télécharger l'exemple de projet Struts2 Annotations