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.