Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

Struts 2.0 com OGNL

Rudranil Dasgupta, Associate IT Architect, Advisory IT Specialist, GBS, IBM USA
Rudranil Dasgupta é IT Architect associado à IBM e IT Specialist autorizado em consultoria, que trabalha como líder de projeto no segmento de mercado de eletrônica. Ele possui quase sete anos de experiência no projeto e desenvolvimento, arquitetura, estratégias técnicas, soluções para a criação e aproveitamento de ativos em solução de cliente, e fornecimento de liderança técnica. Ele possui profunda experiência no trabalho com soluções WebSphere, SOA, Web 2.0, gerenciamento de conteúdo e Java/J2EE. Ele possui múltiplas publicações em fóruns IBM, incluindo no IBM developerWorks. Ele também possui diversas sessões sobre Web 2.0 e colaboração social em fóruns reconhecidos.
Kaushik Dutta, IBM Associate IT Architect, IBM USA
Kaushik Dutta é arquiteto de aplicativos e atualmente trabalha como arquiteto técnico para a GBSC Asset Reuse Enablement Initiative. Ele possui mais de 10 anos de experiência profissional em projeto de software, desenvolvimento, análise e soluções de arquitetura. Ele esteve envolvido na análise, arquitetura, e projeto e desenvolvimento de sistema de aplicativos da Web utilizando a tecnologia Java, J2EE, EJB, SOA, Web 2.0, WebSphere Adapter, JMS, serviços da Web, JSP, Servlet, JDBC, RMI, XML, Oracle, HTML e JavaScript.
Sudip Dutta, IBM Senior System Engineer, IBM USA
Sudip Dutta é desenvolvedor senior no segmento de mercado de eletrônica. Ele possui aproximadamente sete anos de experiência no projeto e desenvolvimento, criação de protótipos, fornecimento de estratégias técnicas, soluções para a criação e aproveitamento de ativos em solução de cliente, bem como no fornecimento de liderança técnica. Ele possui profunda experiência no trabalho com soluções WebSphere, SOA, Web 2.0, Java/J2EE, .NET e soluções DB2. Ele tem mestrado em aplicativos de computador e bacharelado em matemática.

Resumo:  O surgimento do Struts como estrutura foi revolucionário desde o primeiro dia em que ele chegou à cena de tecnologia. Muitos projetos em Java™/J2EE adotaram o Struts, que se tornou posteriormente uma das estruturas mais estáveis entre os inúmeros aplicativos baseados em J2EE. Embora ele forneça apenas suporte do controlador, essa pode ser uma vantagem para desenvolvedores que desejam desenvolver componentes customizados para as seções M (Modelo) e V (Visualização). Neste artigo, destacaremos um dos componentes mais importantes do Struts 2.0, a linguagem OGNL (Object-Graph Navigation Language) e seus recursos.

Data:  18/Jul/2011
Nível:  Intermediário Também disponível em :   Inglês
Atividade:  1204 visualizações
Comentários:  


Introdução

O Struts 2 foi lançado no início de fevereiro de 2007 com uma infinidade de recursos interessantes. No escopo deste artigo, vamos nos concentrar em um dos acréscimos mais recentes à estrutura do Struts 2: a linguagem OGNL (Object-Graph Navigation Language). Esta é a mais nova forma de linguagens de expressão, e tem excelente suporte a coleta, passagem gráfica de objeto e indexação.

Definiremos as páginas da Web com base hierárquica e como podemos realizar a extração de dados utilizando o código mínimo da estrutura OGNL do Struts 2. Vamos analisar como importantes conceitos de negócios estão sendo implementadas na Web usando essas construções. Vamos demonstrar como a extração de dados dessas páginas era manuseada na estrutura anterior (Struts 1.x), e como migrar para a estrutura OGNL do Struts 2 ajuda a minimizar o esforço de desenvolvimento. Neste sentido, abordaremos também os conceitos básicos de OGNL e Struts 2 e como os aproveitamos para criar uma metodologia leve para lidar com páginas hierárquicas. Demonstramos também um estudo comparativo entre os recursos do Struts 1.x e do Struts 2, que ajudaram na migração para um ambiente com menos código.


Caso 1. Estudo de um cenário existente

Vamos levar em conta o seguinte cenário de exibição de dados hierárquicos multinível e atualização de dados em uma página da Web. Um consultor de investimentos está preparando um relatório para um cliente. A captura de tela mostra uma tela de atualização de dados para o portfólio de investimentos do cliente. Os campos de entrada de dados são atributos de nível superior do portfólio. As linhas em roxo são os itens de dados de primeiro nível sob o portfólio, e os campos Target Investment Amount and Target Profit% são atributos de cada um dos itens de primeiro nível. Da mesma forma, as linhas verdes são itens de segundo nível (e os campos sob elas são atributos nesse nível). Por fim, as linhas amarelas exibem itens de terceiro nível. Neste artigo, vamos supor que todos os campos podem ser atualizados e, quando o usuário envia a página, os dados no backend devem ser atualizados em conformidade. Note também que os números das linhas de primeiro, segundo e terceiro nível são dinâmicos por natureza.


Figura 1. Representação gráfica



Implementação atual para resolver o problema (com Struts 1.x)

A Listagem 1 mostra o modelo de dados da página acima.


Listagem 1. Estrutura de dados anterior

public class ClientPortfolioDetailsBean
{
	//Domain model for the client portfolio details
	
	//Portfolio level attributes
	private String investorName = null;
	private String emailId = null;
	private String contactNumber = null;
	//..... Other portfolio level attributes
	//List to hold the details of Stocks / Mutual Funds etc investment category
	private List <InvestmentCategoryDetailsBean> invCategoryList = null;
}
public class InvestmentCategoryDetailsBean {
	
	//Bean to hold the information about investment category details
	//like Stocks, Mutual Funds etc. Represents the first level rows
	private String categoryName = null;
	private double targetInvstAmt  = 0.0;
	private double expectedAnnualReturn   = 0.0;
	//Other attributes follows
	//List of stocks and fund details bean to hold the
	//second level items
	private List <StocksAndFundDetailsBean> itemList = null;
}
public class StocksAndFundDetailsBean {
	
	//Bean to hold the information about investment category details
	//like Stocks, Mutual Funds etc. Represents the second level rows
	
	//Attributes at that level
	private String stockFundCategoryName = null;
	private double targetInvstAmt = 0.0;
	private double targetProfit =0.0;
	//Other attribute follows
	//List to hold the stock details
	private List <StocksDetailsBean> stockDetailsList = null;
}
public class StocksDetailsBean {
	
	//Represents the third level item details
	//Details of individual stock/fund details
	private String stockFundName = null;
	private double noOfStocks = 0.0;
	private double buyingPrice =0.0;
	private Date buyingDate = null;
}

No Struts 1.x, a solução para o primeiro estudo de caso exige a definição de um form bean em um modo de nível único e simples. Para obter os valores atualizados inseridos pelo usuário, a Listagem 2 fornece a estrutura necessária de form bean.


Listagem 2. Estrutura de form beans do Struts 1.x

public class PortfolioDetailsBean extends ActionForm

{

	//Top level attributes
	
	private String investorName = null;
	private String emailId = null;
	//........... Other Top level attributes
	
	//Fields to capture Attributes of First level rows
	private double[] firstLevelTargetAmt = null;
	private double[] firstLevelExpectedAnnlReturn = null;
	//......... Other First Level row attributes

	//Fields to capture Attributes of Second level rows
	private double[] secondLevelTargetAmt = null;
	private double[] secondLevelTargetInvPeriod = null;
	//......... Other Second level row attributes

	//Fields to capture Attributes of Second level rows
	private double[] thirdLevelNoOfStocks = null;
	private double[] thirdLevelByingPrice = null;
	//......... Other Third level row attributes
}

Para converter esses elementos de form bean de nível único no modelo de domínio multinível mostrado na Listagem 1, a classe de ação requer codificação adicional, como mostrado na Listagem 3. Note que a lógica aqui aplicada depende da estrutura do modelo de domínio e, à medida que o nível e número de atributos aumentam, a complexidade da conversão aumenta na classe de ação.


Listagem 3. Código personalizado para converter elementos de form bean de nível único em modelo de domínio multinível

public class UpdatePortfolioAction extends Action

{

    public ActionForward execute(ActionMapping mapping, ActionForm form,
	    HttpServletRequest request, HttpServletResponse response)
	    throws Exception {

	ActionErrors errors = new ActionErrors();
	ActionForward forward = new ActionForward(); // valor de retorno
	PortfolioDetailsBean portfolioDetailsBean = (PortfolioDetailsBean) form;

	
	try {
		//Counter to track index of 2nd level index
		int counter2ndLevelIndex= 0;
		//Converting the form bean to the domain model
		ClientPortfolioDetailsBean clientBean = new ClientPortfolioDetailsBean();
		//Setting the top level attributes
		clientBean.setEmailId(portfolioDetailsBean.getEmailId());
		//.........................................
		//Similarly other top level fields are created
		//Get the size of first level row sizes from session
		int sizeInvestmentCategory = getInvestmentCategorySize
           (request.getSession());
		clientBean.setInvCategoryList(new ArrayList
           <InvestmentCategoryDetailsBean>(sizeInvestmentCategory));
		for(int firstLevelIndex=0;firstLevelIndex<
           sizeInvestmentCategory;firstLevelIndex++)
		{
			//Create the updated first level bean
			InvestmentCategoryDetailsBean invCatBean =
               new InvestmentCategoryDetailsBean();
			//Set the investment category Bean in the parent bean
			clientBean.getInvCategoryList().add(invCatBean);
			//set the updated properties
			invCatBean.setExpectedAnnualReturn(
               portfolioDetailsBean.getFirstLevelExpectedAnnlReturn()[firstLevelIndex]);
			//.........................................
			//Set the other properties at first level
			//Get the size of 2nd level row sizes from session
	        int sizeStockAndFundDetails = getStockAndFundDetailsSize
               (request.getSession(),firstLevelIndex);
              	invCatBean.setItemList(
                     new ArrayList<StocksAndFundDetailsBean>(sizeStockAndFundDetails));
			//Fill Up the second level objects
	        for(int secondLevelIndex=0;secondLevelIndex<
               sizeStockAndFundDetails;secondLevelIndex++)
			{
	StocksAndFundDetailsBean stkFundDetails =
	   new StocksAndFundDetailsBean();
    //Set the object to the parent Bean
    invCatBean.getItemList().add(stkFundDetails);
    //Set the individual attributes
	stkFundDetails.setTargetInvstAmt(
       portfolioDetailsBean.getSecondLevelTargetAmt()[counter2ndLevelIndex++]);
       //............... Other fields follows
	   // Setting up of 3rd level list follows here
	   //......................................
	}			
   }		
} catch (Exception e) {

   // Report the error using the appropriate name and ID.

   }
}


Desvantagens do cenário atual

Uma das tarefas tediosas do desenvolvimento de aplicativos da Web é a transferência de dados de form beans para beans de dados. Converter dos tipos Strings para Java, e vice-versa, aumenta a complexidade. É necessário analisar os valores da cadeia de caractere em duplas e números inteiros, além de resolver as exceções que possam surgir a partir de dados incorretos.

Transferências de dados e conversões de tipo acontecem em ambas as extremidades do ciclo de processamento do pedido. Quando o resultado é renderizado, os dados são reconvertidos do tipo Java de volta para um formato de cadeia de caractere. Esse processo acontece com quase todos os pedidos em um aplicativo da Web, e é parte integrante do domínio. Apoiar formas dinâmicas com conjuntos dinâmicos de registros requer códigos e lógica complicados. O desenvolvimento e a manutenção desse código de lógica tornam-se complicados.


Struts 2 e OGNL

A automação da transferência de dados e da conversão de tipo é um dos recursos mais poderosos do Struts 2. Com a ajuda de OGNL, a estrutura do Struts 2 permite a transferência de dados para tipos do lado de Java mais complexos, como Lista, Mapa, etc. Os conversores personalizados também podem ser desenvolvidos para estender o mecanismo de conversão de tipo, e pode lidar com qualquer tipo de dados, incluindo tipos definidos pelo usuário.

O OGNL é a interface entre a saída e entrada HTTP baseada em cadeia de caracteres da estrutura do Struts 2 e o processamento interno baseado em Java. Para desenvolvedores familiarizados com OGNL, ela melhorará muito a eficiência e reduzirá os problemas com a manutenção.


Figura 2. Pilha de OGNL


Da perspectiva do desenvolvedor, a OGNL possui dois componentes:

  • Linguagem de expressão — Normalmente usada em nomes de campo de entrada de formulário e tags JSP. As expressões de OGNL são usadas para ligar propriedades de dados do lado de Java a cadeias de caractere nas camadas de visualização baseadas em texto.
  • Conversores de tipo — Responsáveis pela conversão de tipos de dados. Cada vez que dados se movem de ou a um ambiente Java, deve ocorrer uma conversão entre a versão de cadeia de caractere dos dados que residem em HTML e o tipo de dados Java adequado. A estrutura oferece conversores integrados para lidar com muito mais do que solicitamos, ou o desenvolvedor tem a opção de criar conversores personalizados.

A estrutura transfere automaticamente dados e faz a conversão de dados dos parâmetros do pedido, mas para onde vão os dados e como a OGNL descobre o destino? ValueStack no Struts 2 é a construção que é um aglomerado de propriedades de objetos como propriedades de um único objeto virtual. Em caso de propriedades duplicadas (ou seja, dois objetos na pilha com a propriedade employeeId ), será usada a propriedade do objeto mais alto na pilha. A estrutura do Struts 2 tem suporte integrado para a conversão entre as cadeias de caractere nativas de HTTP e a seguinte lista de tipos Java:

  • Array
  • booleano/Booleano
  • Car/Caractere
  • int/inteiro, flut/Flutuante, longo/Longo, duplo/Duplo
  • Data
  • Cadeia de caractere
  • Mapa
  • Lista

Usando OGNL para resolver dificuldades de transformação

As expressões de OGNL do Struts 2 reduzem a dificuldades de escrever um código complexo para transformar form beans de nível único em objetos de domínio multinível. No Struts 2, os nomes de campos de entrada em HTML podem ser gerados como expressões de OGNL, as quais, por sua vez, ajudam a eliminar codificação complexa na classe de ação. Como exemplo, se um nome de campo de entrada em HTML (como uma caixa de texto) for definido como clientPortfolioDetailsBean.investorName, o getClientPortfolioDetailsBean() da classe de ação será chamado. Isso deve retornar o ClientPortfolioDetailsBean, seguido pela chamada do método setInvestorName() com o valor fornecido pelo usuário na tela. A nomenclatura inteligente de campos de entrada em HTML atualizados pelos usuários rejeita a escrita de código complexo na classe de ação. O modelo de domínio é preenchido adequadamente dentro da classe de ação.

Precisamos acrescentar um tipo de atributo ClientPortfolioDetailsBean à classe de ação, juntamente com seu método get. Dentro do método get, um bean deve ser retornado da sessão se sua instância não estiver configurada na instância de classe de ação atual. Durante o carregamento da página, a instância de bean detalhada pelo cliente deve ser mantida no objeto de sessão. No caso de objetos maiores, o método getClientDetailsFromSession() pode ser substituído por getClientDetailsFromDB(), no qual os dados devem ser obtidos a partir do banco de dados.


Listagem 4. Fragmento de código do Caso 1
public class ClientPortfolioAction extends ActionSupport {

	private ClientPortfolioDetailsBean clientDetailsBean = null;
		
	//Accessor for the clientDetailsBean.
	public ClientPortfolioDetailsBean getClientDetailsBean() {
		if(clientDetailsBean==null)
		{
			//If the bean is null for this action class instance
			//load the data from the session
			clientDetailsBean = getClientDetailsFromSession();
		}
		return clientDetailsBean;
	}
}


Listagem 5. Fragmento de código do Caso 2

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

	<s:textfield name="clientDetailsBean.investorName" 
value="%{clientDetailsBean.investorName}"/%>
	<s:textfield name="clientDetailsBean.emailId" 
value="%{clientDetailsBean.emailId}"/%>
	<s:textfield name="clientDetailsBean.contactNumber" 
value="%{clientDetailsBean.contactNumber}"/%>
		
	<s:iterator value="clientDetailsBean.invCategoryList" 
var="invCatDetails" status="firstLevelIdx"%>
		 
		<s:property value="%{#invCatDetails.categoryName}"/%>
		 
	<s:textfield name="clientDetailsBean[%{#firstLevelIdx.index}]
.targetInvstAmt" 
value="%{invCatDetails.targetInvstAmt}"/%>
								
<s:textfield name="clientDetailsBean[%{#firstLevelIdx.index}]
.expectedAnnualReturn" 
value="{invCatDetails.expectedAnnualReturn}"/%>
											
			<s:iterator value="#invCatDetails.itemList"
var="stkFundDetails" status="secondLevelIndx"%>
				
			<s:property value="%{#stkFundDetails.
stockFundCategoryName}"/%>
	<s:textfield name="clientDetailsBean
[%{#firstLevelIdx.index}].itemList[%{secondLevelIndx.index}].
targetInvstAmt" value="%{#stkFundDetails.targetInvstAmt}" /%>
	<s:textfield name="clientDetailsBean[%{#firstLevelIdx.index}]
.itemList[%{secondLevelIndx.index}].
targetProfit" value="%{#stkFundDetails.targetProfit}" /%>
											
	<s:iterator value="#stkFundDetails.stockDetailsList" 
var="stkDetails" status="thirdLevelIndx"%>
	<s:property value="%{stkDetails.stockFundName}" /%>
	<s:textfield name="clientDetailsBean[%{#firstLevelIdx.index}]
.itemList[%{secondLevelIndx.index}].stockDetailsList
[%{thirdLevelIndx.index}].noOfStocks" value="%{#stkDetails.noOfStocks}" /%>
	<s:textfield name="clientDetailsBean[%{#firstLevelIdx.index}]
.itemList[%{secondLevelIndx.index}].stockDetailsList
[%{thirdLevelIndx.index}].buyingPrice" value="%{#stkDetails.buyingPrice}"/%>
					
				</s:iterator>				
			</s:iterator>
		
	</s:iterator>

Agora, vamos analisar uma página JSP na qual os nomes de caixa de texto de entrada são gerados por expressões de OGNL válidas, e como o campo "N° de ações" da "ABC Incorporated" é atualizado pela expressão de OGNL:

                <s:textfield
                name="clientDetailsBean[%{#firstLevelIdx.index}]
                .itemList[%{secondLevelIndx.index}].stockDetailsList
                [%thirdLevelIndx.index}].noOfStocks}'/>

Essa linha será convertida no seguinte código HTML:

<input type="text"
                name="clientDetailsBean[0].itemList[0].stockDetailsList[0].noOfStocks"
                value="<somevalue>" /> 

A expressão de OGNL clientDetailsBean[0].itemList[0].stockDetails[0].noOfStocks é equivalente à seguinte chamada de código: getClientDetailsBean().getItemList().get(0).getStockDetailList(0).get(0).setNoOfStocks(<some value>) na instância de classe de ação. De modo similar, outros campos serão atualizados correspondentemente no modelo de domínio. No método de ação, se getClientDetailsBean() for chamado, todos os campos serão atualizados pela estrutura do Struts 2 em vigor. Isso permite evitar a codificação complexa na classe de ação (como mostrado no exemplo do Struts 1) para converter o form bean no objeto relacionado de modelo de domínio.


Benefícios do cenário atual

As vantagens da estrutura do Struts 2 incluem:

  • A linguagem de expressão do OGNL permite mapear campos de formulário em propriedades do lado de Java.
  • Os conversores de tipo de OGNL convertem automaticamente os dados (em forma de cadeia de caractere) de parâmetros de pedido para os tipos Java reais das propriedades.
  • Ao renderizar a visualização, a linguagem de expressão e o conversor de tipo convertem novamente de tipos Java para o valor de cadeia de caractere de forma automática.
  • Suporta um conjunto flexível e amplo de conversões de e para Coleta e Array.
  • Permite o desenvolvimento de Web sites complexos, o que reduz a complexidade dos códigos de backend.
  • Reduz o tempo de desenvolvimento da transferência automática de dados reutilizáveis.
  • Redução significativa de código tedioso para conversão de dados e manipulação de exceções, permitindo concentrar-se na lógica básica de negócio.

Conclusão

Neste artigo, discutimos o aspecto OGNL do Struts 2, e como ele auxilia os profissionais a implementar aplicativos de negócios mais ágeis. Em artigos futuros, revisaremos o Struts 2 a partir de um ponto de vista do desenvolvimento. O Struts 2 veio para ficar, pois torna-se cada vez mais estável, e esperamos ajudá-lo a aproveitar ao máximo os benefícios dos seus recursos aprimorados.


Recursos

Aprender

Obter produtos e tecnologias

Discutir

  • Participe dos Blogs do developerWorks e participe da comunidade do developerWorks.

  • Participe da comunidade do developerWorks. Entre em contato com outros usuários do developerWorks, enquanto explora os blogs, fóruns, grupos e wikis orientados ao desenvolvedor.

Sobre os autores

Rudranil Dasgupta é IT Architect associado à IBM e IT Specialist autorizado em consultoria, que trabalha como líder de projeto no segmento de mercado de eletrônica. Ele possui quase sete anos de experiência no projeto e desenvolvimento, arquitetura, estratégias técnicas, soluções para a criação e aproveitamento de ativos em solução de cliente, e fornecimento de liderança técnica. Ele possui profunda experiência no trabalho com soluções WebSphere, SOA, Web 2.0, gerenciamento de conteúdo e Java/J2EE. Ele possui múltiplas publicações em fóruns IBM, incluindo no IBM developerWorks. Ele também possui diversas sessões sobre Web 2.0 e colaboração social em fóruns reconhecidos.

Kaushik Dutta é arquiteto de aplicativos e atualmente trabalha como arquiteto técnico para a GBSC Asset Reuse Enablement Initiative. Ele possui mais de 10 anos de experiência profissional em projeto de software, desenvolvimento, análise e soluções de arquitetura. Ele esteve envolvido na análise, arquitetura, e projeto e desenvolvimento de sistema de aplicativos da Web utilizando a tecnologia Java, J2EE, EJB, SOA, Web 2.0, WebSphere Adapter, JMS, serviços da Web, JSP, Servlet, JDBC, RMI, XML, Oracle, HTML e JavaScript.

Sudip Dutta é desenvolvedor senior no segmento de mercado de eletrônica. Ele possui aproximadamente sete anos de experiência no projeto e desenvolvimento, criação de protótipos, fornecimento de estratégias técnicas, soluções para a criação e aproveitamento de ativos em solução de cliente, bem como no fornecimento de liderança técnica. Ele possui profunda experiência no trabalho com soluções WebSphere, SOA, Web 2.0, Java/J2EE, .NET e soluções DB2. Ele tem mestrado em aplicativos de computador e bacharelado em matemática.

Ajuda para Relatar Abuso

Relatar abuso

Obrigado. Esta entrada foi sinalizada para atenção do moderador.


Ajuda para Relatar Abuso

Relatar abuso

Falha no envio do Relatório de abuso. Tente novamente mais tarde.


developerWorks: Registre-se


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Selecione seu nome de exibição

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

(Deve possuir de 3 a 31 caracteres.)


Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Classificar este artigo

Comentários

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=654374
ArticleTitle=Struts 2.0 com OGNL
publish-date=07182011
author1-email=rudranil.dasgupta@in.ibm.com
author1-email-cc=
author2-email=kaushik_dutta@in.ibm.com
author2-email-cc=
author3-email=suddutt1@in.ibm.com
author3-email-cc=

Conheça a IBM da sua cidade

Virtual Branch Office Brasil

A IBM está mais perto do que você imagina!


Tags

Help
Use o campo de pesquisa para encontrar todos os tipos de conteúdo no My developerWorks com essa tag.

Use a barra de rolagem para ver mais ou menos tags.

Tags populares mostra as principais tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Minhas tags mostra suas tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Use o campo de pesquisa para localizar todos os tipos de conteúdo no Meu developerWorks com essa tag. Tags populares mostra as tags principais para essa zona de conteúdo particular (por exemplo, tecnologia Java, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere). Minhas tags mostra as suas tags para essa zona de conteúdo em particular (por exemplo, tecnologia Java, Linux, WebSphere).