Struts2 é uma estrutura de aplicativo da web popular e madura baseada no padrão de design MVC. Struts2 não é apenas a próxima versão do Struts 1, mas é uma reescrita completa da arquitetura do Struts.

Aqui estão alguns dos excelentes recursos que podem forçá-lo a considerar o Struts2 -

  • POJO forms and POJO actions- O Struts2 eliminou os Formulários de Ação que eram parte integrante da estrutura do Struts. Com o Struts2, você pode usar qualquer POJO para receber a entrada do formulário. Da mesma forma, agora você pode ver qualquer POJO como uma classe Action.

  • Tag support - Struts2 melhorou as tags de formulário e as novas tags permitem que os desenvolvedores escrevam menos código.

  • AJAX support - O Struts2 reconheceu o controle das tecnologias Web2.0 e integrou o suporte AJAX ao produto, criando tags AJAX, que funcionam de maneira muito semelhante às tags Struts2 padrão.

  • Easy Integration - Integração com outras estruturas como Spring, Tiles e SiteMesh agora é mais fácil com uma variedade de integração disponível com Struts2.

  • Template Support - Suporte para geração de visualizações usando modelos.

  • Plugin Support- O comportamento principal do Struts2 pode ser aprimorado e aumentado pelo uso de plug-ins. Vários plug-ins estão disponíveis para Struts2.

O padrão Model-View-Controller no Struts2 é realizado com os seguintes cinco componentes principais -

  • Actions

  • Interceptors

  • Pilha de valores / OGNL

  • Resultados / tipos de resultados

  • Ver tecnologias

A seguir está o ciclo de vida de uma solicitação no aplicativo Struct2 -

  • O usuário envia uma solicitação ao servidor para solicitar algum recurso (ou seja, páginas).

  • O FilterDispatcher examina a solicitação e, em seguida, determina a ação apropriada.

  • Funcionalidades de interceptores configurados se aplicam como validação, upload de arquivo etc.

  • A ação selecionada é executada para realizar a operação solicitada.

  • Novamente, os interceptores configurados são aplicados para fazer qualquer pós-processamento, se necessário.

  • Finalmente, o resultado é preparado pela visualização e retorna o resultado ao usuário.

O arquivo struts.xml contém as informações de configuração que você modificará conforme as ações são desenvolvidas. Este arquivo pode ser usado para substituir as configurações padrão de um aplicativo, por exemplo struts.devMode = false e outras configurações que são definidas no arquivo de propriedades. Este arquivo pode ser criado na pasta WEB-INF / classes.

A tag constante junto com os atributos de nome e valor serão usados ​​para substituir qualquer uma das seguintes propriedades definidas em default.properties, como acabamos de definir a propriedade struts.devMode. Definir a propriedade struts.devMode nos permite ver mais mensagens de depuração no arquivo de log.

Definimos as tags de ação correspondentes a cada URL que desejamos acessar e definimos uma classe com o método execute () que será acessada sempre que acessarmos a URL correspondente.

Os resultados determinam o que é retornado ao navegador depois que uma ação é executada. A string retornada da ação deve ser o nome de um resultado. Os resultados são configurados por ação conforme acima, ou como um resultado "global", disponível para cada ação em um pacote. Os resultados possuem atributos opcionais de nome e tipo. O valor do nome padrão é "sucesso".

O arquivo de configuração struts-config.xml é um link entre os componentes View e Model no Web Client.

É aqui que você mapeia sua subclasse ActionForm para um nome. Você usa esse nome como um alias para seu ActionForm em todo o restante do arquivo struts-config.xml e até mesmo em suas páginas JSP.

Esta seção mapeia uma página em seu webapp para um nome. Você pode usar este nome para se referir à página real. Isso evita a codificação de URLs em suas páginas da web.

É aqui que você declara os manipuladores de formulário e eles também são conhecidos como mapeamentos de ação.

Esta seção informa ao Struts onde encontrar seus arquivos de propriedades, que contêm prompts e mensagens de erro.

Este arquivo de configuração fornece um mecanismo para alterar o comportamento padrão da estrutura. Na verdade, todas as propriedades contidas no arquivo de configuração struts.properties também podem ser configuradas no web.xml usando o init-param, bem como usando a tag constante no arquivo de configuração struts.xml. Mas se você gosta de manter as coisas separadas e mais específicas, você pode criar este arquivo na pasta WEB-INF / classes. Os valores configurados neste arquivo substituirão os valores padrão configurados em default.properties que estão contidos na distribuição struts2-core-xyzjar.

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.

Criar um interceptor customizado é fácil; a interface que precisa ser estendida é a interface do Interceptor.

A ação real será executada usando o interceptor pela chamada invocation.invoke (). Portanto, você pode fazer algum pré-processamento e pós-processamento com base em sua necessidade.

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

A classe Action gerencia o estado do aplicativo e o Result Type gerencia a visualização.

O tipo de resultado padrão é dispatcher, que é usado para despachar para páginas JSP.

O tipo de resultado do dispatcher é o tipo padrão e é usado se nenhum outro tipo de resultado for especificado. É usado para encaminhar para um servlet, JSP, página HTML e assim por diante, no servidor. Ele usa o método RequestDispatcher.forward ().

O tipo de resultado de redirecionamento chama o método padrão response.sendRedirect (), fazendo com que o navegador crie uma nova solicitação para o local fornecido. Podemos fornecer a localização no corpo do elemento <result ...> ou como um elemento <param name = "location">.

A pilha de valores é um conjunto de vários objetos que mantém os seguintes objetos na ordem fornecida -

  • Temporary Objects- Existem vários objetos temporários que são criados durante a execução de uma página. Por exemplo, o valor de iteração atual para uma coleção que está sendo repetida em uma tag JSP.

  • The Model Object - Se você estiver usando objetos de modelo em seu aplicativo struts, o objeto de modelo atual é colocado antes da ação na pilha de valores.

  • The Action Object - Este será o objeto de ação atual que está sendo executado.

  • Named Objects - Esses objetos incluem #application, #session, #request, #attr e #parameters e referem-se aos escopos de servlet correspondentes.

O Object-Graph Navigation Language (OGNL) é uma poderosa linguagem de expressão usada para fazer referência e manipular dados no ValueStack. OGNL também ajuda na transferência de dados e conversão de tipo.

O mapa ActionContext consiste no seguinte -

  • application - variáveis ​​com escopo de aplicativo.

  • session - variáveis ​​com escopo de sessão.

  • root / value stack - todas as suas variáveis ​​de ação são armazenadas aqui.

  • request - solicitar variáveis ​​com escopo.

  • parameters - parâmetros de solicitação.

  • atributes - os atributos armazenados na página, solicitação, sessão e escopo do aplicativo.

O upload de arquivos no Struts é possível por meio de um interceptor predefinido chamado interceptor FileUpload, que está disponível por meio da classe org.apache.struts2.interceptor.FileUploadInterceptor e incluído como parte do defaultStack.

A seguir estão as propriedades de configuração do Struts2 que controlam o processo de upload de arquivos -

  • struts.multipart.maxSize- O tamanho máximo (em bytes) de um arquivo a ser aceito como upload de arquivo. O padrão é 250M.

  • struts.multipart.parser- A biblioteca usada para fazer upload do formulário multiparte. Por padrão, é jakarta.

  • struts.multipart.saveDir- O local para armazenar o arquivo temporário. Por padrão, é javax.servlet.context.tempdir.

O interceptor fileUplaod usa várias chaves de mensagem de erro padrão -

  • struts.messages.error.uploading - Um erro geral que ocorre quando o arquivo não pode ser carregado.

  • struts.messages.error.file.too.large - Ocorre quando o arquivo carregado é muito grande, conforme especificado por maximumSize.

  • struts.messages.error.content.type.not.allowed - Ocorre quando o arquivo carregado não corresponde aos tipos de conteúdo especificados especificados.

Você pode substituir o texto dessas mensagens nos arquivos de recursos WebContent / WEB-INF / classes / messages.properties.

No núcleo do Struts, temos a estrutura de validação que auxilia o aplicativo a executar as regras para realizar a validação antes que o método de ação seja executado. A classe Action deve estender a classe ActionSupport para que o método de validação seja executado.

Quando o usuário pressiona o botão enviar, o Struts 2 executará automaticamente o método de validação e se qualquer uma das instruções if listadas dentro do método for verdadeira, o Struts 2 chamará seu método addFieldError. Se algum erro tiver sido adicionado, o Struts 2 não continuará a chamar o método execute. Em vez disso, a estrutura do Struts 2 retornará a entrada como resultado da chamada da ação.

Portanto, quando a validação falha e o Struts 2 retorna a entrada, a estrutura do Struts 2 exibe novamente o arquivo de visualização. Como usamos tags de formulário do Struts 2, o Struts 2 adicionará automaticamente as mensagens de erro logo acima do formulário preenchido.

Essas mensagens de erro são as que especificamos na chamada do método addFieldError. O método addFieldError leva dois argumentos. O primeiro é o nome do campo de formulário ao qual o erro se aplica e o segundo é a mensagem de erro a ser exibida acima desse campo de formulário.

O segundo método de fazer a validação é colocar um arquivo xml próximo à classe de ação. A validação baseada em XML Struts2 oferece mais opções de validação como validação de e-mail, validação de intervalo inteiro, campo de validação de formulário, validação de expressão, validação de regex, validação necessária, validação de string necessária, validação de comprimento de string e etc.

O arquivo xml precisa ser nomeado '[action-class]' - validation.xml.

A seguir está a lista de vários tipos de validação de nível de campo e não de nível de campo disponíveis no Struts2 -

  • validador de data

  • validador duplo

  • validador de email

  • validador de expressão

  • validador int

  • validador regex

  • validador necessário

  • validador de string obrigatório

  • validador stringlength

  • validador de url

Internacionalização (i18n) é o processo de planejamento e implementação de produtos e serviços para que possam ser facilmente adaptados a idiomas e culturas locais específicas, um processo denominado localização. O processo de internacionalização às vezes é chamado de capacitação de tradução ou localização.

Struts2 fornece localização, ou seja. suporte à internacionalização (i18n) por meio de pacotes de recursos, interceptores e bibliotecas de tags nos seguintes locais -

  • As tags da IU.

  • Mensagens e erros.

  • Dentro das classes de ação.

O formato de nomenclatura mais simples para um arquivo de recurso é -

bundlename_language_country.properties

Aqui, o nome do pacote pode ser ActionClass, Interface, SuperClass, Model, Package, Global resource properties. A próxima parte language_country representa a localidade do país, por exemplo, a localidade espanhola (Espanha) é representada por es_ES e a localidade Inglês (Estados Unidos) é representada por en_US etc. Aqui você pode pular a parte do país, que é opcional.

Quando você faz referência a um elemento de mensagem por sua chave, a estrutura do Struts procura por um pacote de mensagens correspondente na seguinte ordem -

  • ActionClass.properties

  • Interface.properties

  • SuperClass.properties

  • model.properties

  • package.properties

  • struts.properties

  • global.properties

A classe StrutsTypeConverter informa ao Struts como converter Environment em String e vice-versa, substituindo dois métodos convertFromString () e convertToString ().

O Struts 2 vem com três temas integrados -

  • simple theme- Um tema minimalista sem "sinos e assobios". Por exemplo, a tag textfield renderiza a tag HTML <input /> sem um rótulo, validação, relatório de erro ou qualquer outra formatação ou funcionalidade.

  • xhtml theme - Este é o tema padrão usado pelo Struts 2 e fornece todos os fundamentos que o tema simples fornece e adiciona vários recursos como layout de tabela de duas colunas padrão para o HTML, rótulos para cada um dos HTML, validação e relatório de erros, etc.

  • css_xhtml theme - Este tema fornece todos os fundamentos que o tema simples fornece e adiciona vários recursos como layout padrão baseado em CSS de duas colunas, usando <div> para as tags HTML Struts, rótulos para cada uma das tags HTML Struts, colocadas de acordo com o CSS folha de estilo.

O Struts facilita o tratamento de exceções com o uso do interceptor de "exceção". O interceptor de "exceção" é incluído como parte da pilha padrão, então você não precisa fazer nada extra para configurá-lo. Ele está disponível fora da caixa e pronto para você usar.

Uma anotação @Results é uma coleção de resultados. Sob a anotação @Results, podemos ter várias anotações @Result.

@Results({
   @Result(name = "success", value = "/success.jsp"),
   @Result(name = "error", value = "/error.jsp")
})
public class Employee extends ActionSupport{
 ...
}

As anotações @result têm o nome que corresponde ao resultado do método de execução. Eles também contêm um local para qual visualização deve ser exibida, correspondendo ao valor de retorno de execute ().

@Result(name = "success", value = "/success.jsp")
public class Employee extends ActionSupport{
 ...
}

Isso é usado para decorar o método execute (). O método Action também aceita um valor que é a URL na qual a ação é chamada.

public class Employee extends ActionSupport{
   private String name;
   private int age;
   @Action(value = "/empinfo")
   public String execute() {
      return SUCCESS;
   }
}

A anotação @After marca um método de ação que precisa ser chamado após o método de ação principal e o resultado ser executado. O valor de retorno é ignorado.

public class Employee extends ActionSupport{
   @After
   public void isValid() throws ValidationException {
      // validate model object, throw exception if failed
   }
   public String execute() {
      // perform secure action
      return SUCCESS;
   }
}

A anotação @Before marca um método de ação que precisa ser chamado antes que o método de ação principal e o resultado sejam executados. O valor de retorno é ignorado.

public class Employee extends ActionSupport{
   @Before
   public void isAuthorized() throws AuthenticationException {
      // authorize request, throw exception if failed
   }
   public String execute() {
      // perform secure action
      return SUCCESS;
   }
}

A anotação @BeforeResult marca um método de ação que precisa ser executado antes do resultado. O valor de retorno é ignorado.

public class Employee extends ActionSupport{
   @BeforeResult
   public void isValid() throws ValidationException {
    // validate model object, throw exception if failed
   }
   public String execute() {
      // perform action
      return SUCCESS;
   }
}

Esta anotação de validação verifica se há erros de conversão para um campo e os aplica, se houver.

public class Employee extends ActionSupport{
   @ConversionErrorFieldValidator(message = "Default message", 
                        key = "i18n.key", shortCircuit = true)
   public String getName() {
       return name;
   }
}

Esta anotação de validação verifica se um campo de data tem um valor dentro de um intervalo especificado.

public class Employee extends ActionSupport{
   @DateRangeFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   min = "2005/01/01", max = "2005/12/31")
   public String getDOB() {
       return dob;
   }
}

Esta anotação de validação verifica se um campo duplo possui um valor dentro de um intervalo especificado. Se nem min nem max forem definidos, nada será feito.

public class Employee extends ActionSupport{
   @DoubleRangeFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   minInclusive = "0.123", maxInclusive = "99.987")
   public String getIncome() {
       return income;
   }
}

Esta anotação de validação verifica se um campo é um endereço de e-mail válido se contiver uma String não vazia.

public class Employee extends ActionSupport{
   @EmailValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true)
   public String getEmail() {
       return email;
   }
}

Este validador de nível não campo valida uma expressão regular fornecida.

@ExpressionValidator(message = "Default message", key = "i18n.key", 
shortCircuit = true, expression = "an OGNL expression" )

Esta anotação de validação verifica se um campo numérico possui um valor dentro de um intervalo especificado. Se nem min nem max forem definidos, nada será feito.

public class Employee extends ActionSupport{
   @IntRangeFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   min = "0", max = "42")
   public String getAge() {
       return age;
   }
}

Esta anotação valida um campo de string usando uma expressão regular.

@RegexFieldValidator( key = "regex.field", expression = "yourregexp")

Esta anotação de validação verifica se um campo não é nulo. A anotação deve ser aplicada no nível do método.

public class Employee extends ActionSupport{
   @RequiredFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true)
   public String getAge() {
       return age;
   }
}

Esta anotação de validação verifica se um campo String não está vazio (ou seja, não nulo com um comprimento> 0).

public class Employee extends ActionSupport{
   @RequiredStringValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, trim = true)
   public String getName() {
       return name;
   }
}

Este validador verifica se um campo String tem o comprimento correto. Ele assume que o campo é uma String. Se nem minLength nem maxLength forem definidos, nada será feito.

public class Employee extends ActionSupport{
   @StringLengthFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   trim = true, minLength = "5",  maxLength = "12")
   public String getName() {
       return name;
   }
}

Este validador verifica se um campo é um URL válido.

public class Employee extends ActionSupport{
   @UrlValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true)
   public String getURL() {
       return url;
   }
}

Se você quiser usar várias anotações do mesmo tipo, essas anotações devem ser aninhadas na anotação @Validations ().

public class Employee extends ActionSupport{
  @Validations(
   requiredFields =
      {@RequiredFieldValidator(type = ValidatorType.SIMPLE, 
      fieldName = "customfield", 
      message = "You must enter a value for field.")},
   requiredStrings =
      {@RequiredStringValidator(type = ValidatorType.SIMPLE, 
      fieldName = "stringisrequired", 
      message = "You must enter a value for string.")}
   )
   public String getName() {
       return name;
   }
}

Esta anotação pode ser usada para validadores personalizados. Use a anotação ValidationParameter para fornecer parâmetros adicionais.

@CustomValidator(type ="customValidatorName", fieldName = "myField")

Esta é uma anotação de marcador para conversões de tipo no nível de tipo. A anotação de conversão deve ser aplicada no nível de tipo.

@Conversion()
   public class ConversionAction implements Action {
}

Esta anotação define CreateIfNull para conversão de tipo. A anotação CreateIfNull deve ser aplicada no nível do campo ou método.

@CreateIfNull( value = true )
private List<User> users;

Esta anotação define o Elemento para conversão de tipo. A anotação de elemento deve ser aplicada em nível de campo ou método.

@Element( value = com.acme.User )
private List<User> userList;

Esta anotação define a chave para conversão de tipo. A anotação chave deve ser aplicada no nível do campo ou método.

@Key( value = java.lang.Long.class )
private Map<Long, User> userMap;

Esta anotação define a KeyProperty para conversão de tipo. A anotação KeyProperty deve ser aplicada no nível do campo ou método.

@KeyProperty( value = "userName" )
protected List<User> users = null;

Esta anotação é usada para regras de conversão de classes e aplicativos. A anotação TypeConversion pode ser aplicada em nível de propriedade e método.

@TypeConversion(rule = ConversionRule.COLLECTION, 
converter = "java.util.String")
public void setUsers( List users ) {
   this.users = users;
}