Struts 2 - Interceptores

Os interceptores são conceitualmente iguais aos filtros de servlet ou à classe JDKs Proxy. Os interceptores permitem que a funcionalidade de crosscutting seja implementada separadamente da ação e também da estrutura. Você pode conseguir o seguinte usando interceptores -

  • Fornecer lógica de pré-processamento antes que a ação seja chamada.

  • Fornecendo lógica de pós-processamento após a ação ser chamada.

  • Captura de exceções para que o processamento alternativo possa ser executado.

Muitos dos recursos fornecidos no Struts2 framework são implementados usando interceptores;

Examples incluem manipulação de exceção, upload de arquivo, callbacks de ciclo de vida, etc. Na verdade, como Struts2 enfatiza muito de sua funcionalidade em interceptores, não é provável que tenha 7 ou 8 interceptores atribuídos por ação.

Struts2 Framework Interceptors

O framework Struts 2 fornece uma boa lista de interceptores prontos para uso que vêm pré-configurados e prontos para uso. Alguns dos interceptores importantes estão listados abaixo -

Sr. Não Interceptador e descrição
1

alias

Permite que os parâmetros tenham nomes alternativos diferentes nas solicitações.

2

checkbox

Auxilia no gerenciamento de caixas de seleção, adicionando um valor de parâmetro false para caixas de seleção que não estão marcadas.

3

conversionError

Coloca informações de erro de conversão de strings em tipos de parâmetro nos erros de campo da ação.

4

createSession

Cria automaticamente uma sessão HTTP, se ainda não houver uma.

5

debugging

Fornece várias telas de depuração diferentes para o desenvolvedor.

6

execAndWait

Envia o usuário para uma página de espera intermediária enquanto a ação é executada em segundo plano.

7

exception

Mapeia exceções que são lançadas de uma ação para um resultado, permitindo o tratamento automático de exceções por meio de redirecionamento.

8

fileUpload

Facilita o envio de arquivos fácil.

9

i18n

Mantém o controle do local selecionado durante a sessão de um usuário.

10

logger

Fornece registro simples, exibindo o nome da ação que está sendo executada.

11

params

Define os parâmetros de solicitação na ação.

12

prepare

Isso normalmente é usado para fazer o trabalho de pré-processamento, como configurar conexões de banco de dados.

13

profile

Permite que informações simples de criação de perfil sejam registradas para ações.

14

scope

Armazena e recupera o estado da ação no escopo da sessão ou do aplicativo.

15

ServletConfig

Fornece à ação acesso a várias informações baseadas em servlet.

16

timer

Fornece informações simples de criação de perfil na forma de quanto tempo a ação leva para ser executada.

17

token

Verifica a ação de um token válido para evitar o envio duplicado de formulários.

18

validation

Fornece suporte de validação para ações

Consulte a documentação do Struts 2 para obter detalhes completos sobre os interceptores mencionados acima. Mas vou mostrar como usar um interceptor em geral em seu aplicativo Struts.

Como usar interceptores?

Vamos ver como usar um interceptor já existente para nosso programa "Hello World". Vamos usar otimerinterceptor cujo objetivo é medir quanto tempo leva para executar um método de ação. Ao mesmo tempo, estou usandoparamsinterceptor cujo objetivo é enviar os parâmetros do pedido para a ação. Você pode tentar o seu exemplo sem usar este interceptor e você vai descobrir quename a propriedade não está sendo definida porque o parâmetro não pode alcançar a ação.

Manteremos os arquivos HelloWorldAction.java, web.xml, HelloWorld.jsp e index.jsp como foram criados em Examples capítulo, mas vamos modificar o struts.xml arquivo para adicionar um interceptor da seguinte forma -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "struts.devMode" value = "true" />
   
   <package name = "helloworld" extends = "struts-default">
      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction"
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "timer" />
         <result name = "success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

Clique com o botão direito no nome do projeto e clique em Export > WAR Filepara criar um arquivo de guerra. Em seguida, implante esse WAR no diretório webapps do Tomcat. Finalmente, inicie o servidor Tomcat e tente acessar o URLhttp://localhost:8080/HelloWorldStruts2/index.jsp. Isso produzirá a seguinte tela -

Agora insira qualquer palavra na caixa de texto fornecida e clique no botão Diga Olá para executar a ação definida. Agora, se você verificar o log gerado, encontrará o seguinte texto -

INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM 
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

Aqui o resultado final está sendo gerado por causa de timer interceptador que está dizendo que a ação levou um total de 109 ms para ser executada.

Crie interceptores personalizados

Usar interceptores customizados em seu aplicativo é uma maneira elegante de fornecer recursos de aplicativo transversais. Criar um interceptor customizado é fácil; a interface que precisa ser estendida é a seguinteInterceptor interface -

public interface Interceptor extends Serializable {
   void destroy();
   void init();
   String intercept(ActionInvocation invocation)
   throws Exception;
}

Como os nomes sugerem, o método init () fornece uma maneira de inicializar o interceptor e o método destroy () fornece um recurso para limpeza do interceptor. Ao contrário das ações, os interceptores são reutilizados nas solicitações e precisam ser threadsafe, especialmente o método intercept ().

o ActionInvocationobjeto fornece acesso ao ambiente de tempo de execução. Ele permite o acesso à própria ação e métodos para invocar a ação e determinar se a ação já foi invocada.

Se você não precisa de código de inicialização ou limpeza, o AbstractInterceptorclasse pode ser estendida. Isso fornece uma implementação padrão nooperation dos métodos init () e destroy ().

Criar classe de interceptador

Vamos criar o seguinte MyInterceptor.java em Java Resources > src pasta -

package com.tutorialspoint.struts2;

import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

   public String intercept(ActionInvocation invocation)throws Exception {

      /* let us do some pre-processing */
      String output = "Pre-Processing"; 
      System.out.println(output);

      /* let us call action or next interceptor */
      String result = invocation.invoke();

      /* let us do some post-processing */
      output = "Post-Processing"; 
      System.out.println(output);

      return result;
   }
}

Como você pode notar, a ação real será executada usando o interceptor por invocation.invoke()ligar. Portanto, você pode fazer algum pré-processamento e pós-processamento com base em seus requisitos.

A própria estrutura inicia o processo fazendo a primeira chamada para invoke () do objeto ActionInvocation. Cada vezinvoke()for chamado, ActionInvocation consulta seu estado e executa qualquer interceptor que vier a seguir. Quando todos os interceptores configurados forem chamados, o método invoke () fará com que a própria ação seja executada.

O diagrama a seguir mostra o mesmo conceito por meio de um fluxo de solicitação -

Criar classe de ação

Vamos criar um arquivo java HelloWorldAction.java em Java Resources > src com um nome de pacote com.tutorialspoint.struts2 com o conteúdo fornecido abaixo.

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
   private String name;

   public String execute() throws Exception {
      System.out.println("Inside action....");
      return "success";
   }  

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

Esta é a mesma classe que vimos nos exemplos anteriores. Temos métodos getters e setter padrão para a propriedade "name" e um método execute que retorna a string "success".

Criar uma vista

Vamos criar o arquivo jsp abaixo HelloWorld.jsp na pasta WebContent em seu projeto eclipse.

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      Hello World, <s:property value = "name"/>
   </body>
</html>

Criar página principal

Também precisamos criar index.jspna pasta WebContent. Este arquivo servirá como a URL de ação inicial onde um usuário pode clicar para dizer à estrutura do Struts 2 para chamar um método definido da classe HelloWorldAction e renderizar a visualização HelloWorld.jsp.

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

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      <h1>Hello World From Struts2</h1>
      <form action = "hello">
         <label for = "name">Please enter your name</label><br/>
         <input type = "text" name = "name"/>
         <input type = "submit" value = "Say Hello"/>
      </form>
   </body>
</html>

o hello a ação definida no arquivo de visualização acima será mapeada para a classe HelloWorldAction e seu método de execução usando o arquivo struts.xml.

Arquivos de configuração

Agora, precisamos registrar nosso interceptor e chamá-lo como havíamos chamado o interceptor padrão no exemplo anterior. Para registrar um interceptor recém-definido, as tags <interceptors> ... </interceptors> são colocadas diretamente sob a tag <package>.struts.xmlArquivo. Você pode pular esta etapa para interceptores padrão, como fizemos em nosso exemplo anterior. Mas aqui vamos nos registrar e usá-lo da seguinte maneira -

<?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.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">

      <interceptors>
         <interceptor name = "myinterceptor"
            class = "com.tutorialspoint.struts2.MyInterceptor" />
      </interceptors>

      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction" 
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "myinterceptor" />
         <result name = "success">/HelloWorld.jsp</result>
      </action>

   </package>
</struts>

Deve-se notar que você pode registrar mais de um interceptador dentro <package> tag e ao mesmo tempo, você pode chamar mais de um interceptor dentro do <action>tag. Você pode chamar o mesmo interceptor com as diferentes ações.

O arquivo web.xml precisa ser criado na pasta WEB-INF em WebContent da seguinte forma -

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">
   
   <display-name>Struts 2</display-name>
   
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   
   <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>
</web-app>

Clique com o botão direito no nome do projeto e clique em Export > WAR Filepara criar um arquivo de guerra. Em seguida, implante esse WAR no diretório webapps do Tomcat. Finalmente, inicie o servidor Tomcat e tente acessar o URLhttp://localhost:8080/HelloWorldStruts2/index.jsp. Isso produzirá a seguinte tela -

Agora insira qualquer palavra na caixa de texto fornecida e clique no botão Diga Olá para executar a ação definida. Agora, se você verificar o log gerado, encontrará o seguinte texto na parte inferior -

Pre-Processing
Inside action....
Post-Processing

Empilhando vários interceptores

Como você pode imaginar, ter que configurar vários interceptores para cada ação rapidamente se tornaria extremamente incontrolável. Por esse motivo, os interceptores são gerenciados com pilhas de interceptores. Aqui está um exemplo, diretamente do arquivo strutsdefault.xml -

<interceptor-stack name = "basicStack">
   <interceptor-ref name = "exception"/>
   <interceptor-ref name = "servlet-config"/>
   <interceptor-ref name = "prepare"/>
   <interceptor-ref name = "checkbox"/>
   <interceptor-ref name = "params"/>
   <interceptor-ref name = "conversionError"/>
</interceptor-stack>

A aposta acima é chamada basicStacke pode ser usado em sua configuração conforme mostrado abaixo. Este nó de configuração é colocado no nó <pacote ... />. Cada tag <interceptor-ref ... /> faz referência a um interceptor ou a uma pilha de interceptor que foi configurada antes da pilha de interceptor atual. Portanto, é muito importante garantir que o nome seja exclusivo em todas as configurações de pilha de interceptores e interceptores ao configurar os interceptores iniciais e as pilhas de interceptores.

Já vimos como aplicar interceptor à ação, aplicando pilhas de interceptores não é diferente. Na verdade, usamos exatamente a mesma tag -

<action name = "hello" class = "com.tutorialspoint.struts2.MyAction">
   <interceptor-ref name = "basicStack"/>
   <result>view.jsp</result>
</action

O registro acima de "basicStack" registrará a aposta completa de todos os seis interceptores com ação hello. Deve-se observar que os interceptores são executados na ordem em que foram configurados. Por exemplo, no caso acima, a exceção será executada primeiro, a segunda seria servlet-config e assim por diante.