Arquivos de sites

jQuery – Sliding de elementos (Deslizar)

No capítulo anterior, nós vimos como nós podemos exibir ou esconder elementos  usando os métodos fading do jQuery. Porém, algumas vezes um efeito de sliding é uma melhor escolha, e para isso, o jquery tem um conjunto de métodos de combinação para fazer apenas isso. Vamos começar com um simples exemplo dele, onde nós usamos o método slideDown():

<div id="divTestArea1" style="padding: 50px; background-color: #89BC38; text-align: center; display: none;">
        <b>Hello, world!</b>
</div>
<a href="javascript:void(0);" onclick="ShowBox();">Show box</a>
<script type="text/javascript">
function ShowBox()
{
        $("#divTestArea1").slideDown();
}
</script>

Para esconder a caixa de novo, nós podemos usar o método slideUp(). Ambos recebem o mesmo conjunto de parâmetros, que são todos opcionais. O primeiro parâmetro permite você especificar a duração para o efeito em milissegundos, ou “fast” (rápido) ou “slow” (devagar), que são o mesmo se especificar ou 200 ou 600 milissegundos. Vamos tentar um exemplo onde nós fazemos apenas isso:

<div id="divTestArea21" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div>
<div id="divTestArea22" style="width: 50px; height: 50px; display: none; background-color: #C3D1DF;"></div>
<div id="divTestArea23" style="width: 50px; height: 50px; display: none; background-color: #9966FF;"></div>
<a href="javascript:void(0);" onclick="ShowBoxes();">Show boxes</a>
<script type="text/javascript">
function ShowBoxes()
{
        $("#divTestArea21").slideDown("fast");
        $("#divTestArea22").slideDown("slow");
        $("#divTestArea23").slideDown(2000);
}
</script>

Temos um pouco mais de HTML que o de costume, mas isso está lá apenas para você ser capaz de ver os andamentos diferentes que as caixas são mostradas. Observe como a primeira caixa aparece quase que instantaneamente, a segunda caixa é bem parecida e a terceira caixa é mais devagar, porque ela usou dois segundos inteiros para descer.

Agora, o segundo parâmetro pode ser oir o nome de uma  função de atenuação (que nós não vamos usar nesse tutorial) ou uma função de callback que você pode fornecer, para ser chamada uma vez que o efeito terminar. Aqui está um exemplo disso, combinado com o uso do método slideUp():

<div id="divTestArea3" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div>
<script type="text/javascript">
$(function()
{
        $("#divTestArea3").slideDown(2000, function()
        {
                $("#divTestArea3").slideUp(3000);
        });
});
</script>

A habilidade para fazer isso pode ser muito útil para combinar vários efeitos, com você pode ver. Neste exemplo, a função de callback que nós fornecemos será chamada assim que o método slideDown() estiver completamente finalizado e então o método slideUp() é chamado.

No caso de você querer simplificar o slide de um elemento para cima ou para baixo dependendo do seu estado atual, os desenvolvedores do jQuery forneceram a nós  um método legal slideToggle() para fazer apenas isso. Veja o próximo exemplo, onde nós usamos ele:

<div id="divTestArea4" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div><br />
<a href="javascript:void(0);" onclick="ToggleBox();">Toggle box</a>
<script type="text/javascript">
function ToggleBox()
{
        $("#divTestArea4").slideToggle("slow"); 
}
</script>

Fonte: jquery-tutorial.net

jQuery – Fading de elementos (Exibir/Esconder)

Fazer simples animação é muito fácil com jQuery. Um desses efeitos é o fading em um elemento, para exibí-lo ou escondê-lo. Aqui está um simples exemplo, onde nós exibimos uma caixa escondida, usando o método fadeIn():

<div id="divTestArea1" style="padding: 50px; background-color: #89BC38; text-align: center; display: none;">
        <b>Hello, world!</b>
</div>
<a href="javascript:void(0);" onclick="ShowBox();">Show box</a>
<script type="text/javascript">
function ShowBox()
{
        $("#divTestArea1").fadeIn();
}
</script>

Você pode dar um fade em um monte de elementos diferentes, como divs, spans ou links. O método fadeIn() pode receber três parâmetros. O primeiro permite você especificar a duração do efeito em milissegundos, ou “fast” (rápido) ou “slow” (devagar), que é o mesmo que especificar 200 ou 600 milissegundos. Aqui está um exemplo disso em uso:

<div id="divTestArea21" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div>
<div id="divTestArea22" style="width: 50px; height: 50px; display: none; background-color: #C3D1DF;"></div>
<div id="divTestArea23" style="width: 50px; height: 50px; display: none; background-color: #9966FF;"></div>
<a href="javascript:void(0);" onclick="ShowBoxes();">Show boxes</a>
<script type="text/javascript">
function ShowBoxes()
{
        $("#divTestArea21").fadeIn("fast");
        $("#divTestArea22").fadeIn("slow");
        $("#divTestArea23").fadeIn(2000);
}
</script>

Não se importe com todo o HTML, está lá apenas para que você possa ver a diferença entre as durações do fading. Agora, o segundo parâmetro pode ser o nome de uma função de atenuação (que nós não vamos usar nesse tutorial) ou uma função de callback que você pode fornecer, para ser chamada uma vez que o efeito terminar. Aqui está um exemplo disso, combinado com o uso do método fadeOut(), que obviamente tem o efeito reverso do fadeIn():

<div id="divTestArea3" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div>
<script type="text/javascript">
$(function()
{
        $("#divTestArea3").fadeIn(2000, function()
        {
                $("#divTestArea3").fadeOut(3000);
        });
});
</script>

Pode ter situações onde você quer esconder ou exibir um element dependendo do estado corrente do mesmo. Você poderia com certeza checar se ele está visível ou não, e então chamar ou fadeIn() ou fadeOut(), mas os desenvolvedores legais do jQuery tem nos fornecido um método específico para alternar (toggling) um elemento, chamado fadeToggle().  Ele leva os mesmo parâmetros como fadeIn() e fadeOut(), então ele é muito fácil de usar. Aqui está um pequeno exemplo:

<div id="divTestArea4" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div><br />
<a href="javascript:void(0);" onclick="ToggleBox();">Toggle box</a>
<script type="text/javascript">
function ToggleBox()
{
        $("#divTestArea4").fadeToggle("slow");  
}
</script>

E isso é quão fácil é usar os efeitos de fading do jQuery.

Fonte: jquery-tutorial.net

jQuery – Selectors relação Parent/child (Pai/filho)

O jQuery também permite você selecionar elementos baseado em seus elemento pai. Temos duas variações: Uma que vai apenas combinar elementos que tem um filho direto ao elemento pai, e um qual irá combinar todo o caminho através da hierarquia, ex.: um filho de um filho de um filho de um elemento pai.

A sintaxe para encontrar filhos que são descendentes direto de um elemento se parece com isso:

$(“div > a”)

Esse selector irá encontrar todos os links que são filho direto de um elemento div. Substituindo o símbolo de “maior que” por um simples espaço em branco irá mudar isso para combinar todos links dentro de um elemento div, não interessa se eles estão diretamente relacionados ou não:

$(“div a”)

Aqui está um exemplo onde nós colorimos tags bold de azul se elas são descendentes diretas da primeira área de teste:

<div id="divTestArea1">
        <b>Bold text</b>
        <i>Italic text</i>
        <div id="divTestArea2">
                <b>Bold text 2</b>
                <i>Italic text 2</i>
                <div>
                        <b>Bold text 3</b>
                </div>
        </div>
</div>
<script type="text/javascript">
$("#divTestArea1 > b").css("color", "blue");
</script>

Como você verá, apenas a primeira tag bold está colorida. Agora, se você usou a segunda abordagem, ambas tags bold deverão estar coloridas de azul. Tente o seguinte exemplo, onde a única coisa alterada foi o caractere “maior que” que foi substituído por um espaço em branco, observe que nós também aceitados descendentes não diretos ou “netos” assim eles são chamados algumas vezes:

<div id="divTestArea1">
        <b>Bold text</b>
        <i>Italic text</i>
        <div id="divTestArea2">
                <b>Bold text 2</b>
                <i>Italic text 2</i>
                <div>
                        <b>Bold text 3</b>
                </div>
        </div>
</div>
<script type="text/javascript">
$("#divTestArea1 b").css("color", "blue");
</script>

Agora a coisa legal é que você pode na verdade voltar a cima da hierarquia se necessário, usando o método parent().

Fonte: jquery-tutorial.net

jQuery – Introdução ao selectors (seletores) e Usando elementos, IDs e classes

Uma tarefa muito comum quando se está usando JavaScript, é ler e modificar o conteúdo da página. Para fazer isso, você precisa encontrar o(s) elemento(s) que você deseja modificar, e ai é onde o selector no jQuery ajudará você. Com o JavaScript normal, encontrar elementos pode ser extremamente pesado, ao menos que você precise encontrar um único elemento que tem um valor especificado no atributo ID. O jQuery pode ajudar você a encontrar elementos baseado em seus IDs, classes, tipos, atributos, valores de atributos e muito, muito mais. Ele é baseado no selectors do CSS e como você verá através desse tutorial, ele é extremamente poderoso. Quando usamos esse tipo de programa para fazer mudanças em seu site, é importante que você tenha autenticação de dois fatores (two factor authentication (em Inglês)) de modo que o seu site e computador não são compromissados.

Pela razão dessa ser uma tarefa tão comum, o construtor do jQuery vem em várias formas que recebem uma selector query como argumento (parâmetro), permitindo você localizar elementos com uma quantidade bastante limitada de código para uma eficiência ótima. Você pode instanciar o objeto jQuery simplesmente escrevendo jQuery() ou até mais curto usando o nome de atalho do jQuery: $().

Portanto, selecionar um conjunto de elementos é simples assim:

$(<query aqui>)

Com o objeto jQuery retornado, você pode então começar a usar e alterar os elementos que você encontrou.

Fonte

Usando elementos , IDs e classes

O selector #id

Um tipo de selector muito comum é o baseado em ID, que nós vimos no exemplo “Hello, world”. Ele usa o atributo ID de uma tag HTML para localizar o elemento desejado. Um ID deve ser único,então você deve apenas usar esse selectior quando você deseja localizar um único elemento. Para localizar um elemento com um ID específico, escreva um caractere hash (#), seguido pelo ID do elemento que você deseja localizar, assim:

$("#divTest")

Um exemplo disso em uso:

<div id="divTest"></div>
<script type="text/javascript">
$(function()
{
        $("#divTest").text("Test");
});
</script>

Agora, enquanto tiver apenas um único elemento que combina com a nossa query acima, você deve estar ciente que o resultado é uma lista, significando que isso pode conter mais de um elemento, se a query combina com mais de um. Um exemplo disso é combinar todos os elementos quais usam uma ou varias classes CSS.

O selector .class

Elementos com uma classe específica podem ser localizados escrevendo um caractere ponto (.) seguido pelo nome da classe. Aqui vai um exemplo:

<ul>
        <li>Test 1</li>
        <li>Test 2</li>
        <li>Test 3</li>
</ul>
<script type="text/javascript">
$(function()
{
        $(".bold").css("font-weight", "bold");
});
</script>

O selector element

Você também pode combinar baseado em elementos nos nomes das tags.

You can also match elements based on their tag names. Por exemplo, você pode combiner todos os links emu ma página assim:

$(“a”)

Ou todas as tags div assim:

$(“div”)

Se você usar um selector de multi-elemento (multi-element), como o selector de classe que nós usamos no exemplo anterior, e nó sabemos que nós estamos procurando por emento de um tipo específico, é uma boa prática especificar o tipo do elemento antes do selector. Não é apenas mais preciso, mas também é mais rápido para o jQuery processar, resultando em sites mais responsivos. Aqui vai uma versão reescrita do exemplo anterior, onde nós usamos esse método:

$("span.bold").css("font-weight", "bold");

Isso combinará todos os elementos span com “bold” como classe. Claro, isso pode ser usado com IDs e praticamente com todos os outros selector também.

Fonte: jquery-tutorial.net / jquery-tutorial.net

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 😀

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