Arquivos de sites

Tutorial Completo de Struts2 (PDF – em Português)

Clique aqui para fazer o download do Tutorial Completo de Struts2 (PDF – em Português)

Se preferir pode acessar o conteúdo diretamente aqui no blog, tudo em português:

É isso ai pessoal… deu um trabalhinho traduzir tudo isso, deve ter alguns errinhos,
pois meu inglês é meia boca… mas espero que tenham gostado e que tenha sido útil 😀

Anúncios

Parte 7 (Final) – Tutorial de Ajax no Struts 2 com Exemplo

Bem vindo a ultima parte de uma série de 7 artigos de tutoriais do Framework Struts2, no artigo anterior nós vimos como implementar a funcionalidade de carga de arquivo (File Upload) no Struts2. Neste artigo nós vamos ver como nós podemos implementar o suporte Ajax em uma aplicação web usando o framework struts2.

Suporte AJAX no Struts 2

O Struts 2 fornece  suporte embutido a Ajax usando a biblioteca Dojo Toolkit. Se você é novo em Dojo, talvez você queira passar pela Introdução ao DOJO Toolkit (Em Inglês).

O Struts 2 vem com um poderoso conjunto de APIs de Dojo AJAX que você pode usar para adicionar suporte Ajax. A fim de adicionar suporte Ajax, você precisa adicionar o seguinte arquivo JAR no seu classpath:
struts2-dojo-plugin.jar

Uma vez que nós adicionamos esse arquivo JAR, nós precisamos adicionar o seguinte fragmento de código em qualquer arquivo JSP que nós precisamos adicionar o suporte Ajax.

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

Primeiro defina a taglib sx que nós usaremos para adicionar as tags disponíveis de AJAX.

<sx:head/>

Adicione essa tag head no seu JSP entre as tags <head> … </head>. Essa tag sx:head incluirá os arquivos javascript e css necessários pra implementar o Ajax.

Exemplo AJAX: Ajax Drop Down (Combobox)  do Struts2

Vamos adicionar um simples suporte AJAX a nossa aplicação web StrutsHelloWorld. Nós usaremos o código base que nós usamos nos artigos anteriores e adicionar o Ajax no topo dele.

Nós criaremos um drop down (combobox) qual irá autocompletar e sugerir a entrada. Para isso nós iremos adicionar o suporte Dojo a nossa app web.

Passo 1: Adicionar o arquivo JAR

Como discutido anteriormente nós adicionaremos o struts2-dojo-plugin.jar no classpath (WEB-INF/lib). Assim, a seguinte é a lista dos arquivos JAR necessários. Observe que estes jars são necessários para rodar toda a aplicação, incluindo todos os exemplos das partes anteriores desta série de tutoriais.
struts2-ajax-jar-files

Passo 2: Criar a classe action do AJAX

Nós vamos criar uma classe action a qual irá ser chamada pelo nosso exemplo Ajax. Crie um arquivo AjaxAutocomplete.java no pacote net.viralpatel.struts2 e copie o seguinte conteúdo dentro dele.

AjaxAutocomplete.java

package net.viralpatel.struts2;

 

import java.util.ArrayList;

import java.util.List;

import java.util.StringTokenizer;

 

import com.opensymphony.xwork2.ActionSupport;

 

public class AjaxAutocomplete extends ActionSupport {

    private String data = "Afghanistan, Zimbabwe, India, United States, Germany, China, Israel";

    private List<String> countries;

    private String country;

    

    public String execute() {

        countries = new ArrayList<String>();

        StringTokenizer st = new StringTokenizer(data, ",");

 

        while (st.hasMoreTokens()) {

            countries.add(st.nextToken().trim());

        }

        return SUCCESS;

    }

    public String getCountry() {

        return this.country;

    }

 

    public List<String> getCountries() {

        return countries;

    }

 

    public void setCountries(List<String> countries) {

        this.countries = countries;

    }

    public void setCountry(String country) {

        this.country = country;

    }

}

No código acima nós criamos uma simples classe action com os atributos String country e List countries. A lista de países será populada com nomes de países quando o método execute() é chamado. Aqui por exemplo, nós carregamos dados estáticos. Você pode se sentir livre para mudar isso e adicionar dados do banco de dados.

Passo 3: Crie o JSP

Crie o arquivo JSP para exibir o Textbox com Autocomplete para nossa action Ajax. Crie AjaxDemo.jsp no diretório WebContent.

AjaxDemo.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

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

<html>

<head>

    <title>Welcome</title>

    <sx:head />

</head>

<body>

    <h2>Struts 2 Autocomplete (Drop down) Example!</h2>

    

    Country:

    <sx:autocompleter size="1" list="countries" name="country"></sx:autocompleter>

    </action>

</body>

</html>

No arquivo JSP acima nós usamos a tag sx:autocompleter para renderizar um drop down com autocomplete o qual utiliza a classe Ajax para buscar dados internamente. Veja que nós mapeamos o atributo list com List countries.

Passo 4: Criando a entrada no Struts.xml

Adicione a seguinte entrada de action no arquivo Struts.xml:

<action name="ajaxdemo" class="net.viralpatel.struts2.AjaxAutocomplete">

    <interceptor-ref name="loggingStack"></interceptor-ref>

    <result name="success" type="tiles">/ajaxdemo.tiles</result>

    <result type="tiles">/ajaxdemo.tiles</result>

</action>

Observe que nós estamos utilizando Tiles aqui neste exemplo. Você pode querer usar o AjaxDemo.jsp ao invés do /ajaxdemo.tiles para renderizar a saída diretamente em JSP.

Isso é tudo pessoal

Compile e rode a aplicação no eclipse
struts2-ajax-drop-down

Download do código fonte

Clicque aqui para fazer o download do código fonte sem os JARs (24KB)

Conclusão

O framework Struts2 fornece uma ampla variedade de recursos para criar uma rica aplicação web. Nessa série de Struts2 nós vimos diferentes aspectos do Struts2 como introdução ao struts2, aplicação hello world, framework de validação, plugin tiles, interceptadores do struts2, carga de arquivo e suporte a Ajax.

Fonte: viralpatel.net – Viral Patel

Parte 6 – Tutorial de Upload e Gravação de Arquivos do Struts 2 com Exemplo

Bem vindos a parte 6 de uma série de 7 partes do framework Struts2. Na parte anterior nós passamos pelo básico dos Interceptadores do Struts2. Também criamos um interceptador customizado e o integramos a aplicação Struts2.

É bastante recomendável passar pelos artigos anteriores no caso de você ser novo no framework Struts2.

Hoje vamos ver como fazer um Upload de Arquivos no Struts2. Nós vamos utilizar o interceptador FileUploadInterceptor que vem embutido no Struts2, no nosso exemplo para fazer o upload do arquivo. O interceptador de upload de arquivos do Struts2 é baseado no MultiPartRequestWrapper, o qual é automaticamente aplicado a requisição se ela contém um elemento de arquivo.

Arquivo JAR Necessário

Antes de começar, você precisa ter certeza que o arquivo commons-io.jar está presente no classpath. Segue a lista de arquivos JAR necessários.
struts2-file-upload-jar-files

Primeiros passos

A fim de adicionar a funcionalidade de upload de arquivos, nós vamos adicionar uma classe action FileUploadAction ao nosso projeto. Crie o arquivo FileUploadAction.java no pacote net.viralpatel.struts2
FileUploadAction.java

package net.viralpatel.struts2;

 

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;

import org.apache.struts2.interceptor.ServletRequestAware;

import com.opensymphony.xwork2.ActionSupport;

 

public class FileUploadAction extends ActionSupport implements

        ServletRequestAware {

    private File userImage;

    private String userImageContentType;

    private String userImageFileName;

 

    private HttpServletRequest servletRequest;

 

    public String execute() {

        try {

            String filePath = servletRequest.getSession().getServletContext().getRealPath(“/”);

            System.out.println("Server path:" + filePath);

            File fileToCreate = new File(filePath, this.userImageFileName);

 

            FileUtils.copyFile(this.userImage, fileToCreate);

        } catch (Exception e) {

            e.printStackTrace();

            addActionError(e.getMessage());

 

            return INPUT;

        }

        return SUCCESS;

    }

 

    public File getUserImage() {

        return userImage;

    }

 

    public void setUserImage(File userImage) {

        this.userImage = userImage;

    }

 

    public String getUserImageContentType() {

        return userImageContentType;

    }

 

    public void setUserImageContentType(String userImageContentType) {

        this.userImageContentType = userImageContentType;

    }

 

    public String getUserImageFileName() {

        return userImageFileName;

    }

 

    public void setUserImageFileName(String userImageFileName) {

        this.userImageFileName = userImageFileName;

    }

 

    @Override

    public void setServletRequest(HttpServletRequest servletRequest) {

        this.servletRequest = servletRequest;

 

    }

}

No arquivo da classe acima, nós declaramos alguns atributos:

  • private File userImage; -> Isso irá armazenar o arquivo carregado
  • private String userImageContentType; -> Essa string conterá o Content Type do arquivo carregado.
  • private String userImageFileName; -> Essa string irá conter o nome do arquivo carregado.

Os campos userImageContentType e userImageFileName são opcionais. Se o método setter desse campos for fornecido, o Struts2 irá setar o dado. Isso é apenas para pegar alguma informação extra do arquivo carregado. Segue também o padrão de nomeação, se você fornecer o tipo do conteúdo e o nome do arquivo. O nome deve ser ContentType e FileName. Por exemplo, se o atributo arquivo (File) na action for private File uploadedFile, o tipo do conteúdo será uploadedFileContentType e o nome do arquivo uploadedFileFileName.

Observe também na classe action acima, nós implementamos a interface org.apache.struts2.interceptor.ServletRequestAware. Isto é para pegar o objeto servletRequest. Nós estamos usando esse path para salvar o arquivo carregado no método execute(). Nós usamos o método FileUtil.copyFile() do pacote commons-io para copiar o arquivo carregado na pasta root. Esse arquivo será recuperado na página JSP e exibido ao usuário.

Os JSPs

Crie dois arquivos JSP na pasta WebContent. UserImage.jsp irá exibir um formulário para o usuário carregar a imagem. Ao submeter, o arquivo será carregado e salvo no servidor. O usuário será enviado ao arquivo SuccessUserImage.jsp aonde terá os detalhes do arquivo serão exibidos. Copie o seguinte código dentro dele.
UserImage.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<html>

<head>

<title>Upload User Image</title>

</head>

 

<body>

<h2>Struts2 File Upload & Save Example</h2>

<s:actionerror />

<s:form action="userImage" method="post" enctype="multipart/form-data">

    <s:file name="userImage" label="User Image" />

    <s:submit value="Upload" align="center" />

</s:form>

</body>

</html>

SuccessUserImage.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<html>

<head>

<title>Success: Upload User Image</title>

</head>

<body>

    <h2>Struts2 File Upload Example</h2>

    User Image: <s:property value="userImage"/>

    <br/>

    Content Type: <s:property value="userImageContentType"/>

    <br/>

    File Name: <s:property value="userImageFileName"/>

    <br/>

    Uploaded Image:

    <br/>

    <img src="<s:property value="userImageFileName"/>"/>

</body>

</html>

Entrada no Struts.xml

Adicione a seguinte entrada da classe FileUploadAction  ao arquivo struts.xml.

<action name="userImage"

    class="net.viralpatel.struts2.FileUploadAction">

    <interceptor-ref name="fileUpload">

        <param name="maximumSize">2097152</param>

        <param name="allowedTypes">

            image/png,image/gif,image/jpeg,image/pjpeg

        </param>

    </interceptor-ref>

    <interceptor-ref name="defaultStack"></interceptor-ref>

    <result name="success">SuccessUserImage.jsp</result>

    <result name="input">UserImage.jsp</result>

</action>

Observe que na entrada acima nós especificamos dois parâmetros ao interceptador fileUpload, maximumSize e allowedTypes. Estes são parâmetros opcionais que nós podemos especificar ao interceptador. O parâmetro maximumSize setará o tamanho máximo do arquivo que poderá ser carregado. Por padrão é 2MB. E o parâmetro allowedTypes especifica os tipos de conteúdos permitidos do arquivo que será carrregado. Aqui nós o especificamos para ser um arquivo de imagem (image/png,image/gif,image/jpeg,image/pjpeg).

O interceptador de carga de arquivo também faz a validação e adiciona erros, essas mensagens de erros são armazenadas dentro do arquivo struts-messsages.properties. Os valores das mensagens podem ser sobrescritos fornecendo texto/valor para as seguintes chaves:

  • struts.messages.error.uploading – erro quando a carga do arquivo falha
  • struts.messages.error.file.too.large – erro ocorrido quando o tamanho do arquivo é grande
  • struts.messages.error.content.type.not.allowed – quando o tipo do conteúdo não é permitido

Isso é tudo pessoal

Compile e execute o projeto no eclipse e vá ao link http://localhost:8080/StrutsHelloWorld/UserImage.jsp

Tela de carga de imagem
struts2-file-upload-example

Tela de carga de imagem no caso de erro
struts2-file-upload-error

Tela de carga de imagem em sucesso
struts2-file-upload-success

Download do código fonte

Clique aqui para fazer o download do código fonte sem os JARs (20KB)

Fonte: viralpatel.net – Viral Patel

Parte 5 – Tutorial de Interceptadores (Interceptors) do Struts2 com Exemplo

Sejam vem vindos a parte 5 de uma série de 7 partes aonde nós vamos examinar aspectos diferentes do framework Struts2. No artigo anterior nós vimos como integrar o framework Tile com o Struts2.

Hoje vamos explorer o mundo dos Interceptadores(Interceptors) no Struts2. Nós vamos ver o que os interceptadores são e como configura-los em uma aplicação web baseada em Struts2.

Interceptadores do Struts 2: Fundamentos

O Struts2 fornece um mecanismo poderoso para controlar uma requisição usando Interceptadores. Interceptadores são responsáveis pela maior parte do processamento de requisições. Eles são invocados pelo controller (controlador) antes e depois de invocar uma action, assim eles ficam entre o controller e a action. Interceptadores executam tarefas como Logging, Validation, File Upload, Double-submit guard e etc.
struts2 request processing lifecycle
O ciclo de vida de processamento do framework Struts2 é bastante discutido na parte 1 do tutorial.

  1. A requisição é gerada pelo usuário e enviada ao Servlet container.
  2. Servlet container invoca o filtro FilterDispatcher que por sua vez determina a ação apropriada.
  3. Um por um dos Intercetors são aplicados ante de chamar a Action. Interceptors executam tarefas como Logging, Validation, File Upload, Double-submit guard e etc.
  4. Action é executada e o Result é gerado pela Action.
  5. A saída da Action é renderizada na view (JSP, Velocity, etc) e o resultado é retornado ao usuário.

Portanto os interceptadores do Struts2 removem funções cross cutting como logging de componentes action e cria uma separação mais limpa do MVC.

O Struts2 vem com uma lista padrão de interceptadores já configurada na aplicação, no arquivo struts-default.xml. Nós podemos criar nossas próprios interceptadores e pluga-los dentro de uma aplicação web baseada em Struts2.

O framework cria um objeto de ActionInvocation que encapsula a action e todos os interceptadores configurados para aquela action. Cada interceptador é chamado antes da action ser chamada. Uma vez que a action é chamada e o resultado é gerado, cada interceptador é chamado de novo na ordem contrária para executar o trabalho de pós-processamento. Interceptadores podem alterar o workflow (fluxo de trabalho) da action. Isso talvez impessa a execução da action.

Nossa Meta

Nossa meta sera criar um interceptador customer MyLoggingInterceptor, o qual irá logar a requisição antes de qualquer action ser chamada. Ele também irá imprimir o nome da classe Action e o tempo de execução em milisegundos.

Criando o Interceptador de Log

Crie uma classe java MyLoggingInterceptor no pacote net.viralpatel.struts2.interceptors e copie o seguinte conteúdo dentro dela.
struts2-logging-interceptors

package net.viralpatel.struts2.interceptor;import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.Interceptor;

public class MyLoggingInterceptor implements Interceptor{

    private static final long serialVersionUID = 1L;

    public String intercept(ActionInvocation invocation) throws Exception {

        String className = invocation.getAction().getClass().getName();

        long startTime = System.currentTimeMillis();

        System.out.println("Before calling action: " + className);

        String result = invocation.invoke();

        long endTime = System.currentTimeMillis();

        System.out.println("After calling action: " + className

                + " Time taken: " + (endTime - startTime) + " ms");

        return result;

    }

    public void destroy() {

        System.out.println("Destroying MyLoggingInterceptor...");

    }

    public void init() {

        System.out.println("Initializing MyLoggingInterceptor...");

    }

}

Configurando o interceptador no struts.xml

Uma vez que nós criamos uma classe interceptadora, tudo o que precisamos fazer é configurar ela no arquivo struts.xml e usa-la com as actions.

Para configurar o interceptador criado há pouco, adicione o seguinte código dentro do struts.xml

<interceptors>    <interceptor name="mylogging"

        class="net.viralpatel.struts2.interceptor.MyLoggingInterceptor">

    </interceptor>

    <interceptor-stack name="loggingStack">

        <interceptor-ref name="mylogging" />

        <interceptor-ref name="defaultStack" />

    </interceptor-stack>

</interceptors>

Esse código deve ser adicionado depois da tag <result-types >  no <package ></package>. Aqui nós configuramos um novo interceptador mylogging com a tag <interceptor >. Também veja que nós definimos um interceptor-stack com o nome de loggingStack. Isso é para ter certeza de que o Struts2 chamará todos os interceptadores padrões assim como chamará o nosso interceptador customizado. Isso é muito importante como por exemplo a lógica de validação não será chamada na nossa aplicação Struts2 se nós ignorarmos o stack padrão (defaultStack) dos interceptadores.

Nós podemos fazer o novo loggingStack como interceptador padrão ou podemos configurar ele em cada nível de action. A fim de faze-lo um stack padrão, nós devemos adicionar o seguinte no struts.xml

<default-interceptor-ref name="loggingStack"></default-interceptor-ref>

Uma vez que nós adicionamos o código acima no Struts.xml, o logginStack será aplicado à todas as action daquele pacote.

Também nós talvez quiséssemos aplicar o interceptador customizado para apenas determinadas actions. Para fazer isso, nós precisamos adicionar a tag interceptor-ref na action.

<action name="login"    class="net.viralpatel.struts2.LoginAction">

    <interceptor-ref name="loggingStack"></interceptor-ref>

    <result name="success" type="tiles">/welcome.tiles</result>

    <result name="error">Login.jsp</result>

</action>

Isso é tudo pessoal

Se nós executarmos nossa aplicação StrutsHelloWorld no ecplipse e olharmos os logs do console, nós vamos encontrar as declarações de log que nós imprimimos no nosso interceptador.

Initializing MyLoggingInterceptor.....

..

..

Before calling action: net.viralpatel.struts2.LoginAction

..

..

After calling action: net.viralpatel.struts2.LoginAction Time taken: 313 ms

..

..

..

Destroying MyLoggingInterceptor...

Download do código fonte

Clique aqui para fazer o download do código fonte sem os JARs (17KB)

Fonte: viralpatel.net – Viral Patel

Parte 4 – Tutorial do Plugin Struts 2 Tiles com exemplo no Eclipse

Bem vindos à parte 4 de uma série de 7 partes, onde nós passaremos por diferentes aspectos do Framework Struts2 com alguns exemplos úteis. Na parte anterior nós passamos por Framework de validação do Struts2. Nós vimos como é fácil integrar validação na sua aplicação Struts2.

Nesta parte vamos discutir sobre o Framework Tile e a sua integração com Struts2. Nós vamos adicionar o suporte Tiles a nossa aplicação de Struts ‘HelloWorld’ que nós criamos anteriormente. Eu recomendo você passar pelos artigos anteriores e baixar o código fonte da nossa aplicação de exemplo.

Introdução ao Tiles 2

Atualmente, um website é geralmente dividido em pedaços de templates que são renderizados entre diferentes páginas web. Por exemplo, um site contendo um header (cabeçalho), footer (rodapé), menu e etc. Estes itens permanecem os mesmos por todo o site e dando  um visual padrão. Isso é muito difícil de codificar em cada página web e se depois uma modificação é necessária, então todas as páginas precisam ser modificadas. Por isso nós usamos o mecanismo de Templatization. Nós criamos uma página padrão de Header, Footer, Menu e etc., e a incluímos em cada página.

O plugin Tile premite ambos templating e componentização. De fato, ambos mecanismos são similates: você define partes da página (uma ‘Tile’/’Telha’) que você junta para construir outra parte ou uma página inteira. Uma parte pode receber parâmetros, permitindo um conteúdo dinâmico, e pode ser visto como um método na linguagem Java. Tiles é um sistema de templating usado para manter um visual consistente através de todas as páginas web de uma aplicação web. Isso aumenta a reusabilidade do template e reduz a duplicação de código.

Um layout comum de website é definido em um arquivo de configuração central e esse layout pode ser estendido através de todas as páginas web da aplicação.

Layout da nossa Aplicação

Nossa meta é adicionar um Header, Footer e Menu ao nossa aplicação StrutsHelloWorld.
Abaixo segue o layout da mesma.
struts2-tiles-layout

Arquivos JAR requeridos

A fim de adicionar o suporte Tiles a nossa aplicação Struts2, nós precisaremos de alguns arquivos JARs.
Abaixo segue a lista de JARs do nosso exemplo. Adicione estes JARs na pasta WEB-INF/lib.
struts2-tiles-jar-files

Configurando o Tiles no web.xml

Para configurar o Tiles, uma entrada  de listener tem que ser criada no web.xml. Abra o web.xml na pasta WEB-INF e adicione o seguinte código.

<listener>

    <listener-class>

        org.apache.struts2.tiles.StrutsTilesListener

    </listener-class>

</listener>

<context-param>

    <param-name>tilesDefinitions</param-name>

    <param-value>/WEB-INF/tiles.xml</param-value>

</context-param>

O código acima configure o listener do Tiles no web.xml. Um arquivo de configuração de entrada /WEB-INF/tiles.xml é passado como argumento. Este arquivo contém a definição do Tiles para sua aplicação web.

Crie um arquivo tiles.xml na pasta WEB-INF e copie o seguinte código dentro dele.
struts2-tiles-xml

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

 

<!DOCTYPE tiles-definitions PUBLIC

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

       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>

    <definition name="baseLayout" template="/BaseLayout.jsp">

        <put-attribute name="title" value="" />

        <put-attribute name="header" value="/Header.jsp" />

        <put-attribute name="menu" value="/Menu.jsp" />

        <put-attribute name="body" value="" />

        <put-attribute name="footer" value="/Footer.jsp" />

    </definition>

    <definition name="/welcome.tiles" extends="baseLayout">

        <put-attribute name="title" value="Welcome" />

        <put-attribute name="body" value="/Welcome.jsp" />

    </definition>

    <definition name="/customer.tiles" extends="baseLayout">

        <put-attribute name="title" value="Customer Form" />

        <put-attribute name="body" value="/Customer.jsp" />

    </definition>

    <definition name="/customer.success.tiles" extends="baseLayout">

        <put-attribute name="title" value="Customer Added" />

        <put-attribute name="body" value="/SuccessCustomer.jsp" />

    </definition>

</tiles-definitions>

Aqui no tile.xml nós temos que definir um template baseLayout. Este layout contém atributos como Header, Title, Body, Menu e Footer. O layout é depois estendido, e novas definições para as páginas Welcome e Customer são definidas. Nós temos que substituir o layout padrão e mudar o conteúdo de Body e Title.

Criando os JSPs

struts-2-tiles-layout-jsp

Nós definiremos o template para nossa aplicação web em uma arquivo JSP chamado BaseLayout.jsp. Este template irá conter diferentes segmentos da página (Header, Footer, Menu etc). Crie 4 novos arquivos JSP BaseLayout.jsp, Header.jsp, Menu.jsp and Footer.jsp e copie o seguinte conteúdo em cada um deles.

BaseLayout.jsp

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<!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=UTF-8">

<title><tiles:insertAttribute name="title" ignore="true" /></title>

</head>

<body>

<table border="1" cellpadding="2" cellspacing="2" align="center">

    <tr>

        <td height="30" colspan="2"><tiles:insertAttribute name="header" />

        </td>

    </tr>

    <tr>

        <td height="250"><tiles:insertAttribute name="menu" /></td>

        <td width="350"><tiles:insertAttribute name="body" /></td>

    </tr>

    <tr>

        <td height="30" colspan="2"><tiles:insertAttribute name="footer" />

        </td>

    </tr>

</table>

</body>

</html>

Header.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<h2>Struts2 Example - ViralPatel.net</h2>

Menu.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<s:a href="customer-form">Customer</s:a>

Footer.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

Copyright &copy; ViralPatel.net – Tradução SpigandoEAprendendo.wordpress.com

Modificações no Struts.xml

No struts.xml nós definimos a tag de resultado (result) que mapeia uma ação específica com uma página JSP. Agora nós modificaremos isso e mapearemos o resultado com Tiles. Abaixo segue o conteúdo do arquivo struts.xml.

<?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>

    <constant name="struts.enable.DynamicMethodInvocation"

        value="false" />

    <constant name="struts.devMode" value="false" />

    <constant name="struts.custom.i18n.resources"

        value="ApplicationResources" />

 

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

        <result-types>

            <result-type name="tiles"

                class="org.apache.struts2.views.tiles.TilesResult" />

        </result-types>

        <action name="login"

            class="net.viralpatel.struts2.LoginAction">

            <result name="success" type="tiles">/welcome.tiles</result>

            <result name="error">Login.jsp</result>

        </action>

        <action name="customer"

            class="net.viralpatel.struts2.CustomerAction">

            <result name="success" type="tiles">/customer.success.tiles</result>

            <result name="input" type="tiles">/customer.tiles</result>

        </action>

        <action name="customer-form">

            <result name="success" type="tiles">/customer.tiles</result>

        </action>

    </package>

</struts>

O struts.xml agora define um novo tipo de Resultado pelo Tiles. Esse tipo de resultado é usado na tag <result> para diferentes ações. Também observe que nós vamos definir uma nova ação customer-form. Esta é apenas uma declaração vazia para redirecionar o Usuario para página do formulário Customer quando ela clica no link Customer no menu.

É isso ai pessoal

Compile e execute a aplicação no Eclipse e veja que o header, menu e o footer estão apropriadamente aplicados.

Página de Boas Vindas com Tiles
struts-2-welcome-page-tiles

Página Customer com Tiles
struts2-tiles-customer-page

Página de Sucesso Customer com Tiles
struts2-customer-added-tiles

Download do código fonte:
Clique aqui para fazer o download do código fonte (sem os JARs) (11KB)

Fonte: viralpatel.net – Viral Patel

Parte 3 – Tutorial do Framework de validação do Struts2 com Exemplo

Seja bem vindo a parte 3 de uma série de 7 partes do tutorial aonde vamos passar por diferentes aspectos práticos do framework Struts2. Na última parte nós criamos uma Aplicação básica de Struts2 do zero. Eu recomendo fortemente que você passe pelos artigos anteriores no caso de você ser novo no Struts2.

Nesse artigo vamos aprender como alavancar o framework de validação do Struts2 em uma aplicação. Para isso utilizaremos a aplicação StrutsHelloWorld a qual nós criamos no artigo anterior como base e começaremos adicionando a lógica de validação a ele.

Introdução ao framework de validação do Struts2

A action do Struts2 depende de um framework de validação fornecido pela XWork para permitir a aplicação de regras de validação de entrada para nossa Action antes delas serem executadas. O framework de validação do Struts2 nos permite separar a lógica de validação do real código Java/JSP, onde isso pode ser revisado e facilmente modificado depois.

O framework de validação do Struts2 alivia muita das dores de cabeça associadas com  manipulação de validação de dado, permitindo você focar no código de validação e não no mecanismo de captura de dados e reexibição de dados incompletos ou inválidos.

O framework de validação vem com um conjunto de retinas úteis para manipular o formulário de validação automaticamente e isso pode tratar o formulário de validação de ambos os lados, servidor (Server Side) ou cliente (Client Side). Se determinada validação não está presente, você pode criar sua própria lógica de validação implementando a interface com.opensymphony.xwork2.Validator e plugá-la dentro do framework de validação como um componente reutilizável.

O validador usa arquivos de configuração XML para determinar quais rotinas de validação devem ser instaladas e quais delas devem ser aplicadas para uma determinada aplicação.O arquivo validators.xml contém todas as declarações dos validadores comuns. Se o arquivo validators.xml não estiver presente no classpath, um arquivo de validação padrão é carregado do path com/opensymphony/xwork2/validator/validators/default.xml.

O primeiro arquivo de configuração, declara as rotinas de validação que devem ser plugadas dentro do framework e fornece nomes lógicos para cada uma das validações. O arquivo validator-rules.xml também define o código JavaScript do lado cliente para cada rotina de validação. O validador pode ser configurado para enviar esse código JavaScript para o navegador então essas validações são realizadas tanto do lado cliente quanto do lado servidor.

Escopo dos Validadores (Validators Scope)

Temos 2 tipos de validadores na Validação do Struts2.

  1. Field Validators (Validação de Campos)
  2. Non-field validators (Validação de Não-Campos)

Field validators, como o nome indica, atua em um único campo acessível através de uma action. Um validador, em contrapartida, é mais genérico e pode fazer validações no contexto inteiro da action, invocando mais de um campo (ou até mesmo nenhum campo) na regra de validação. A maioria das validações podem ser definidas em forma de campo. Isso deve ter preferência sobre validação non-field sempre que possível, como mensagens de validação de campo são vinculados ao campo relacionado e será apresentado próximo ao elemento de entrada correspondente na view respectiva.

<validators>

  <field name="bar">

      <field-validator type="required">

          <message>You must enter a value for bar.</message>

      </field-validator>

  </field>

</validators>

Non-field validators apenas adiciona mensagens de nível de action. Validações non-field fornecida pela XWork é ExpressionValidator (Validador de Expressão).

<validators>

      <validator type="expression">

            <param name="expression">foo lt bar</param>

            <message>Foo must be greater than Bar.</message>

      </validator>

</validators>

Primeiros passos

Vamos adicionar a lógica de validação na aplicação StrutsHelloWorld que nós criamos no artigo anterior. Para esse tutorial, vamos criar uma classe Action chamada CustomerAction a qual conterá poucos campos. Crie um arquivo CustomerAction.java no pacote net.viralpatel.struts2.
customer-action-struts2

Copie o seguinte conteúdo dentro dele.

CustomerAction.java

package net.viralpatel.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class CustomerAction extends ActionSupport{

    private String name;

    private Integer age;

    private String email;

    private String telephone;

    public String addCustomer() {

        return SUCCESS;

    }

    

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public Integer getAge() {

        return age;

    }

    public void setAge(Integer age) {

        this.age = age;

    }

    public String getEmail() {

        return email;

    }

    public void setEmail(String email) {

        this.email = email;

    }

    public String getTelephone() {

        return telephone;

    }

    public void setTelephone(String telephone) {

        this.telephone = telephone;

    }

}

Observe que a classe CustomerAction tem os campos name, email, telephone e age. Também tem um método chamado addCustomer() o qual não tem nenhuma lógica, ele apenas retorna SUCCESS.

Agora nós vamos adicionar uma entrada para essa classe action no arquivo struts.xml. Abra o arquivo struts.xml o qual estará presente abaixo da pasta resources. E adicione o seguinte conteúdo entre as tags <package></package>.

<action name="customer"

    class="net.viralpatel.struts2.CustomerAction">

    <result name="success">SuccessCustomer.jsp</result>

    <result name="input">Customer.jsp</result>

</action>

Observe que nós estamos mapeando a classe CustomerAction com o nome customer. Também em sucesso o usuário será redirecionado a página SuccessCustomer.jsp. Repare que tem outra tag de resultado com nome input. Sempre que a lógica de validação encontra algum erro de validação, redireciona o usuário de volta a página especificada como input. Assim no nosso exemplo, o usuário será redirecionado de volta para Customer.jsp no caso de quaisquer erros.

Crie duas novas JSPs Customer.jsp (qual conterá o formulário do Customer) e SuccessCustomer.jsp (qual será mostrada em sucesso).
struts2-validation-jsp-files

Customer.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<html>

<head>

<title>Customer Form - Struts2 Demo | ViralPatel.net</title>

</head>

<body>

<h2>Customer Form</h2>

<s:form action="customer.action" method="post">

    <s:textfield name="name" key="name" size="20" />

    <s:textfield name="age" key="age" size="20" />

    <s:textfield name="email" key="email" size="20" />

    <s:textfield name="telephone" key="telephone" size="20" />

    <s:submit method="addCustomer" key="label.add.customer" align="center" />

</s:form>

</body>

</html>

SuccessCustomer.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<html>

<head>

<title>Customer Page - Struts2 Demo | ViralPatel.net</title>

</head>

<body>

    <h2>Customer Added Successfully.</h2>

</body>

</html>

Nós criamos o arquivo Customer.jsp qual irá exibir o formulário Customer. Mas nós não temos link para esta página na nossa aplicação web. Então nós criaremos um link para Customer.jsp da página Welcome.jsp. Abra a página Welcome.jsp e adicione o seguinte código de link dentro dela.

<s:a href="Customer.jsp">Add Customer</s:a>

Agora abra o arquivo ApplicationResources.properties da pasta resources e adicione as seguintes chaves/valores dentro dela.

name= Name

age= Age

email= Email

telephone= Telephone

label.add.customer=Add Customer

errors.invalid=${getText(fieldName)} is invalid.

errors.required=${getText(fieldName)} is required.

errors.number=${getText(fieldName)} must be a number.

errors.range=${getText(fieldName)} is not in the range ${min} and ${max}.

Execute o código no Eclipse e veja a saida. Você verá a página de login. Entre com username=admin e a senha=admin123 e faça o login. Na página de boas vindas você verá um link para página Add Customer. Clique naquele link e você verá a página Customer.
struts2-customer-form

Adicionando a lógica de validação

Agora nós terminamos o básico do formulário customer no qual nós vamos adicionar a lógica de validação. Seguem as regras de validações:

  1. Campo Name é obrigatório.
  2. Campo Age é obrigatório. Deve ser um número entre 1 e 100.
  3. Campo Email é obrigatório. Deve ser um endereço de email válido.
  4. Campo Telephone é obrigatório.

A fim de definir a lógica de validação para um formulário em particular, primeiro nós devemos criar um arquivo XML no qual manterá esse dado. O Struts2 define uma convenção de nomenclatura específica na definição dos arquivos XML de validação. O formato é <NomeDaClasseAction>-validation.xml. Então para nossa aplicação vamos criar um arquivo CustomerAction-validation.xml. Observe que este arquivo deve estar presente no mesmo pacote da classe action.
Crie o arquivo
CustomerAction-validation.xml no pacote net.viralpatel.struts2. E copie o seguinte conteúdo dentro dele.
struts2-validation-xml

CustomerAction-validation.xml

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"

    "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

<validators>

    <field name="name">

        <field-validator type="requiredstring">

            <param name="trim">true</param>

            <message key="errors.required" />

        </field-validator>

    </field>

    <field name="age">

        <field-validator type="required">

            <message key="errors.required" />

        </field-validator>

        <field-validator type="int">

            <param name="min">1</param>

            <param name="max">100</param>

            <message key="errors.range"/>

        </field-validator>

    </field>

    <field name="email">

        <field-validator type="requiredstring">

            <message key="errors.required" />

        </field-validator>

        <field-validator type="email">

            <message key="errors.invalid" />

        </field-validator>

    </field>

    <field name="telephone">

        <field-validator type="requiredstring">

            <message key="errors.required" />

        </field-validator>

    </field>

</validators>

E é isso. Nós apenas adicionamos a lógica de validação ao nosso exemplo. Veja que os arquivos XML de validação contém diferentes field-validators.

Validação do lado cliente

É muito fácil adicionar a validação do lado cliente ou validação JavaScript a qualquer formulário em Struts2. Tudo o que você precisa fazer é adicionar validate=”true” na tag form no seu arquivo JSP. Por exemplo abra o Customer.jsp e adicione validate=”true” na tag form. O Struts2 automaticamente gerará o código JavaScript para validação do lado cliente do formulário.

<s:form action="customer.action" method="post" validate="true">

    ...

</s:form>

Isso é tudo pessoal

Execute a aplicação e teste o formulário Customer com diferentes valores.

Página Customer

struts2-customer-form

Página Customer com erros
customer-page-validation-errors

Página Customer com sucesso
customer-page-success

Download do Código Fonte

Struts2_Validation_example.zip (3.6 MB)

Fonte: viralpatel.net – Viral Patel

Parte 2 – Tutorial: Criando uma aplicação Struts 2 no Eclipse

Sejam bem-vindos a parte 2 da série de 7 partes onde vamos explorar o mundo do framework Struts 2. No artigo anterior nós passamos pelo básico do Struts2, seu Diagrama de Arquitetura, ciclo de vida do processamento das requisições e uma breve comparação do Struts1 e Struts2. Se você não passou no nosso artigo anterior, eu altamente recomendo você fazer isso antes de botar a mão na massa hoje.

Coisa que nós precisamos

Antes de nós começarmos com nosso primeiro exemplo Hello World no Struts 2, nós vamos precisar de algumas ferramentas.

  1. JDK 1.5 ou acima (download)
  2. Tomcat 5.x ou acima ou qualquer outro container (Glassfish, JBoss, Websphere, Weblogic etc) (download)
  3. Eclipse 3.2.x ou acima (download)
  4. Arquivos JAR do Apache Struts2. Segue a lista dos arquivos JAR necessários para essa aplicação.
    • commons-logging-1.0.4.jar
    • freemarker-2.3.8.jar
    • ognl-2.6.11.jar
    • struts2-core-2.1.6.jar
    • xwork-2.1.2.jar

Observe que dependendo da versão utilizada do Struts2, o número da versão dos arquivos JAR acima podem mudar.

Nosso Objetivo

Nosso objetivo é criar uma aplicação básica de Struts2 com uma página de Login. O usuário entrará com a credencial de login(username e senha) e se for autenticado com sucesso ele será redirecionado à uma página de ‘Bem-Vindo’ na qual mostrará a mensagem ” Howdy, <username>…!“. Se o usuário não autenticar, ele será redirecionado de volta para página de login.
struts2-application-login-page

Primeiros Passos

Vamos começar com a nosa primeira aplicação baseada em Struts2.
Abra o Eclipse e vá em File -> New -> Project e selecione Dynamic Web Project na tela New Project.
Dynamic Web Project in Eclipse

Após selecionar Dynamic Web Project, pressione Next.
Eclipse Struts2 Project

Digite o nome do projeto. Por exemplo StrutsHelloWorld. Uma vez que fez isso, selecione o target runtime environment (ex.: Apache Tomcat v6.0). Isso é pra rodar o projeto dentro do ambiente do eclipse. Depois disso clique em Finish.

Uma vez que o projeto está criado, você pode ver essa estrutura no Project Explorer.
Eclipse Project Explorer: Struts2 Example

Agora copie todos os arquivos JAR requeridos no pasta WebContent -> WEB-INF -> lib. Crie essa pasta se ela não existir.
struts2-webinf-jars

Mapeamento o Struts2 no WEB.xml

Como discutido no artigo anterior, o ponto de entrada da aplicação Struts2 será definir o Filter no web.xml. Daqui nós definiremos uma entrada da classe org.apache.struts2.dispatcher.FilterDispatcher no web.xml.

Abra o arquivo web.xml que está abaixo da pasta WEB-INF e copie e cole o seguinte código.

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

<web-app id="WebApp_9" version="2.4"

    xmlns="http://java.sun.com/xml/ns/j2ee"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Struts2 Application</display-name>

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>

            org.apache.struts2.dispatcher.FilterDispatcher

        </filter-class>

    </filter>

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    <welcome-file-list>

        <welcome-file>Login.jsp</welcome-file>

    </welcome-file-list>

</web-app>

O código acima no web.xml mapeará o filtro do Struts2 com a url /*. O mapeamento padrão de url para aplicação struts2 será /*.action. Também observe que nós temos que definir Login.jsp como arquivo de boas-vindas.

Observação: O filtro FilterDispatcher está depreciado desde a versão 2.1.3 do  Struts. Se você está utilizando a última versão do Struts2 ( > 2.1.3) utilize a classe StrutsPrepareAndExecuteFilter em vez disso.

<filter>

    <filter-name>struts2</filter-name>

    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

</filter>

<filter-mapping>

    <filter-name>struts2</filter-name>

    <url-pattern>/*</url-pattern>

</filter-mapping>

A classe Action

Precisaremos de uma classe Action que irá autenticar nosso usuário e manterá o valor do username e da senha. Para isso vamos criar um pacote net.viralpatel.struts2 na pasta source. Esse pacote conterá o arquivo action.
struts2-source-package

Crie uma classe chamada LoginAction no pacote net.viralpatel.struts2 com o seguinte conteudo.

package net.viralpatel.struts2;

public class LoginAction {

    private String username;

    private String password;

    public String execute() {

        if (this.username.equals("admin") && this.password.equals("admin123")) {

            return "success";

        } else {

            return "error";

        }

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

}

Observe que, a classe action acima contém dois campos, username e senha qual manterá os valores do formulário e também contem o método execute() que autenticará o usuário. Neste simples exemplo, nós vamos checar se o username admin é e a senha é admin123.

Também observe que diferente da classe Action no Struts1, a classe Action do Struts2 é uma simples classe POJO com os atributos necessários e método.

O método execute() retorna um valor String qual irá determinar a página de resultado. Também, no Struts2 o nome do método não é fixo. Neste exemplo nós devemos definir o método execute(). Você pode querer definir um método authenticate() em vez disso.

O ResourceBundle

ResourceBundle é uma entidade Java muito útil que ajuda a colocar o conteúdo estático fora do arquivo fonte. A maioria das aplicações definem um arquivo resource bundle como ApplicationResources.properties o qual conterá mensagens estáticas como Username e Senha e inclui isso com a aplicação.

ResourceBundle se torna útil quando nós queremos adicionar suporte a internacionalização(I18N) a uma aplicação.

Nós definiremos um arquivo ApplicationResources.properties para nossa aplicação. Esse arquivo de propriedade deve estar presente na pasta WEB-INF/classes quando a fonte for compilada. Portanto criaremos uma pasta source chamada resources e colocar esse arquivo ApplicationResources.properties dentro dela.

Para criar uma pasta source, clique com o botão direito no seu projeto no Project Explorer e selecione New -> Source Folder.
struts2-resource-folder

Especifique o nome da pasta como resources e clique em Finish.

Crie um arquivo ApplicationResources.properties embaixo da pasta resources.
struts-2-application-resources-properties

Copie o sequinte conteúdo dentro do ApplicationResources.properties.

label.username= Username

label.password= Password

label.login= Login

O JSP

Nós vamos criar dois arquivos JSP para renderizar a saída ao usuário. Login.jsp será o ponto de partida da nossa aplicação, no qual conterá um simples formulário de login com username e senha. Em uma autenticação bem sucedida, o usuário será redirecionado à Welcome.jsp que irá mostrar uma simples mensagem de boas vindas.

Crie dois arquivos JSP Login.jsp e Welcome.jsp na pasta WebContent do seu projeto. Copie o seguinte conteúdo dentro deles.

Login.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<html>

<head>

<title>Struts 2 - Login Application | ViralPatel.net</title>

</head>

<body>

<h2>Struts 2 - Login Application</h2>

<s:actionerror />

<s:form action="login.action" method="post">

    <s:textfield name="username" key="label.username" size="20" />

    <s:password name="password" key="label.password" size="20" />

    <s:submit method="execute" key="label.login" align="center" />

</s:form>

</body>

</html>

Welcome.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

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

<html>

<head>

<title>Welcome</title>

</head>

<body>

    <h2>Howdy, <s:property value="username" />...!</h2>

</body>

</html>

Observe que nós usamos a tag <s:> do Struts 2 para renderizar as caixas de texto e labels. Struts2 vem com uma ponderosa biblioteca de tags embutida para renderizar elementos UI com mais eficiência.

O arquivo struts.xml

O Struts2 lê a configuração e a definição de classe de um arquivo XML chamado struts.xml. Esse arquivo é carregado do classpath do projeto. Nós definiremos o arquivo struts.xml na pasta resources. Crie o arquivo struts.xml na pasta resources.
struts2-struts-xml

Copie o seguinte conteúdo dentro do struts.xml.

<?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>

    <constant name="struts.enable.DynamicMethodInvocation"

        value="false" />

    <constant name="struts.devMode" value="false" />

    <constant name="struts.custom.i18n.resources"

        value="ApplicationResources" />

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

        <action name="login"

            class="net.viralpatel.struts2.LoginAction">

            <result name="success">Welcome.jsp</result>

            <result name="error">Login.jsp</result>

        </action>

    </package>

</struts>

Observe que no arquivo de configuração acima, nós temos definido a action Login da nossa aplicação. Dois result paths (caminhos de resultado) estão mapeados com LoginAction dependendo do resultado do método execute(. Se o método execute() retornar sucesso, o usuário será redirecionado para Welcome.jsp se não para Login.jsp.

Também observe que uma Constant é especificada com o nome struts.custom.i18n.resources. Essa constante especifica o arquivo resource bundle que nós criamos nos passos acima. Nós apenas precisamos especificar o nome do arquivo resource bundle sem a extensão (ApplicationResources sem o .properties).

Nosso LoginAction contém o método execute() o qual é o método padrão sendo chamado pelo Struts2. Se o nome do método é diferente, ex.: authenticate(); então devemos especificar o nome do método na tag <action>.

<action name="login" method="authenticate"

    class="net.viralpatel.struts2.LoginAction">

Quase pronto

A aplicação está quase pronta. Você talvez queira rodar a aplicação agora e ver o resultado você mesmo. Eu presumo que você já tenha configurado o Tomcat no eclipse.  Tudo que você precisa fazer:
Abrir a view de Server em Windows -> Show View -> Server. Botão direito nesta view e selecionar New -> Server e adicionar os detalhes do seu servidor.
Para rodar o projeto, botão direito no nome do projeto no Project Explorer e selecione Run as -> Run on Server (Atalho: Alt+Shift+X, R)

Mas ai tem um pequeno problema. Nossa aplicação roda perfeitamente bem até este ponto. Mas então o usuário entra com as credenciais erradas, ela será redirecionada para página de Login. Mas nenhuma mensagem de erro é mostrada. O usuário não sabe oque aconteceu. Uma boa aplicação sempre mostrará mensagens de erro apropriadas ao usuário. Então nós devemos mostrar uma mensagem de erro Invalid Username/Password. Please try again quando a autenticação do usuário falhar.

Toque final

Para adicionar essa funcionalidade, primeiro nós vamos adicionar a mensagem de erro no nosso arquivo ResourceBundle. Abra o ApplicationResources.properties e adicione uma entrada para error.login. O ApplicationResources.properties final parecerá como:

label.username= Username

label.password= Password

label.login= Login

error.login= Invalid Username/Password. Please try again.

Nós também precisamos adicionar lógica no LoginAction para adicionar a mensagem de erro se o usuário não autenticar. Mas ai nós temos um problema. Nossa mensagem de erro está especificada no arquivo ApplicationResources.properties. Nós precisamos especificar a chave error.login no LoginAction e a mensagem deverá aparecer na página JSP.

Para isso nós precisamos implementar a interface com.opensymphony.xwork2.TextProvider que fornece o método getText(). Esse método retorna um valor String do arquivo resource bundle. Nós precisamos apenas passar o valor chave como argumento para o método getText(). A interface TextProvider define vários métodos que nós precisamos implementar a fim de conseguir segurar o método getText(). Mas nós não queremos estragar o nosso código adicionando todos esses métodos que não temos a intenção de usar. Tem um bom jeito de lidar com este problema.

Struts2 vem com uma classe muito útil com.opensymphony.xwork2.ActionSupport. Nós precisamos estender nossa classe LoginAction com esta classe e diretamente usar métodos como o getText(), addActionErrors() e etc. Portanto nós iremos estender a classe LoginAction com a classe ActionSupport e adicionar a lógica para reportar o erro dentro dela. O código final do LoginAction deve se parecer com:

package net.viralpatel.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport {

    private String username;

    private String password;

    public String execute() {

        if (this.username.equals("admin")

                && this.password.equals("admin123")) {

            return "success";

        } else {

            addActionError(getText("error.login"));

            return "error";

        }

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

}

E é isso. Nossa primeira aplicação Hello World em Struts2 está pronta.

Isso é tudo pessoal

Execute a aplicação no eclipse e rode-o no seu navegador favorito.
Página de Login
struts2-application-login-page

Página de boas vindas
struts2-welcome-page

Página de Login com erro
struts2-login-page-error

Download do código fonte

Código fonte sem os arquivos JAR (9 KB)
Código fonte com os arquivos JAR (3 MB)

Fonte: viralpatel.net – Viral Patel

Parte 1 – Introdução ao Framework Struts 2

Então vamos começar a parte 1 de uma série de 7 partes, Nestes tutoriais nós vamos discutir a  Introdução ao Framework Struts2, framework de validação, os interceptadores no Struts2, plugin Tiles e essa aplicação com exemplo, um exemplo de upload de arquivo e exemplo de Ajax do Struts2.

Introdução ao Framework Struts 2

Apache Struts 2 é um framework elegante e extensível para criação de aplicações web em java. O framework é projetado para simplificar todo o ciclo de desenvolvimento, desde a construção, implantação, manutenção de aplicações ao longo do tempo.

Apache Struts2 foi originalmente conhecido como WebWork 2. Após trabalhar independentemente por vários anos, as comunidades WebWork e Struts juntaram forças para criar o Struts2. Essa nova versão do Struts é mais simples de usar e mais próximo de como o Struts sempre pretendia ser.

Struts 2 é um framework pull-MVC. Isto é, os dados que são mostrados ao usuáro tem que ser puxado da Action.

Struts2 suporta configurações baseadas em anotação que é mais fácil de criar e mais intuitiva. Classe action no Struts 2 atua como model na aplicação web. Ao contrário do Struts, a classe action do Struts 2 são simples objetos POJO assim slimplificando o teste do código. Struts2 também bem com poderosas APIs para configurar Interceptadores que reduzem muito o acoplamento na aplicação. A parte de view do Struts 2 é altamente configurável e suporta diferentes result-types como Velocity, FreeMarker, JSP e etc.

A Arquitetura do Struts 2

A Arquitetura do Struts 2 é baseado no framework WebWork 2. Isto influência as tecnologias JEE Standard como Java Filters, JavaBeans, ResourceBundles, Locales, XML etc nesta arquitetura.
Abaixo segue o diagram do framework.

struts 2 architecture
Imagem: struts.apache.org

  1. O ciclo de vida normal do struts começa quando a requisição é enviada pelo cliente. Isto resulta na invocação do servlet container que por sua vez é passa através da cadeia de filtros padrão.
  2. O filtro FilterDispatcher que é chamado consulta o ActionMapper para determinar  se uma  Action deveria ser invocada.
  3. Se o ActionMapper encontra uma Action a ser invocada, o FilterDispatcher delega controle ao ActionProxy.
  4. O ActionProxy lê o arquivo de configuração como o struts.xml. ActionProxy cria uma instancia da classe ActionInvocation e delega o controle.
  5. ActionInvocation é responsável pela implementação padrão de comando. Ela invoca os Interceptors(Interceptadores) um por um (se necessário) e então invoca a Action.
  6. Uma vez que a Action retorna, o ActionInvocation é responsável por procurar o resultado da propriedade associada com o código resultado da Action mapeada no struts.xml.
  7. Os Interceptors são executados de novo na ordem contrária e a resposta é retornada para o Filter (Na maioria dos casos ao FilterDispatcher). E o resultado é então enviado para o servlet container que por sua vez o envia de volta ao cliente.

Ciclo de vida do Processamento da Requisição


O ciclo de vida do processamento da requisição do framework Struts2 é bastante discutida na sessão acima, onde vimos a arquitetura do framework Struts 2.

  1. A requisição é gerada pelo usuário e enviada ao Servlet container.
  2. Servlet container invoca o filtro FilterDispatcher que por sua vez determina a ação apropriada.
  3. Um por um dos Intercetors são aplicados ante de chamar a Action. Interceptors executam tarefas como Logging, Validation, File Upload, Double-submit guard e etc.
  4. Action é executada e o Result é gerado pela Action.
  5. A saída da Action é renderizada na view (JSP, Velocity, etc) e o resultado é retornado ao usuário.

Suporte AJAX no Struts 2

AJAX é um termo bem conhecido no desenvolvimento web. Agora é possível escrever aplicações desktop como web2.0 usando AJAX. Até o Struts 1.x, o desenvolvedor tinha que escrever e manter o código em javascript para adicionar o suporte AJAX.
Mas agora o Struts 2 lhe dá o Ajax ‘for a da caixa’. Sem escrever javascript, sem debugar comparando vários browsers; apenas configure e vai.

Struts 2 vem com uma biblioteca de tags AJAX altamente configuráveis quais podem ser usada diretamente sem escrever código JavaScrip. Struts 2 também suporta biblioteca Dojo. Agora é muito fácil adicionar características de AJAX habilitado como o Autocomplete a sua aplicação web.
Relacionado: Introdução ao DOJO Toolkit (em inglês)

Comparação do Struts 1 e Struts 2

Vamos ver a diferença básica entre o framework Struts 1 e 2.

  1. Diferente do Struts 1, o Struts 2 não necessita de implementar a classe Action. A Action no Struts 2 é um objeto POJO. Assim fazendo isso ficar fácil para teste unitário do código.
  2. Actions  do Struts 1 são singletons e deve ser thread-safe uma vez que só terá apenas uma instancia de uma classe para manipular todas as requisições para aquela Action. Objetos action do Struts 2 são instanciados para cada requisição, então não tem problemas de thread-safety.
  3. As actions do Struts 1 tem dependências da servlet API desde que a HttpServletRequest e HttpServletResponse é passada ao método execute quando uma Action é invocada. As actions do Struts 2 não são acopladas a um container. Mais frequentemente os contextos de servlet são representadas como simples Maps, permitindo Actions serem testadas em isolamento.
  4. Struts 1 usa um objeto ActionForm para capturar a entrada. Como as Actions, todos ActionForms devem estender uma classe base. Uma vez que outro JavaBeans não pode ser usada como ActionForms, desenvolvedores criam mais classes redundantes para capturar as entradas. Struts 2 usa Action properties como input properties, eliminando a necessidade por um segundo objeto de entrada. Input properties podem ser tipos de objetos ricos quais podem ter suas próprias propriedades.
  5. Struts 1 integra com JSTL, assim utilizando o JSTL EL. O EL tem basic object graph traversal, mas é relativamente uma coleção fraca e suporte de propriedades indexado. Struts 2 pode utilizar JSTL, mas o framework também suporta uma linguagem de expressão (expression language) muito mais poderosa e flexível, chamada “Object Graph Notation Language” (OGNL).
  6. Struts 1 usa o mecanismo padrão JSP para fazer o binding (amarração) dos objeto dentro do contexto da página para acesso. Struts 2 usa um tecnologia “ValueStack” de modo que  as taglibs podem acessar valores sem acoplar sua view ao tipo do objeto que ela está renderizando.

Struts 1 suporta separar Request Processors (ciclos de vida) para cada módulo, mas todas as Actions no modulo necessitam compartilhar o mesmo ciclo de vida. Struts 2 suporta criar diferentes ciclos de vida em cada Action base via Interceptor Stacks. Custom stacks podem ser criadas e usada com diferentes Actions, conforme desejado.

—————————————————————-

Espero que tenham gostado dessa primeira parte, assim que possível postarei a parte 2 😀
See ya!

Fonte: viralpatel.net – Viral Patel