Mais um exemplo utilizando o doubleSelect do Struts 2

No exemplo mostrado no post anterior, foi utilizado um HashMap com valores pré-definidos para popular os selects. Neste exemplo, será utilizado um método que retornará uma array com os dados filtrados.

O projeto que está sendo utilizado é o mesmo do exemplo do post anterior, sendo assim, não irei postar novamente as libs e as configurações. Para ver o post anterior clique aqui.

Na página index.jsp foi adicionado mais um link para uma outra action:


<h3>A simple example to how use dobleselect from Struts 2!</h3>

<p><s:a action='test' > Go to dobleselect! </s:a></p>
 <p><s:a action='prepareLists' > Go to dobleselect 2! </s:a></p>

Este segundo link irá chamar o mótodo prepareLists() da Action CityStateAction. Abaixo segue o código desta action.


public class CityStateAction extends ActionSupport{

private static final long serialVersionUID = -2739421817296013920L;

 public ArrayList<State> states;
 public ArrayList<City> cities;

 @Action("prepareLists")
 public String prepareLists(){

  states = new ArrayList<>();
  cities = new ArrayList<>();

  State mg = new State();
  mg.setName("Minas Gerais");
  mg.setAcronym("MG");

  State sp = new State();
  sp.setName("São Paulo");
  sp.setAcronym("SP");

  State rj = new State();
  rj.setName("Rio de Janeiro");
  rj.setAcronym("RJ");

  states.add(mg);
  states.add(sp);
  states.add(rj);

  createCity(mg, "Pouso Alegre");
  createCity(mg, "Poços de Caldas");
  createCity(mg, "Belo Horizonte");

  createCity(sp, "Campinas");
  createCity(sp, "Ribeirão Preto");
  createCity(sp, "Atibaia");

  createCity(rj, "Paraty");
  createCity(rj, "Angra dos Reis");
  createCity(rj, "Resende");

 return SUCCESS;
 }

 public void createCity(State state, String name){

  City city = new City();
  city.setName(name);
  city.setState(state);

  cities.add(city);
 }

 public ArrayList<City> getCitiesByState(State top){
  return populateCitiesList(top);
 }

 public ArrayList<City> populateCitiesList(State state){
  ArrayList<City> citiesByState = new ArrayList<>();

  for(City city : cities){
   if(city.getState().equals(state)){
    citiesByState.add(city);
   }
  }
  return citiesByState;
 }

 public ArrayList<State> getStates() {
  return states;
 }

 public void setStates(ArrayList<State> states) {
  this.states = states;
 }

 public ArrayList<City> getCities() {
  return cities;
 }

 public void setCities(ArrayList<City> cities) {
  this.cities = cities;
 }
}

Como nesta action o método que está sendo chamado não é o execute(), é necessário utilizar a annotaion @Action e passar como parâmetro qual action que chamará este método.
O método prepareLists() popula uma lista de Estados contendo três itens: MG, SP e RJ. Ele popula também uma lista de cidades, contendo três cidades para cada um dos três estados.
Para popular a select de cidades que dependerá da select de estados, será utilizado o método getCitiesByState(…), que receberá o estado selecionado e a partir dele retornará uma lista com as cidades que pertencem ao mesmo.
Quando o método prepareLists() retornar SUCCESS a página prepareLists-success será carregada:

<h3>Filling dobleselect lists with a action method</h3>
<s:form action="test">
<s:doubleselect name="state" listKey="name" listValue="name" list="states"
doubleName="city" doubleListKey="name" doubleListValue="name"                doubleList="getCitiesByState(top)" label="Choose a State/City">
</s:doubleselect>
 </s:form>

No atributo list que corresponde a lista da primeira select, foi passado a lista states que foi populada na Action.
No atributo doubleList é passado o método getCitiesByState(…) da action passando o item que foi selecionado na primeira select.

Página index.jsp
prepareLists-success.jsp: lista de estados
prepareLists-success.jsp: selecionando as cidades do estado de MG.
prepareLists-success.jsp: selecionando o estado de SP na segunda select são carregadas as cidades relacionados a ele.
prepareLists-success.jsp: lista de cidades do estado do RJ
Estrutura do projeto exemplo.

Clique aqui para download do projeto de exemplo.

Um simples exemplo utilizando o doubleselect do Struts 2

Este é um simples exemplo de como preencher um <s:doubleselect> do Struts 2 utilizando um HashMap.

Primeiramente, foram utilizadas as seguinte bibliotecas:

  • asm-3.3.jar
  • asm-commons-3.3.jar
  • commons-fileupload-1.2.2.jar
  • commons-io-2.0.1.jar
  • commons-lang3-3.1.jar
  • commons-logging-1.1.1.jar
  • freemarker-2.3.19.jar
  • javassist-3.11.0.GA.jar
  • ognl-3.0.5.jar
  • struts2-convention-plugin-2.3.4.jar
  • struts2-core-2.3.4.1.jar
  • xwork-core-2.3.4.1.jar

Após adicionar as bibliotecas acima, é necessário adicionar a seguinte configuração no web.xml

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

 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>
   org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  </filter-class>
  <init-param>
   <param-name>struts.devMode</param-name>
   <param-value>true</param-value>
  </init-param>
 </filter>

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

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

</web-app>
<pre>

Não é necessário criar um arquivo struts.xml pois será utilizado o plugin de convenção de nomenclatura do Struts 2 ao invés de xml para mapeamento da Action.

No arquivo index.jsp existirá apenas uma mensagem e logo abaixo um link que chamará a o método execute() da action TestAction.

</pre>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>

<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Doubleselect Struts 2</title>
</head>
<body>

  <h3>A simple example to how use dobleselect from Struts 2!</h3>

  <p><s:a action='test' > Go to dobleselect! </s:a></p>

</body>
</html>
<pre>

Pela convenção de nomenclatura padrão do Plugin de Convenção do Struts 2 (struts2-convention-plugin-2.3.4.jar) que está sendo utilizado, esta url irá procurar pela TestAction e chamar o método execute();

Abaixo segue o código da classe TestAction:


package cris.test.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport{

private static final long serialVersionUID = 6939102585085668554L;

    public List<String> listFruit;
    public List<String> listColor;

    public String fruitOrColor1;
    public String fruitOrColor2;

    public Map<String, ArrayList<String>> listCorlorOrFruits;

    public String execute(){

     listFruit = new ArrayList<>();
     listColor = new ArrayList<>();

     listFruit.add("Apple");
     listFruit.add("Orange");
     listFruit.add("Strawberry");

     listColor.add("Red");
     listColor.add("Blue");
     listColor.add("Purple");

     listCorlorOrFruits = new HashMap<String, ArrayList<String>>();
     listCorlorOrFruits.put("Fruits", (ArrayList<String>) listFruit);
     listCorlorOrFruits.put("Colors", (ArrayList<String>) listColor);

     return "success";
   }

   public List<String> getListColor() {
    return listColor;
   }

   public void setListColor(List<String> listColor) {
    this.listColor = listColor;
   }

   public String getFruitOrColor1() {
    return fruitOrColor1;
   }

   public void setFruitOrColor1(String fruitOrColor1) {
    this.fruitOrColor1 = fruitOrColor1;
   }

   public String getFruitOrColor2() {
    return fruitOrColor2;
   }

   public void setFruitOrColor2(String fruitOrColor2) {
    this.fruitOrColor2 = fruitOrColor2;
   }

   public Map<String, ArrayList<String>> getListCorlorOrFruits() {
    return listCorlorOrFruits;
   }

   public void setListCorlorOrFruits(
       Map<String, ArrayList<String>> listCorlorOrFruits) {
    this.listCorlorOrFruits = listCorlorOrFruits;
   }

   public List<String> getListFruit() {
    return listFruit;
   }

   public void setListFruit(List<String> listFruit) {
    this.listFruit = listFruit;
   }
}

Dentro do método execute foi criado duas listas, uma com frutas e outra com cores. Estas listas foram adicionadas dentro de HashMap. Cada lista contém sua chave correspondente no HashMap.

É importante também que os getters and setters sejam colocados na Action. Então o método execute será responsável por preencher as listas.

Este método irá redirecionar para página test-success.jsp que deve estar dentro de WebContent/WEB-INF/content. Abaixo segue o código desta página:

</pre>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Doubleselect Struts 2</title>
</head>
<body>

 <h3>Filling dobleselect lists with a HashMap</h3>

 <s:form action="test">
   <s:doubleselect name="fruitOrColor1" list="listCorlorOrFruits.keySet()"
                   doubleName="fruitOrColor2" doubleList="listCorlorOrFruits.get(top)"                 label="Color or Fuits">
   </s:doubleselect>
 </s:form>

</body>
</html>

Os atributos name e list se referem ao primeiro Select e os atributos  doubleName e doubleList se refere ao segundo Select que irá depender do primeiro.

No atributo list está sendo passado as keys do Map e no dobleList está sendo passado o valor das keys que são as arrays.

Então quando for selecionado a opção de frutas a lista de frutas será carregada no segundo select e quando a opção cor for selecionada no primeiro select a lista de cores será carregada.

Abaixo segue imagens do exemplo rodando:

Página index.jsp
Página test-success.jsp: Selecionando a opção Fruits a segunda select é preenchida com a lista de frutas
Página test-success.jsp: Selecionando a opção Colors a segunda select é preenchida com a lista de cores.
Estrutura do exemplo no eclipse.

Clique aqui para fazer o download do projeto de exemplo.

Struts 2 – Validação utilizando Annotations

As seguinte bibliotecas foram utilizadas:

  • commons-logging-1.1.1.jar
  • freemarker-2.3.8.jar
  • ognl-2.6.11.jar
  • struts2-core-2.0.11.1.jar
  • xwork-2.0.4.jar

Primeiro será configurado o arquivo struts.xml da seguinte forma:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>

<include file="struts-default.xml" />

<package name="default" extends="struts-default">

<action name="Login">
<result name="input">index.jsp</result>
<result name="success">success.jsp</result>
<result name="error">index.jsp</result>
</action>

</package>
</struts>

Agora será criada uma página index.jsp com um formulário para login.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login</title>
<s:head />
</head>
<body>

<s:form action="Login" method="post" validate="true" >
<s:actionmessage/>
<s:textfield name="username" label="Username" size="14" required="true" />
<s:password name="password" label="Password" size="14" required="true" /><br/>
<s:submit name="login" value="Login" type="button" align="center" method="post" required="true"/>

</s:form>

A tag <s:head /> adiciona um link ao css e javascripts utilizado para redenrizar os elementos do struts na página. Também é colocado o atributo validate=”true” e nos campo username e password é colocado o atributo required=”true”.

Também será criada uma página que será exibida quando o usuário e senha digitados no formulário de login correspoderem a string “admin”.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Success</title>
</head>
<body>
<h1>Success Login! </h1>
</body>
</html>

Agora será criada uma classe para ser a Action e que se chamará LoginAction:


public class LoginAction extends ActionSupport{

private static final long serialVersionUID = -1200187785923962284L;

private String username;
private String password;

public String login(){

if(username == "admin" && password == "admin"){
return "success";
}

return "error";
}

public String post(){
return "success";
}

/**
* @param username the username to set
*/
@RequiredStringValidator(type=ValidatorType.SIMPLE, trim=true, fieldName="username", message="Fill username field")
public void setUsername(String username) {
this.username = username;
}

/**
* @return the username
*/
public String getUsername() {
return username;
}

/**
* @param password the password to set
*/

@RequiredStringValidator(type=ValidatorType.SIMPLE, trim=true, fieldName="password", message="Fill password field")
public void setPassword(String password) {
this.password = password;
}

/**
* @return the password
*/
public String getPassword() {
return password;
}

}

Para a validação, foram colocados nos métodos sets dos atributos a anotação @RequiredStringValidator colocando o tipo de validação, como se trata de textfields será utilizado o o tipo SIMPLE. Colocamos a função trim como true, passamos o nome do campo a ser validado e mensagem que deve aparecer caso a validação falhe.

Página de login antes da submissão dos dados
Formulário de login após submeter formulário com os campos vazios e com espaços em branco.
Página que é mostrada quando os campos de login correspondem a string “admin”

Validação de Login Simples com Struts 2

Primeiramente vamos criar a nossa página index.jsp, para que possamos dar funcionalidades ajax para a nossa página utilizaremos na tag head o theme=”ajax”, no nosso form usaremos a action Login e o seu método loginStatus, que iremos ver mais abaixo, colocamos também o atributo validate como “true” para que possamos fazer a validadação dos campos. Usamos o atributo required como “true” nos campo de login e senha para que os mesmos sejam obrigatorios:

<pre>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<%@taglib prefix="s" uri="/struts-tags" %>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Login</title>

<s:head theme="ajax"/>

</head>

<body>

<s:form action="Login!loginStatus" validate="true" >

<s:textfield name="username" label="Usuário" required="true"

theme="ajax"/>

<s:password name="password" label="Senha" required="true"

theme="ajax"/>

<s:submit value="Login" align="center" required="true"/>

</s:form>

</body>

</html>

Agora será criada a página errorLogin.jsp que será usada quando o usuário e/ou senha estiverem incorretos, então redirecionaremos para esta página que é bem simples, só contem uma mensagem em vermelho informando que a senha e/ou usuário são inválidos:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Erro em Login</title>

</head>

<body>

<h1 align="center">

<font color="red">ERRO LOGIN: Usuário ou senha inválidos </font>

</h1>

</body>

</html>

E quando o login for válido, a aplicação redirecionará para a página success Login.jsp, que apenas terá uma mensagem de sucesso:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Sucesso em Login</title>

</head>

<body>

<h1 align="center">

<font color="blue">Você realizou o login com sucesso!!!</font>

</h1>

</body>

</html>
<span style="color: #339966;">

</span>

Agora criaremos a nossa action que será chamada de LoginAction, que como visto, será usada na página index.jsp. Nossa action herdará de ActionSupport, e apenas terá um método para validar o login, como não estamos fazendo conexão com o banco de dados neste exemplo, para efeito de simplificação, consideraremos o usuário e senha corretos como “admin”, então se o que for digitado nos campos de usuário e senha na página index.jsp forem “admin” e “admin” respectivamente o login será válido. É importante não se esquecer dos métodos getters and setters, pois o Struts os usa para o acesso dos atributos da action:

public class LoginAction extends ActionSupport {

private String _username;

private String _password;

private String _status;

public LoginAction() {

}

public String loginStatus(){

_status = "invalid";

if(_username.equals("admin") && _password.equals("admin")) {

_status = "valid";

}

return _status;

}

public String getUsername() {

return _username;

}

public void setUsername(String username) {

_username = username;

}

public String getPassword() {

return _password;

}

public void setPassword(String password) {

_password = password;

}

}
<pre style="padding-left: 30px;">

Depois disto, configuraremos agora o nosso struts.xml, iremos mapear a nossa action (LoginAction), na tag <action> colocamos o nome da nossa Action como Login, e colocamos uma exclamação e um asterisco que indica que o struts vai ler todos os métodos da action, assim podemos usar qualquer método da action, no atributo class colocamos o caminho da nossa action. Adicionamos também dois resultados, a String “invalid” caso o login não seja válido que redirecionará para a página errorLogin.jsp e a String “valid” , caso seja válido que retornará para a página successLogin.jsp :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
 <struts>
<include file="struts-default.xml" />
<package name="default" extends="struts-default">
<action name="Login!*"
                 class="cris.exemplo.login.strtus2.LoginAction" >
<result name="invalid">errorLogin.jsp</result>
             <result name="valid">successLogin.jsp</result>
</action>
</package>
 </struts></pre>
<span style="color: #339966;">

</span>

E por último o LoginAction-validation.xml, que será responsável pela validação dos campos, o nome deste arquivo deve ser igual ao nome da action correspondente precencido de -validation. Neste arquivo passamos o nome do field que vamos validar e o tipo, que no nosso caso é os campos username e password, o tipo dos dois são requredstring, ou seja esses campos não poderão estar em branco. E passamos também a mensagem que será mostrado caso os campos não forem preenchidos.

</pre>

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC

"-//OpenSymphony Group//XWork Validator 1.0.2//EN"

"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>

<field name="username">

<field-validator type="requiredstring">

<message>É necessário informar o usuário</message>

</field-validator>

</field>

<field name="password">

<field-validator type="requiredstring">

<message>É necessário informar a senha</message>

</field-validator>

</field>

</validators>
<span style="color: #339966;">

</span>

Turorial em PDF

Neste link você pode baixar o projeto porém estão sem as bibliotecas.

HelloWorld com Struts 2

Para esta pequena aplicação será utilizado como IDE o eclipse e a versão do struts 2.0.11.

Do pacote lib do struts 2 utilizemos a seguintes bibliotecas:

  • commons-logging.jar
  • freemarker.jar
  • ognl.jar
  • struts2-core.jar
  • xwork.jar

Essas libs deverão estar dentro de WebContent/WEB-INF/lib,  esses diretórios são criados automaticamente quando se cria um WebDinamicProject no eclipse.

Primeiro será configurado o arquivo web.xml que também é criado automaticamente quando se cria um WebDinamicProject no eclipse, serão adicionadas seguintes linhas:


  Hello World Struts2

    struts2

			org.apache.struts2.dispatcher.FilterDispatcher

    struts2
    /*

    index.jsp

Agora criaremos a nossa Action que vai se chamar HelloStruts2, a action nada mais é que a classe que será mapeada no struts.xml, ela será responsável por atribuir a string “José” para o atributo name da classe,  ela deve estender de ActionSupport para que tenha as funcionalidades do Strtus. O JSP irá usar os métodos getter and setters para acessar os atributos da classe. Por padrão o método execute é o primeiro método que é chamado na action, ao menos que vc configure no struts.xml que outro método será chamado.

package cris.helloworld.struts2.action;
import com.opensymphony.xwork2.ActionSupport;

public class HelloStruts2 extends ActionSupport {
	private static final long serialVersionUID = -4647857925273234378L;

	private String _name;

	public HelloStruts2() {
	}

	public String execute(){
		_name = "José";
		return "execute";
	}

	public String getName(){
		return _name;
	}

	public void setName(String name){
		_name = name;
	}
}

Agora criaremos o arquivo struts .xml, que será reponsável pelo mapeamento da action, ele devera estar dentro da pasta src do projeto. No eclipse para criar um xml  clicamos com o botão direito em cima do diretório que queremos  -> new -> other -> XML -> XML. Para criar um   na tag <action> colocamos o nome que será chamada a nossa action no atributo name, e o pacote em que a action se localiza no atributo class. Como não estamos especificando nenhum método, por default será chamado o método execute. Na tag <result> configuramos os rsultados que a action pode nos retornar. Neste caso estamos dizendo que ela pode retornar a string “execute” e que se retornar a pagina direcionada será a helloStruts.jsp.

</pre>
<pre>
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

  <include file="struts-default.xml" />

  <package name="default" extends="struts-default">

    <action name="HelloStruts"

      class="cris.helloworld.struts2.action.HelloStruts2">

       <result name="execute">helloStruts.jsp</result>

    </action>

   </package>

</struts>
<span style="color: #339966;"> </span>
<pre>

Agora criaremos a nossa index.jsp, que será a primeira página da aplicação, nela colacamos a taglib do struts, por conversão usamos como prefixo a letra “s”, na tag <a> no atributo href, colocamos o nome da action, a qual foi mapeada no struts.xml. Então quando o link for clicado ele chamará o método execute da nossa action.

</pre>
<pre>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Index - Hello World Struts 2</title>

</head>

<body>

<%@ taglib prefix="s" uri="/struts-tags"%>

<s:a href="HelloStruts.action">Clique aqui!</s:a>

</body>

</html>

<pre>
<pre>

Por último será criado a página helloStruts.jsp, esta página será chamada quando o link da index.jsp for clicado. E a tag <s:property> será responsável por pegar o valor do atributo name atribuído na action:

</pre>
<pre>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Hello Struts 2</title>

</head>

<body>

<%@ taglib prefix="s" uri="/struts-tags"%>

Hello Struts 2 <s:property value="name"/>

</body>

</html>

<pre>
<pre>
<pre>

Abaixo segue a extrutura de como o exemplo deve mais ou menos ficar:
exemplo

Tutorial em PDF
Clique aqui para baixar os projeto sem as bibliotecas