java para web com struts danilo toshiaki sato [email protected] treinamento alesp – spl módulo...

48
Java para Web com Struts Danilo Toshiaki Sato [email protected] Treinamento ALESP – SPL Módulo III

Upload: luiza-alva

Post on 07-Apr-2016

224 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Java para Web com Struts

Danilo Toshiaki [email protected]

Treinamento ALESP – SPLMódulo III

Page 2: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 2

Agenda - Módulo III1. Recapitulando...2. Construindo a View

1. Internacionalização2. TagLibs3. Struts Validator4. Struts Tiles

3. Configurando o Struts1. web.xml2. struts-config.xml

4. Considerações sobre o SPL

Page 3: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 3

Recapitulando... Fluxo Básico de ControleViewConfig

Page 4: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 4

Construindo a View Suporte à Internacionalização (i18n):

No Struts, o suporte é limitado à apresentação de conteúdo internacionalizado

Internacionalização na entrada de dados fica a cargo do cliente (navegador)

Aplicações na web podem ser acessadas por pessoas de diversos países

Internacionalização permite que a aplicação seja localizada para cada usuário: Língua Formato de data Formato numérico Formato monetário

Page 5: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 5

Construindo a View Conceitos principais:

Locale: Classe Java que representa uma escolha de localização (país e língua – en_US)

ResourceBundle: Classe Java para prover recursos localizados

MessageFormat: Classe Java que permite a definição de mensagens parametrizadas (Ex: “Valor máximo: {0}”)

MessageResources: Classe do Struts para obter mensagens localizadas de ResourceBundles, num Locale diferente do padrão no servidor

Page 6: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 6

Construindo a View Um ResourceBundle é um

mapeamento chave (String) valor (Object)

PropertyResourceBundle: uma subclasse de ResourceBundle para representar localização de mensagens (String) definidas num arquivo de propriedades

Sintaxe: “nome=valor”

Page 7: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 7

Construindo a View Para criar conteúdo localizado no Struts:

1. Crie os arquivos de propriedades para cada localização do ResourceBundle

2. Coloque os arquivos de propriedades no classpath da aplicação web (WEB-INF/classes/diretórios_do_pacote)

3. Configurar os parâmetros de internacionalização na configuração do ActionServlet (web.xml)

4. Utilizar as taglibs do Struts para exibição de mensagens e conteúdo localizado no JSP

Page 8: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 8

Construindo a View1. MeusRecursos.properties

Meus Recursos_en.properties

erro.usuario.invalido=Usuário inválidoerro.nome.invalido=Nome deve ter no máximo 10 caracteresmsg.nome=Nomemsg.login=Loginmsg.login.sucesso=Login efetuado com sucesso

erro.usuario.invalido=Invalid usererro.nome.invalido=Maximum length of name is 10msg.nome=Namemsg.login=Loginmsg.login.sucesso=Login successfull

Page 9: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 9

Construindo a View2. Salvar os arquivos no diretório WEB-INF/classes/app3. Configurar os parâmetros locale e application no

web.xml (ou <message-resources> no struts-config.xml para o Struts 1.1)

<servlet (... Configurações do ActionServlet)> <init-param> <param-name>application</param-name> <param-value>app.MeusRecursos</param-value> </init-param> <init-param> <param-name>locale</param-name> <param-value>true</param-value> </init-param></servlet>

Page 10: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 10

Construindo a View4. Utilizando as taglibs para localização:<%@ taglib uri="/tags/struts-html" prefix="html"%><%@ taglib uri="/tags/struts-bean" prefix="bean"%>

<html:html> <html:form action="login.do"> <bean:message key="msg.nome"/>: <html:text property="nome"/><br> <html:submit> <bean:message key="msg.login"/> </html:submit> </html:form> <html:errors/></html:html>

Page 11: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 11

Construindo a View Interação com os ActionForms:

Geralmente é preciso lidar com formulários HTML para entrada de dados

O Struts fornece o ActionForm para representar um formulário HTML

Ao montar a página HTML usando tags como <input> queremos evitar que o usuário tenha que preencher todo o formulário no caso de um erro

Solução: Taglibs do Struts

Page 12: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 12

Construindo a View TagLibs: Tags personalizadas que podem

ser utilizadas na construção do JSP Sintaxe parecida com HTML: facilita leitura

e visualização do código JSP Struts disponibiliza três TagLibs principais:

bean: Útil para acessar JavaBeans e suas propriedades

html: Útil para construção de formulários HTML e interação com os componentes do Struts

logic: Útil para controle de fluxo na apresentação (condicionais, loops, ...)

Page 13: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 13

Construindo a View Instalando as taglibs do Struts:

1. Instalar os arquivos JAR e TLD: WEB-INF\lib\struts.jar WEB-INF\struts-bean.tld WEB-INF\struts-html.tld WEB-INF\struts-logic.tld

2. Configurar as taglibs no web.xml3. Importar as taglibs no JSP para utilização

Page 14: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 14

Construindo a View web.xml:<taglib> <taglib-uri>/tags/struts-bean</taglib-uri> <taglib-location> /WEB-INF/struts-bean.tld </taglib-location></taglib><taglib> <taglib-uri>/tags/struts-html</taglib-uri> <taglib-location> /WEB-INF/struts-html.tld </taglib-location></taglib>(...)

Page 15: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 15

Construindo a View Importando no JSP:

Utilização:

Consulte a documentação online para descrições completas das tags do Struts e suas propriedades

<%@ taglib uri="/tags/struts-html" prefix="html"%><%@ taglib uri="/tags/struts-bean" prefix="bean"%><%@ taglib uri="/tags/struts-logic" prefix="logic"%>

<bean:write name="meuForm" property="nome"/>

Page 16: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 16

Construindo a View Propriedades comuns das tags Struts:

id: nomeia uma variável que será criada no escopo de página

name: Nome para encontrar o JavaBean existente no escopo especificado

scope: Escopo para buscar o JavaBean (ordem padrão: page, request, session, application)

property: Nome da propriedade do JavaBean cujo valor será recuperado

<logic:iterate scope="request" name="resultado" property="colecao" id="linha"> (...) </logic:iterate>

Page 17: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 17

Construindo a View Taglib: bean

message: Apresenta uma mensagem internacionalizada

parameter: Define uma variável (escopo page) com base no valor do parâmetro especificado

write: Apresenta o valor da propriedade do componente especificado

define: Define uma variável com base no valor da propriedade do componente especificado

cookie, header, struts, include, ... Apenas message e struts estão ligadas ao

framework Struts

Page 18: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 18

Construindo a View Taglib: html

form: <form> button,cancel,checkbox,file,hidden

,image,password,radio,reset,submit,text,textarea: <input type="...">

select,option: <select> e <option> link: <a> img: <img> errors: exibe um conjunto de

mensagens de erro

Page 19: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 19

Construindo a View Taglib: logic

Tags de avaliação: para testar se valores são iguais, menores que, maiores que, vazios ou se estão presentes (Ex: <logic:equal>)

Tags de controle: para redirecionar o fluxo (<logic:forward> e <logic:redirect>)

Tags de repetição: para iteração em coleções (<logic:iterate>)

Tags logic podem ser utilizadas fora do framework Struts

Page 20: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 20

Construindo a View Validação:

Os elementos HTML aceitam qualquer valor digitado pelo usuário

Validação com JavaScript pode ser desabilitada pelo usuário

Recomendação: Efetuar validação no cliente (resposta mais rápida) e também no servidor (caso o JavaScript esteja desabilitado)

Page 21: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 21

Construindo a View Precisamos de validações para:

Campos obrigatórios Verificar se um valor encaixa-se na faixa de

valores esperados Verificar se um valor segue um padrão esperado Verificar um formulário inteiro de uma só vez e

retornar uma lista de mensagens Comparar valores entre campos Retornar os dados originais para correção Exibir mensagens localizadas quando necessário Executar validações no lado do servidor se

JavaScript está desabilitado

Page 22: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 22

Construindo a View Struts Validator:

Baseado no Jakarta Commons Validator Extrai regras de validação do código Java e

do HTML Suporte à internacionalização de mensagens Configurado em arquivos XML Regras de validação para tipos básicos já

são parte do arcabouço Suporte à validação no cliente e no servidor Permite a criação de regras customizadas

Page 23: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 23

Construindo a View Componentes do Struts Validator:

Validadores: para lidar com tipos básicos ResourceBundle: compartilhado com o

Struts Arquivos de configuração XML Tag JSP: para incluir validações

JavaScript na página ValidatorForm ValidatorActionForm

Page 24: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 24

Construindo a View Adicionando validação automática:

1. O Form deve estender org.apache.struts.validator.ValidatorForm ou org.apache.struts.validator.ValidatorActionForm

2. O JSP deve incluir a tag <html:javascript> para validação JavaScript

3. Definir as validações da sua aplicação no arquivo validator.xml

4. Ligar o plug-in to Struts Validator no arquivo struts-config.xml

Page 25: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 25

Construindo a View Diferença entre ValidatorForm e

ValidatorActionForm: ValidatorForm: O nome declarado no

validator.xml deve ser o mesmo do Form correspondente, como definido no atributo name do struts-config.xml

ValidatorActionForm: O nome declarado no validator.xml deve ser o mesmo do Action correspondente, como definido no atributo path do struts-config.xml

Você ainda pode sobrescrever o método validate(), se achar necessário: Basta chamar super.validate() no início do

método

Page 26: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 26

Construindo a View Validadores básicos:

required: campo obrigatório mask: campo deve ser aceito pela expressão regular

definida range: campo pertence a um intervalo maxLength: tamanho máximo do campo minLength: tamanho mínimo do campo byte,short,integer,long,float,double: campo

deve ser convertido para o tipo especificado date: campo deve representar uma data válida creditCard: campo deve ser um valor válido de

cartão de crédito email: campo deve ser um endereço válido de e-mail

Page 27: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 27

Construindo a View Exemplo: validator.xml<formset> <form name="meuForm"> <field property="nome" depends="required,minlength"> <arg0 key="msg.nome"/> <var> <var-name>minlength</var-name> <var-value>1</var-value> </var> </field> </form></formset>

Page 28: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 28

Construindo a View Exemplo: JSP<%-- definições de taglibs ... --%><html:html> <html:form action="login.do" onsubmit="validateMeuForm(this)"> <bean:message key="msg.nome"/>: <html:text property="nome"/><br> <html:submit> <bean:message key="msg.login"/> </html:submit> </html:form> <html:errors/> <html:javascript formName="meuForm"/></html:html>

Page 29: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 29

Construindo a View Exemplo: struts-config.xml<!-- Definição do Plugin do Validator --><plug-in className="org.apache.struts.validator.ValidatorPlugIn"><set-property property="pathnames"value="/WEB-INF/validator-rules.xml,/WEB-INF/validator.xml"/></plug-in>

Page 30: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 30

Construindo a View Struts Tiles:

Componente para definição de templates para as páginas web

Uso comum para separar: cabeçalhos, rodapés, menus, ...

É um plugin do Struts com um RequestProcessor especializado para o processamento dos templates

Definições de template ficam centralizadas no arquivo tiles-defs.xml

Inclusão nos JSP através de uma taglib <tiles>

Page 31: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 31

Construindo a View Exemplo: layout.jsp

index.jsp

<%@ taglib uri="/tags/struts-tiles" prefix="tiles"%><html> <body> <tiles:insert attribute="body"/> </body></html>

<h1>Título da página principal</h1>

Page 32: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 32

Construindo a View Exemplo: tiles-defs.xml<tiles-definitions> <definition name="layout" path="/layout/layout.jsp"> <put name="body" value=""/> </definition> <definition name="homepage" extends="layout"> <put name="body" value="/index.jsp"/> </definition><tiles-definitions>

Page 33: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 33

Construindo a View Exemplo: struts-config.xml<!-- Definição do Plugin do Tiles --><plug-in className="org.apache.struts.tiles.TilesPlugin"> <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml"/></plug-in>(...)<!-- Definição dos ActionMappings --><action path="/index" type="org.apache.struts.actions.ForwardAction" parameter="homepage"/>(...)

Page 34: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 34

Configurando o Struts Para redirecionar as requisições HTTP

para o Struts, o contêiner deve conhecer o ActionServlet

Como todo Servlet, o ActionServlet é configurado no arquivo: WEB-INF/web.xml

Além das configurações do ActionServlet e seus mapeamentos, você precisa configurar as taglibs do Struts

Page 35: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 35

Configurando o Struts web.xml<!-- Configuração do ActionServlet --><servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servlet-class> <init-param> <param-name>config</param-name> <param-value> /WEB-INF/struts-config.xml </param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>

Page 36: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 36

Configurando o Struts web.xml<!-- Redireciona requisições para o ActionServlet --><servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern></servlet-mapping><!-- Configuração das taglibs --><taglib> <taglib-uri>/tags/struts-bean</taglib-uri> <taglib-location> /WEB-INF/struts-bean.tld </taglib-location></taglib>(...)

Page 37: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 37

Configurando o Struts As principais configurações do Struts

ficam no arquivo struts-config.xml Esqueleto do arquivo:<struts-config> <data-sources>...</data-sources> <form-beans>...<form-beans> <global-exceptions>...<global-exceptions> <global-forwards>...<global-forwards> <action-mappings>...<action-mappings> <controller>...</controller> <message-resources>...</message-resources> <plug-in>...<plug-in></struts-config>

Page 38: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 38

Configurando o Struts DataSources: recurso JDBC para conexão

com banco de dados Geralmente representam um pool de

conexões SQL Estrutura básica de configuração:<data-sources> <data-source> <set-property name="${ }" value="${ }"/> <set-property name="${ }" value="${ }"/> ... </data-source></data-sources>

Page 39: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 39

Configurando o Struts ActionForm e DynaActionForm são

definidos na tag <form-beans> Veja “Construindo o Model” para detalhes

sobre esse elemento Estrutura básica de configuração:<form-beans> <form-bean name="${ }" value="${ }"> <form-property name="${ }" value="${ }"/> <form-property name="${ }" value="${ }"/> ... </form-bean></form-beans>

Page 40: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 40

Configurando o Struts Para tratamento declarativo de erros

globais, utilize a tag <global-exceptions> Veja “Construindo o Controller” para

detalhes sobre esse elemento Estrutura básica de configuração:<global-exceptions> <exception type="${ }" key="${ }" path="${ }"/> ...</global-exceptions>

Page 41: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 41

Configurando o Struts Para definição de encaminhamentos

globais, utilize a tag <global-forwards> Veja “Construindo o Controller” para

detalhes sobre esse elemento Estrutura básica de configuração:<global-forwards> <forward name="${ }" path="${ }" redirect="${ }"/> ...</global-forwards>

Page 42: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 42

Configurando o Struts Para definição de ActionMappings, utilize a tag

<action-mappings> Veja “Construindo o Controller” para detalhes

sobre esse elemento Estrutura básica de configuração:<action-mappings> <action path="${ }" type="${ }" name="${ }" scope="${ }" validate="${ }" input="${ }"> <forward name="${ }" path="${ }"/> <exception type="${ }" key="${ }" path="${ }"/> </action> ...</action-mappings>

Page 43: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 43

Configurando o Struts Para configurações do ActionServlet, utilize

a tag <controller> Alguns dos parâmetros antes definidos no

web.xml foram migrados para o <controller> no Struts 1.1

Estrutura básica de configuração:<controller processorClass="${ }" debug="${ }" contentType="${ }" .../>

Page 44: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 44

Configurando o Struts Para configurações do ResourceBundle para

internacionalização da aplicação web, utilize a tag <controller>

Definido no parâmetro application do web.xml no Struts 1.0

Estrutura básica de configuração:<message-resources parameter="${ }" null="${ }" .../>

Page 45: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 45

Configurando o Struts Para configurações de Plug-ins como o

Struts Validator e o Struts Tiles, utilize a tag <plug-in>

Veja “Construindo a View” para detalhes sobre esse elemento

Estrutura básica de configuração:<plug-in classname="${ }"> <set-property property="${ }" value="${ }"/> <set-property property="${ }" value="${ }"/> ...</plugin>

Page 46: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 46

Considerações sobre o SPL Alguns sintomas observados:

Muito código scriptlet no JSP Código mal-estruturado (muitas classes

no mesmo pacote, JSPs misturados, ...) Código de validação espalhado e

inconsistente (alguns JSPs usam JavaScript, outros não, algumas classes efetuam validação, outras não)

Arquivo de configuração muito extenso e difícil de ler

Page 47: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 47

Considerações sobre o SPL Sugestões:

Utilizar melhor as taglibs do Struts nos JSPs Mover código de controle para uma ou mais

Actions Separar a aplicação em módulos para:

Facilitar a estruturação das classes em pacotes bem definidos

Facilitar a estruturação e leitura do arquivo de configuração

Utilizar o Struts Validator para código de validação

Page 48: Java para Web com Struts Danilo Toshiaki Sato dtsato@ime.usp.br Treinamento ALESP – SPL Módulo III

Copyleft 2006 Danilo Sato 48

Dúvidas ou Sugestões?