Escolar Documentos
Profissional Documentos
Cultura Documentos
Struts 2
Principais Componentes
Controller
FilterDispatcher (Filtro baseado em Servlet)
Utilização padrão de projeto FrontController
R
Recebeb requisições
i i õ e iinvoca a ação
ã correspondente
d t
Necessário mapear URLs em ações
Ação é invocada pelo framework (Struts 2)
Model
Contém as Ações (Action) que serão executadas
Realiza a interface com o restante da aplicação (Regras de Negócio,
Persistência e Integrações)
Encaminha
E i h resultado
lt d para VIEW
View
Responsável pela produção da resposta à requisição
Traduz o estado da aplicação para uma representação onde é possível a
interação do usuário
Struts 2
Componentes
FilterDispatcher
Interceptors
ValueStack
Action
Result
ActionContext
OGNL
Struts 2
Componentes - Interceptors
São invocados tanto antes, quanto depois o processamento
da ação
pré-processamento
Utilizados no pré processamento do request e pós-
pós
processamento do response
Uma pilha dos mesmos está associada a cada ação
Realizam atividades complementares à ação, sem a
necessidade de acoplá-las à ação
Exemplo de uso
Logging
L i
Não é parte da ação, mas um requisito da aplicação
Conversão de Tipos
File Upload
Struts 2
Componentes - OGNL
Object-Graph Navigation Language
Linguagem de expressões que permite obter (get) e atualizar
(set) propriedades em objetos Java
Permite a manipulação de propriedades existentes na
ValueStack
Pode ser utilizada para associar dados de um formulário
HTML com Objetos existentes na ValueStack
Permite obter dados da ValueStack e rendizar os mesmos
em páginas JSP ou outros tipos de objetos Result
Struts
Componentes
Basicamente a
construção de uma
aplicação consiste em:
Configurar Framework
(Struts.xml)
Criar Ações (Action)
Preparar a maneira que
a resposta será exibida
(Template)
Struts 2
Setup Aplicação – Versão 2.2.3
Pastas e Arquivos
/AppName/META-INF/
/AppName/WEB-INF/
/AppName/WEB-INF/classes/struts.xml
/AppName/WEB-INF/lib/ Struts2 JARs + dependências
/AppName/WEB-INF/web.xml
Struts 2 Jars
ARQUIVO DESCRIÇÃO
struts2‐core‐2.2.3.1.jar Componente básico do Struts 2
XWork 2 é uma biblioteca utilizada pelo Struts2 (a partir da versão 2.0). Implementa um pattern baseado
xwork‐core‐2.2.3.1.jar
em um pattern de comandos
Implementação da Object Graph Navigation Language (OGNL). A linguagem de expressão utilizada pelo
ognl‐3.0.1.jar
framework
freemarker‐2.3.16.jar Responsável por todas as tags utilizada na camada de apresentação do Struts2
Utilizado de forma transparente pelo Struts2 para prover um mecanismo de logging que pode ser tanto o
commons‐logging‐1.1.1.jar
Log4J quanto o próprio JDK 1.4+
commons‐fileupload‐1.2.2.jar Biblioteca que permite adicionar a servlets e aplicações web capacidade de upload de arquivos.
commons‐io‐2.0.1.jar Biblioteca com várias funções utilitárias para o desenvolvimento de funcionalidades de IO
Biblioteca com funcionalidades adicionais para class no pacote java.lang principalmente relacionadas com
commons‐lang‐2.5.jar
manipulação de Strings entre outros
javassist‐3.11.0.GA.jar Javassist (Java Programming Assistant) permite a manipulação de bytecodes em tempo de execução
Struts 2
Struts.xml
Arquivo de Configuração Básica
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
http://struts.apache.org/dtds/struts 2.0.dtd >
Struts 2
Struts XML
Arquivo básico de configuração do framework
Deve residir no classpath da aplicação web. Normalmente em /WEB-
INF/classes
Estrutura
<struts>
<bean>
<constant>
<include>
<package>
<action>
<result>
</struts>
Struts 2
Struts XML - Constant
Exemplos de definição de constantes
Struts.xml
<struts>
/
<constant name="struts.devMode" value="true" />
</struts>
struts.properties
struts.devMode = true
web.xml
<web-app id="WebApp_9" version="2.4"
<filter>
<init-param>
<param-name>struts.devMode</param-name>
<param-value>true</param-value>
</init-param>
</filter>
</web-app>
Programação para Internet 222
Flávio de Oliveira Silva, M.Sc.
Struts 2
Struts XML - include
Permite a inclusão de um outro arquivo de configuração dentro do
arquivo struts.xml, modularizando a configuração
Desta forma é possível quebrar o arquivo em diferentes partes
Arquivo incluído deve possuir o mesmo formato do arquivo struts.xml,
inclusive com o elemento DOCTYPE
Arquivos podem estar em qualquer local do classpath e são
referenciados pelo atributo "file"
Exemplo
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
"htt // t t h /dtd / t t 2 0 dtd">
<struts>
<include file="Simple.xml"/>
<include file="/util/POJO.xml"/>
<include file="/com/initech/admin/admin-struts.xml"/>
</struts>
Programação para Internet 223
Flávio de Oliveira Silva, M.Sc.
Struts 2
Struts.xml - Package
O elemento package permite agrupar configurações que compartilham
atributos comuns como uma pilha de Interceptors ou mesmo um
namespace
extends="struts default">
<package name="default" extends="struts-default">
Atributos
name – nome único do pacote
extends – nome do do pacote que este pacote estenderá. Desta
forma todas as configurações estarão disponíveis para o pacote
No geral o deve estender o pacote "struts-default"
namespace – realiza um mapeamento da URL para o pacote
(namespace = "package1")
"/WebAppName/package1/actionName.action
abstract – Neste caso o pacote é apenas para efeito de configuração
não sendo possível acessar suas ações
<package name="struts-default" abstract="true">
</package name>
Programação para Internet 224
Flávio de Oliveira Silva, M.Sc.
Struts 2
Struts.xml - Package
O atributo name (nome do pacote) permite realizar uma organização
lógica da aplicação, dividindo as ações
Exemplo
bli – área
public á úbli d
pública it
do site
secure – área secura do site
O atributo namespace permite também organizar as ações, porém seu
nome interfere na URL mapeada para cada ação
Caso uma ação não seja encontrada em um namespace o nome da
mesma será procurado no pacote “default”
Nome no pacote na URL de uma ação
Struts 2
Struts.xml - Action
Define acão
<action name = "a" class = "className" method="">
<result name="resultName" type="resultType">
</result>
</action>
Exemplo
<action name="teste" class="br.com.company.action.TesteStruts">
<result name="SUCCESS">success.jsp</result>
<result name="FAIL">fail.jsp</result>
</action>
name – nome único de uma ação
ação. Será associado à URL
class – classe java responsável pelo comportamento associado à ação
method – método desta classe que será invocado pelo Struts2. Caso o
método não seja informado o Struts2 invocará o método:
public String execute()
String de retorno deste método será utilizada para selecionar o <result> adequado
Programação para Internet 226
Flávio de Oliveira Silva, M.Sc.
Action
Utilizando Wildcards
Permite a reutilização de ações baseados em caracteres
curinga
Nome da Ação contém caracteres curinga
Caracteres na ordem que são encontrados são substituídos dentro da
configuração .
Acesso é feito utilizando um par de chaves
<action name="*/*" method="{2}"
class="br.struts.app.actions.{1}Action">
<result type="redirect">/{1}/view.action</result>
<result name="view">/{1}/view.jsp</result>
<result name="input">/{1}/edit.jsp</result>
<result name="home">/{1}/home.jsp</result>
</action>
Result
Após a execução de uma ação, um resultado é selecionado.
O elemento <result> indica como será realizada a seleção de resultados
para uma determinada ação
Uma ação deve retornar uma String que será então utilizada para
selecionar o respectivo resultado
Atributos
name – indica o nome do resultado. Este valor deve ser retornado pelo
método invocado na classe Action a fim de que o resultado seja selecionado
type – indica o tipo de resultado que será utilizado. No geral o resultado
padrão é encaminhar o request para a página de template que será
responsável pela VIEW
No arquivo struts-default.xml, dentro do elemento <result-types> são definidos
vários <result-type> indicando a classe do Struts2 responsável pela associação
sendo que o default (true) é para o “dispatcher” que encaminha normalmente para
uma página JSP
Existem outros tipos que permitem diferentes comportamentos
O conteúdo do elemento indica a localização da página de resultado
Programação para Internet 228
Flávio de Oliveira Silva, M.Sc.
Result
Resultados Dinâmicos
Nem sempre o resultado de uma ação é conhecido em tempo de
configuração
Neste caso é possível utilizar o type “redirectAction” que permite
encaminhar uma ação para outra ação
Exemplo
<action name="wizard" class="br.ufu.facom.Wizard">
<result name="next" type="redirectAction">${nextAction}</result>
</action>
No exemplo o conteúdo do atributo “nextAction” da classe Wizard, que é
ajustado em tempo de execução é selecionado para o nome da ação
O atributo
t ib t é acessado
d através
t é da d OGNL
Result
RedirectAction – Outro Exemplo
Redirecionamento para outra ação com passagem de parâmetros
<action name="Login" class="br.package.LoginAction">
<result type="redirectAction">
<
<param " ti N "> tA ti </ >
name="actionName">nextAction</param>
<param name="namespace">/module/secure</param>
<param name="user">hardCodedValue</param>
<param name="passwd">${testProperty}</param>
</result>
</action>
Elementos <param> são responsáveis pela passagem de parâmetros
entre
t ações,
õ sendo
d possível
í l o uso d
da OGNL
"actionname" – nome da próxima ação que será chamada
"namespace" – namespace associado, à ação caso exista
Outros parâmetros podem ser informados no elemento <param> sendo que o
atributo é o nome do parâmetro a ser encaminhado e o valor é passado via
OGNL (${ForwardParamValue})
Programação para Internet 230
Flávio de Oliveira Silva, M.Sc.
Result
Redirect
Permite o redirecionamento para uma URL
<action name="SendToSearchEngine" class="br.package.MyAction">
<result type='redirect'>http://www.google.com</result>
</action>
Actions
Representa o comportamento que será executado a fim de responder um
determinado pedido
Realizam a transferência de dados entre o pedido e a VIEW
Representam o MODEL no MVC, visto que contém os dados a serem
exibidos na resposta
Realizam a conexão com outras camadas da aplicação (Serviços,
Persistência, Integração)
No Struts2 a o código da ação pode estar relacionado apenas com a
lógica da mesma
Uma estratégia comum é injetar um componente relacionado com esta
lógica de negócio e utilizá-lo dentro da ação
A cada request uma nova instância da ação relacionada é criada
Actions
As ações podem ser um simples POJO com um método que contém a
lógica da ação. Este método deve retornar uma string
public String actionMethod() throws Exception
public String execute()
Uma ação pode implementar a interface Action
(com.opensymphony.xwork2.Action) que basicamente:
Define o método execute()
String execute() throws Exception
Define a strings de retorno que podem ser utilizadas para selecionar o
resultado
public static final String ERROR "error"
public static final String INPUT "input"
public static final String LOGIN "login"
public static final String NONE "none"
public static final String SUCCESS "success"
Action
Transferência de Dados
A Action contém os dados que são obtidos a partir da VIEW e que podem
ser modificados durante o processamento para posterior apresentação
na mesma VIEW
Basicamente existem três formas de representar os dados na Action
Propriedades
Informações que estão no formulário de entrada e/ou saída são propriedades da
Classe Action
Classe Action é um POJO com os getters e setters para cada uma destas
propriedades
Objeto
Todas as informações que estão no formulário de entrada e/ou saída estão
encapsuladas
l d em um ú único
i objeto
bj t
Classe Action contém um método getter e outro setter para este objeto
Interface ModelDriven
Informações estão encapsuladas em um único Objeto
Objeto é instanciado pela Action e obtido pelo Método getModel()
Necessário que a Action implemente a interface ModelDriven
Programação para Internet 236
Flávio de Oliveira Silva, M.Sc.
Action - Transferência de Dados
Propriedades
Interceptor "params", presente da "defaulStack" é
responsável por realizar um setXXX para cada propriedade
Valores informados no request são associados a cada
propriedade e obtidos no request
Neste processo a conversão de String para o tipo da
propriedade é feito de forma transparente
Associação é feita pelo nome da propriedade utilizada tanto
na VIEW como na ACTION
Na VIEW os métodos getXXX são utilizados
Struts 2
Validação – struts-default.xml
No arquivo struts-default.xml o seguinte interceptor é definido
<interceptor name="workflow"
class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
Além disso a seguinte pilha de interceptors também é definida
<interceptor-stack name="defaultStack">
...
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*
</param>
</interceptor-ref>
...
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse
</param>
</interceptor-ref>
</interceptor-stack>
Programação para Internet 244
Flávio de Oliveira Silva, M.Sc.
Struts 2
Validação – struts-default.xml
A pilha de interceptors default é definida da seguinte forma:
<default-interceptor-ref name="defaultStack"/>
Desta forma, quando uma ação é invocada, de maneira padrão ocorre as
i t operações:
seguintes õ
Interceptor "params", é responsável por transferir os parâmetros enviados no
request para a ação. Transferência pode ser feita através de métodos setXXX
existentes na ação
Em um momento posterior interceptor "workflow" é invocado e o mesmo
chama o método validate() existente na ação
Método possui uma implementação padrão na classe ActionSupport
Este método é sobrecarregado na ação a fim de validar de forma específica os
dados
Em caso de erro o método informará o erro ocorrido
Caso ocorra algum erro durante a validação o interceptor "workflow" fará uma
alteração no fluxo do pedido enviando a requisição de volta para o formulário
de entrada de dados
Validação - Action
public class LoginAction extends ActionSupport {
...
@Override
public void validate() {
if ( getNewUser().getPassword().length() == 0 ){
addFieldError("password", "Password is required.");
}
if ( getNewUser().getName().length() == 0 ){
addFieldError( "name", "Username is required." );
}
}}
Definição da Ação Struts.xml – Necessário incluir o result "input"
</action>
<action name="login" class="br.course.contacts.web.LoginAction">
<result name="error">/errorContacts.jsp</result>
<result name="input">/index.jsp</result>
</action> Programação para Internet 246
Flávio de Oliveira Silva, M.Sc.
Validação – Action
Utilizando Resource Bundle
public class LoginAction extends ActionSupport {
...
@Override
public void validate() {
if ( getNewUser().getPassword().length() == 0 ){
addFieldError("password", getText("password.empty"));
}
if ( getNewUser().getName().length() == 0 ){
addFieldError( "name", getText("name.empty"));
}
}
}
Necessário arquivo NomeClasseAcao.properties (LoginAction.properties)
password.empty = Password is required.
name.empty=Username is required.
Struts 2
Interceptors
Struts 2 contém uma série de interceptadores padrão já configurados
A configuração padrão está configurada na basicStack
Struts 2
Interceptors
Exception
O primeiro a ser invocado no request e o último a ser invocado
durante o response
Permite capturar exceções e mapeá-las para páginas de erro
previamente definidas
Possível configurar mapeamentos Exceção x Resultado na
configuração
<global-results>
<result name="error">/Error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception"
result="error"/>
</global-exception-mappings>
Struts 2
Interceptors ServletConfig
Armazenamento de objetos na sessão pode ser feito com a interface
SessionAware em conjunto com o intercetor servletConfig
Ação deve implementar interface SessionAware
bli class
public l L i extends
Login t d A ti S
ActionSupportt
implements SessionAware {
//...
private Map session;
public void setSession(Map session) {
this.session = session;
}
}
Interceptor é responsável por invocar o método setSession e então
passar o mapa de objetos para a ação
Alterações no objeto são refletidas na sessão pois o objeto é uma
referência para a mesma
Programação para Internet 252
Flávio de Oliveira Silva, M.Sc.
Struts 2
Interceptors - Mapeamento
Mapeamento em uma Ação
<action name="Action" class="org.comp.actions.MyAction">
<interceptor-ref name="timer"/>
<interceptor-ref
<interceptor ref name="logger"/>
name logger />
<result>Success.jsp</result>
</action>
Apenas os dois interceptadores serão chamados
Mapamento em uma Ação utilizando uma pilha já definida
<action name="Action" class="org.comp.actions.MyAction">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
<interceptor-ref name="defaultStack"/>
<result>Success.jsp</result>
</action>
Inicialmente os interceptores serão invocados e depois a pilha defaultStack
Struts2
Integração com Hibernate
Existem várias estratégias para integração do Hibernate com o Strutus
No geral o problema reside em como obter uma sessão (Session) do
Hibernate
Algumas Estratégias
Extender o FilterDispatcher para que crie a sessão com o Hibernate
Utilizar Spring para criação dos objetos
Obter a sessão na classe responsável pelo DAO
O método mais simples é obter a sessão dentro da classe DAO
Classe que contém uma única instância da SessionFactory e é responsável
por devolver a sessão
Classe HibernateSessionFactory
DAO
Será criado utilizando objetos do Hibernate
Utilizará a classe HibernateSessionFactory
Action
Conterá uma instância da classe DAO baseada no Hibernate
Programação para Internet 254
Flávio de Oliveira Silva, M.Sc.
Hibernate Session Factory
package br.ufu.facom.model.util;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import
p org.hibernate.Session;
g
public class HibernateSessionFactory{
private static final SessionFactory sessionFac = buildSessionFactory();
private static SessionFactory buildSessionFactory()
try {
sessionFac = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
System.err.println("Failed to create SessionFactory. " + ex);
throw new Exception(ex);
}
}
public static Session getSession() {
return sessionFac.openSession();
}
}
Programação para Internet 255
Flávio de Oliveira Silva, M.Sc.
ActionContextCleanUp
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</filter mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>