Captulo 1
Introduo
(R)evoluo
(R)evoluo. Amigos, esta a palavra mais falada pelos desenvolvedores Delphi quando fazem o primeiro contato com a verso 7 do produto. Uns dizem evoluo, outros revoluo. Particularmente acho que o Delphi amadureceu de uma forma extraordinria, e que a equipe de negcios do produto conseguiu quebrar algumas barreiras importantes, como a incorporao de um excelente gerador de relatrios, ou melhor, um poderoso conjunto de componentes conhecido por grande parte dos desenvolvedores Delphi: Rave Report. Como o foco principal deste livro o desenvolvimento de aplicaes e-Business, a maior novidade para os Web-Developers o excelente pacote da empresa Atozed. J ouviram falar em IntraWeb? Agora sim temos uma ferramenta RAD de respeito para o desenvolvimento de aplicaes Web. Veja que no quero desprezar a tecnologia existente desde a verso 3 do produto, nem a nova tecnologia WebSnap, introduzida na verso 6. Pelo contrrio, ainda apio fortemente tais tecnologias, mas ganhamos um forte aliado: IntraWeb. Podem ficar tranqilos, teremos um captulo inteiro sobre o nosso mais novo companheiro. Aproveitando o embalo das apresentaes, no prximo tpico veremos todo o potencial do Delphi 7 em todas as suas distribuies, inclusive da novssima Studio Architect.
Novidades do Delphi 7
Primeiramente, irei apresentar as mudanas na nova verso do Delphi e, em seguida, uma tabela comparativa entre as suas distribuies. Nas mensagens de compilao, poderemos obter novas informaes atravs do site da Borland, com um link direto da mensagem. Maior controle sobre os famosos warnings ou advertncias que so geradas. Uma nova seo System para aplicaes CLX, com diversos controles de diretrios e arquivos. Anteriormente tais controles estavam disponveis somente para aplicaes VCL. Novas implementaes da Nevrona, com melhorias no pacote Indy Components, trazendo Indy Intercepts e Indy I/O Handlers, facilitando ainda mais o desenvolvimento de aplicaes para Internet. O poderosssimo IntraWeb, com as sees IW Standard, IW Data, IW Client Side e IW Control. Para quem reclamava do QuickReport, no pode mais chorar. O Delphi 7 traz consigo o poderoso Rave Reports, com superioridade absoluta em relao ao QR. A cada nova verso, a equipe de desenvolvimento melhora o Code Insight. Agora o code completion (uns dos fortes atrativos do Code Insight) est bem mais rpido, e com inteligncia artificial (este por minha conta). Sem sombra de dvidas ficou bem mais esperto e rpido. 1
2 Delphi 7 Internet e Banco de Dados Temos tambm um code completion para cdigo HTML. Voc tambm poder criar seus prprios administradores code completion, atravs da OpenTools. Para quem no dispensa as Watch Lists, ir babar com as melhorias: mltiplas sees para organizar suas watchs (seus vigilantes, observadores) atravs de grupos. Controle completo sobre a viso das watchs. Possibilidade de compilar projetos por grupo atravs do Project Manager. A seo Message View foi dividida em diversas abas para apresentar diferentes tipos de mensagens (Build, Search, e outros). Agora podemos selecionar mltiplos componentes na opo View/Component List. O editor suporta diferentes tipos de linguagem: Pascal, C++, C#, HTML e XML. Possibilidade de visualizar graficamente tabs e espaos no editor de cdigo. Melhorias para o desenvolvedor Web, com a incluso do IntraWeb (perceberam como estou feliz, s falo nele), suporte ao Apache2 (com todas as suas melhorias e recursos) e excluso do desenvolvimento de aplicaes Win-CGI (16 bits). Um novo browser UDDI para WebServices, e tambm novas classes e interfaces para o SOAP. TSoapAttachments, a grande novidade, onde podemos enviar atravs do SOAP, mensagens com anexo, utilizando multipart form. Tipos de definies so registrados automaticamente. Agora temos um evento poderoso: THTTPReqResp, onde podemos monitorar o pacote de mensagens, enquanto as mesmas so transmitidas. Novos drivers para o dbExpress, trazendo Informix SE, Oracle 9i, DB2 7.2, Interbase 6.5, MySQL 3.23.49, MSSQL2000 (uma das grandes novidades). A Borland desaprova o uso dos SQLLinks, e no disponibiliza mais suporte nas prximas verses do Delphi (aps 2002). Ela recomenda a utilizao da tecnologia dbExpress, que sinceramente, vem melhorando a cada verso. Suporte a Windows XP Themes nas verses Professional e Enterprise. A nova unit DBClientActns, com 3 novas classes: TClientDataSetApply, TClientDataSetUndo, TClientDataSetRevert. E os novos componentes dbExpress: TSimpleDataSet para aplicaes simples e de 2-camadas (TSimpleDataSet substitui TSQLClientDataSet). Diversos componentes visuais e de dilogo para CLX. Melhorias na unit Math. Model-Maker. Para quem nunca ouviu falar em UML, sugiro conhecer esta importante especificao. No Delphi 7, a partir da verso Studio Enterprise, temos uma excelente ferramenta especfica para integrao UML-Delphi-UML. E muito mais.
x x x x x x x x x
Para que voc tenha uma idia de qual verso adquirir, a Borland disponibiliza a sua tabela comparativa. Resolvi adapt-la, fazendo breves comentrios, para que voc tenha uma idia mais clara sobre as diferenas de verses. Nesta tabela so apresentadas somente as novidades do produto. Para maiores informaes, sugiro uma visita ao site da Borland Latin Amrica: www.borland.com.br
Introduo 3
Minha opinio Atualmente estamos vivendo uma fase bem madura de desenvolvimento de software. Antigamente tnhamos aqueles fantasmagricos fluxogramas, passando pela modelagem de dados, e agora, trs vivas: UML (Unified Modeling Language, ou Linguagem de Modelagem Unificada). Ao contrrio dos outros mtodos, a UML uma linguagem de modelagem muito usual em empresas fabricantes de software. E o mais incrvel, foi estendida para outros tipos de segmentos, como automveis, hardwares, empresas de energia, enfim, uma grande variedade. O Model Maker facilita muito o trabalho com UML, integrando totalmente as classes e objetos do Delphi em seu editor. Sugiro a todos que se aprofundem no estudo da UML. Alm dos fortes benefcios, est se tornando uma grande exigncia para desenvolvedores, analistas e coordenadores de projetos, alm, claro, dos gerentes.
Minha opinio Quando tive meu primeiro contato com o IntraWeb pensei: essa a grande soluo para o maior problema: prazo. Amigos, sem sombra de dvidas, o IntraWeb otimiza diversas tarefas no desenvolvimento de aplicaes Web. At mesmo quem no entende nada de HTML, JavaScript, desenvolve poderosas aplicaes Web, com uma interface de primeira. Fico feliz em ter o meu sonho realizado, de aumentar em mais de 30% a produtividade de minhas equipes. E o melhor, no requer um grande treinamento. Com o captulo dedicado a esta incrvel ferramenta, tenho certeza de que todos vocs estaro desenvolvendo aplicaes para Internet com extrema facilidade. Outro ponto bastante importante que a Borland fechou diversas parcerias para o seu novo produto, sempre pensando em disponibilizar o que h de melhor no mercado para ns desenvolvedores.
Introduo 5
Minha opinio Amigos, algum lembra do QuickReport? Eu j esqueci, nem sei do que estamos falando! Brincadeiras parte, finalmente ganhamos um gerador de relatrios bastante profissional. A nossa Me-Borland conseguiu quebrar algumas barreiras para que esse sonho fosse realizado, e todos ns ganhamos com isso. O Rave Reports da inovadora e genial empresa Nevrona (a mesma criadora do Indy Componentes) muito estvel e traz diversos recursos que facilitam a vida do desenvolvedor. Sugiro que criem coragem de aprender um novo gerador de relatrios. Digo isso porque ao longo de minha carreira presenciei diversas pessoas e equipes que relutaram em adotar um novo gerador de relatrios, por diversas crenas: Ser que a empresa que produz o software vai manter a compatibilidade? Ser que a empresa no vai quebrar? Acho muito difcil este software! Entre outras...
IDE
A IDE do Delphi 7 (figura 1.1) muito parecida com a verso anterior. Basicamente mudou o seu visual, muito semelhante ao Windows XP. Vamos dar uma rpida olhadinha.
Figura 1.1 IDE Delphi 7 Como este livro est voltado para o desenvolvimento de aplicao para Internet, vamos conhecer algumas novidades. A figura 1.2 ilustra a nova seo de objetos Web Documents. Sua principal funo de auxiliar na criao dos principais tipos de documentos Web.
Figura 1.2 Nova seo Web Documents Outra grande novidade o nosso amigo Intraweb (figuras 1.3, 1.4, 1.5, 1.6 e 1.7) que ganhou um captulo inteiro neste livro.
Introduo 7
Figura 1.7 Paleta IW Control (IntraWeb) Amigos, d pra imaginar o poder do IntraWeb, com mais de 50 componentes nativos, no padro CLX, s para o desenvolvimento de aplicaes Web? Vocs devem estar pensando: nossa, eu nem aprendi tudo o que o Delphi me oferece de recursos e os caras disponibilizam mais poder, mais novidades! Ser que eu vou aprender tudo isso? Eis a questo. Por isso um livro especializado em Internet, focado no desenvolvimento de aplicaes e-Business. E o j consagrado WebSnap? Uma das estrelas da verso 6, ganhou algumas melhorias e as devidas correes dos pequenos bugs. A figura 1.8 ilustra os componentes do WebSnap.
Figura 1.8 Paleta WebSnap E a moda do momento? WebServices na veia. A tecnologia de WebServices j est sendo utilizada, mesmo que timidamente, em diversos setores, e far mais sucesso ainda com as ferramentas que vm surgindo no mercado. A figura 1.9 ilustra a seo de WebServices do Delphi 7, e a figura 1.10, a paleta de componentes.
Introduo 9 Amigos, tivemos uma breve apresentao dos novos recursos do Delphi 7 na rea de desenvolvimento para Web. A seguir teremos uma introduo bastante importante sobre o desenvolvimento de aplicaes e-Business, bem como sobre o Mtodo Facunte.
MEADOS
80 a 90 91 a 94 94 a 97 98 e 99 00 a 01
PLATAFORMA (*)
Unix, IBM, DOS DOS, Windows DOS, Windows Windows, Internet Windows, Linux, Internet, Intranet, Extranet Cross-plataform, objetos distribudos
LINGUAGENS/FERRAMENTAS
Cobol, Dataflex, C, C++, Clipper DataFlex, Clipper, Fox, Visual Basic Clipper, Visual Basic, Delphi Visual Basic, Delphi, ASP, PHP Visual Basic, Delphi, Kylix, ASP, PHP, ColdFusion, Java . NET, Delphi, Kylix, Corba (ORB), Java, SOAP, SNAP (Web Services)
02 tendncias
Como observamos na Tabela 1, o mercado evoluiu muito aps a dcada de 90, tornando confusa a deciso do desenvolvedor na escolha da melhor tecnologia. Para ajudar os desenvolvedores da velha-guarda, bem como os da nova-gerao, foi criado o MTODO FACUNTE (falaremos do mtodo em seguida). Bem, Mtodo parte, falaremos da forte tendncia para esta dcada que, conforme a Tabela 1, o desenvolvimento Cross-Plataform e Objetos Distribudos. Mas o que so estas novas tecnologias? Ser que so novas mesmo? Vamos iniciar pela tendncia Cross-Plataform. Cross-Plataform quer dizer que a aplicao roda em duas ou mais plataformas. Isso excelente, j que estamos num mercado bastante disputado; Windows melhorando, Linux cativando grandes legies de adeptos, e quem sabe o Lindows1 avana no mercado. Agora vamos imaginar nossa aplicao sendo executada em qualquer ambiente operacional. No timo? J pensou em oferecer ao seu cliente um produto Cross-Plataform? Tenho certeza de que aumentaro muito as chances de vender o produto. OK, e os Objetos-Distribudos? Bem, esse o ponto. Vamos imaginar o seguinte cenrio:
1
Aplicao de Controle de Estoque sendo acessada pela LOJA. Faturamento acessando informaes de Vendas.
Lindows Sistema operacional baseado no LINUX, que traz consigo a tecnologia WINE (kernel para execuo de aplicaes baseadas em Win32).
10 Delphi 7 Internet e Banco de Dados Financeiro gerenciando Faturamento e Contas a Pagar. Diretoria gerenciando todo o sistema. Clientes consultando e fechando pedidos atravs da Internet. Setor de compras fechando pedidos com Fornecedores. Compensao automtica de crdito/dbito da Rede Bancria. Vendedores externos fechando negcios com PALM TOPS.
Sem dvida um sistema dos sonhos de qualquer empresrio e desenvolvedor. Agora imagine efetuar uma manuteno no sistema sem interromper as atividades normais (no v pensar em atualizar o sistema as 02:00 da manh, hein?! Isso no tudo). Vamos melhorar o nosso lado? Com a tecnologia de Objetos-Distribudos podemos criar diversas camadas: Camada de Negcios Camada da Aplicao Cliente Camada da Aplicao Servidor Camada Aplicao Servidor-WEB Camada Banco de Dados entre outras Para realizar as tarefas de manuteno no sistema, o desenvolvedor poder alterar apenas a camada que satisfaz a ocasio. Outro fator bastante interessante que as camadas podem e devem ficar em servidores diferentes, especficos para cada camada. Tudo bem Facunte, mas o que a tecnologia de desenvolvimento WEB tem a ver com tudo isso? Isso mesmo: TUDO! Bem, quando nos referimos a Cross-Plataform imaginamos que os nossos clientes pudessem executar a mesma aplicao em diversas plataformas, certo? Ento temos aqui um caso tpico de Cross-Plataform tudo bem, no nvel de Client e no Server eu explico: Desenvolver uma aplicao com a tecnologia WEB utilizando o Delphi, a mesma poderia ser executada num servidor Windows NT e qualquer equipamento (micro-computador, PALM, Celular, etc. acessaria a aplicao, mesmo que o sistema operacional no fosse Win X. Exemplo: Linux, Mac OS, Solaris, celulares com browser baseado em JAVA (esquea WAP por enquanto), PALM com acesso Internet, entre outros. Viram que magnfico? Em resumo, o objetivo deste livro o desenvolvimento de uma Camada Web, uma das grandes tendncias desta dcada.
Mtodo FACUNTE
O Mtodo Facunte foi criado em 2001 inspirado nas necessidades de desenvolvedores iniciantes e dos amigos da velhaguarda que no tinham base formada sobre qual tecnologia adotar. O mtodo consiste num treinamento completo para o desenvolvedor, abrangendo desde as tendncias do mercado, passando por orientaes financeiras de projeto, at o desenvolvimento prtico de uma aplicao, utilizando ferramentas de alta tecnologia e comumente aceitas como padro de mercado. No diagrama a seguir temos a representao grfica do mtodo.
Introduo 11
Sucesso Mtodo Facunte Desenvolvimento Como e Quanto Cobrar do Cliente Definio do Projeto
Devemos esquecer alguns costumes do mtodo tradicional, como por exemplo: Grids; Barras de navegao entre registros; Botes de funes para todos os lados; Sobreposio excessiva de janelas.
Os referidos costumes degradam muito a performance do servidor de aplicaes e de banco de dados, alm de confundir o usurio em alguns aspectos. Outra coisa bastante interessante que a maioria dos desenvolvedores quer trazer para a web uma interface parecida com seu sistema tradicional. Isso pode custar caro, pois exige um esforo grande de desenvolvimento. Para tanto, recomendo um novo conceito de interface, que veremos ao longo do livro. Vejam que isso apenas um exemplo, que na minha opinio deve ser seguido, mas novos conceitos devero ser criados, e at mesmo outros tipos de interfaces existentes no mercado devem ser analisadas. Procure sempre o melhor para o usurio.
cargo desenvolvedor jr desenvolvedor pleno desenvolvedor snior Gerente de projetos arquiteto web consultor
desenvolvedor tradicional R$ 800 a R$ 1200 R$ 1000 a R$ 2000 R$ 2000 a R$ 4000 R$ 2000 a R$ 6000 R$ 20 a R$ 50/hora
desenvolvedor web R$ 1200 a R$ 1800 R$ 1800 a R$ 3500 R$ 3000 a R$ 8000 R$ 4000 a R$ 12000 R$ 6000 a R$ 10000 R$ 40 a R$ 130/hora
TABELA 2 pesquisa salarial realizada nos principais sites de RH (Grupo Catho, AP Info, Canal de Empregos, Manager) A demanda de desenvolvedores web ainda muito pequena, e a oferta de trabalho muito grande, por isso temos esse cenrio. Claro que aqueles que entrarem antes no mercado sero altamente beneficiados. No se assustem com as quebradeiras das empresas pontocom, pois este tipo de trabalho no se restringe a este seguimento. O que estamos mostrando aqui que qualquer empresa pode contratar os servios de um desenvolvedor web, desde a lojinha de autopeas da esquina, at as grandes corporaes.
Introduo 13 Nunca faa leilo comum o seu cliente querer reduzir o valor de sua proposta, apresentando outras de seus concorrentes. Casos absurdos de reduo de 50, 60 e at 70% so comuns. Acredito num valor de reduo mximo de 20% e o ideal em 10%.
Tudo bem, Facunte, mas como definir os custos de um projeto? Minha sugesto a seguinte: Defina seu valor hora, entre R$ 40 e R$ 60 (sessenta reais). Baseado em sua experincia, calcule o tempo necessrio para desenvolver a aplicao, em nmero de horas e multiplique por 2,5. Caso haja a necessidade de outros membros no desenvolvimento do projeto, faa a adequao em nmero de horas e acrescente 20% por membro. Acrescente os impostos. E finito, encaminhe a proposta ao cliente.
Veja um exemplo prtico: Minha estimativa em horas do projeto Tempo necessrio Prazo estimado pelo cliente O prazo fornecido pelo cliente forou-me a Introduzir mais 3 membros na equipe : 500 horas : 500 horas x 2,5 = 1.250 h : 2 meses : 1.250h + 60% = 2.000 h (60% = 20% por membro) : R$ 40,00 : 2.000 x R$ 40,00 = R$ 80.000,00
Repare, o que pesou no valor final do projeto foi o prazo estipulado pelo cliente, seno teramos um valor bem mais atraente, em torno de R$ 45.000,00. Lembre-se de estimar as horas baseadas em sua experincia, e no faam leiles com o seu valor hora. Obviamente numa fbrica de software virou moda este nome so utilizados recursos mais avanados para avaliao de valores.
Costumo dizer que, aps a modelagem de dados, desenvolver fica fcil. Digo isso porque o corao da aplicao a modelagem. Uma boa modelagem igual a uma boa aplicao, j uma razovel modelagem igual a uma semente frutfera de
14 Delphi 7 Internet e Banco de Dados problemas. Com a modelagem em mos, o gerente poder iniciar os trabalhos com cadastros bsicos e design, lembrando que a modelagem de dados deve ser baseada na anlise de negcios. Os testes devero ser iniciados paralelamente ao desenvolvimento dos cadastros bsicos, assim como o ncleo do projeto (caso haja um responsvel por esta rea, seno, somente aps a concluso dos cadastros bsicos). O prximo tpico complementa as dicas sobre gerenciamento de equipes.
MS Project
O Microsoft Project o melhor gerenciador de projetos que conheo. Com ele podemos gerenciar diversas equipes ao mesmo tempo, conseqentemente diversos projetos (mesmo que por equipe), definir metas e analisar grficos de desempenho por fases, projetos e equipes. O projeto compartilhado entre os membros da equipe, facilitando assim o andamento do mesmo, mostrando as deficincias e tambm toda a eficincia da equipe. Recomendo para todos os tamanhos de projeto, e acredito ser indispensvel para grandes projetos.
ERWin
Quem nunca ouviu falar da fantstica ferramenta de modelagem de dados ERWin? Hoje pertence a CA (Computer Associates) que tem investido muito para melhoria da ferramenta. O ERWin gera scripts SQL para a maioria dos bancos de dados comerciais, como Oracle, SQL Server, Interbase, Sybase, DB2, Progress, Informix, entre outros. Para pequenos desenvolvedores no recomendo, devido ao seu alto custo (CA, no fique brava comigo, mas a dura realidade), mas para mdios e grandes indispensvel. A Squadra, empresa 100% nacional, fabricante de uma tima ferramenta de modelagem de dados: Dr Case. Alm do preo bastante atraente, a ferramenta traz consigo timos recursos para o trabalho com os principais bancos de dados (recomendo para quem utiliza diversos tipos de banco de dados). Existem produtos alternativos especficos para Interbase, como o fantstico IB Admin, da SQLLY (www.sqlly.com) com um custo bastante atraente, e com diversos recursos de gerenciamento do Interbase (altamente recomendvel para quem utiliza Interbase).
UML
Para quem quer qualidade total em seus projetos, recomendo o trabalho baseado em UML (Unified Modeling Language, ou Linguagem de Modelagem Unificada). S para ter uma idia, alm das grandes empresas de software, esto adotando UML indstrias automobilsticas (GM, Ford), fabricantes de hardware (Intel, EPSON, HP, Compaq), entre outras. Mas o que UML? E quais as suas vantagens? Em resumo, UML a unificao dos mtodos Booch, OMT e OOSE, padronizando a modelagem de sistemas de software orientados a objetos, entre outras aplicaes. Hoje em dia, a recomendao bsica para desenvolvimento de sistemas a utilizao de todo o poder da orientao a objetos. A UML colabora muito para a organizao e documentao de projetos orientados a objeto. Para entender melhor o UML, recomendo a leitura do livro Desenvolvendo Aplicaes com UML da Brasport. Mas falar de UML sem falar de sua principal ferramenta, realmente um deslize. Ao meu ver, no existe ferramenta melhor que o Rational Rose da empresa Rational (www.rational.com.br). Todas as especificaes da UML so encontradas na ferramenta, alm da integrao com as principais linguagens de desenvolvimento do mercado. E como agora ganhamos o Model Maker, lets go, friends!!!
TeamSource
A Borland disponibiliza uma excelente ferramenta de controle de verses e de trabalho em equipe: a TeamSource. Com esta ferramenta possvel gerenciar inmeras verses do projeto, alm de organizar o desenvolvimento em grupo, permitindo que inmeros desenvolvedores participem do mesmo projeto. Maiores informaes www.borland.com.br
Introduo 15
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 2
Aplicaes Servidoras
O que so
As aplicaes servidoras so responsveis pelo processamento das informaes no servidor WEB, e a gerao das informaes em formato HTML, ou outro designado pelo desenvolvedor. As Aplicaes Servidoras so responsveis pela comunicao entre um Servidor HTTP e o cliente. No captulo de servidores WEB, encontramos uma representao grfica das aplicaes servidoras.
Principais exemplos
Grandes instituies financeiras utilizam aplicaes servidoras para disponibilizar tecnologia Internet Banking aos seus clientes. Bradesco e Ita so bons exemplos. Atualmente empresas de mdio e grande porte utilizam aplicaes servidoras em seus sistemas ERP e CRM. O Delphi fornece diversas formas de desenvolver tais aplicaes. So elas: CGI, WINCGI, ISAPI/NSAPI, Apache Modules.
CGI
CGI (Common Gateway Interface) um padro muito utilizado pela maioria dos servidores WEB. As aplicaes CGI so criadas com a extenso EXE, solicitando ao sistema operacional a criao de um novo processo a cada execuo, ou seja, para cada execuo o sistema operacional aloca memria no servidor, tornando-o bastante carregado. Facunte, ento por que o CGI bastante utilizado, j que o mesmo escraviza o servidor? A resposta muito simples. Em servidores UNIX as aplicaes CGI so bem rpidas e leves, pois os processos no UNIX no escravizam o servidor como acontece em sistemas operacionais baseados em WIN32. A comunidade Apache.org trabalhou muito neste caso e disponibilizou, no seu servidor web, o Apache Server, um trabalho semelhante para qualquer plataforma, seja ela baseada em UNIX ou Win32.
WINCGI
WinCGI, na realidade, uma extenso do padro CGI. Foi criado para aproveitar algumas caractersticas dos sistemas operacionais baseados no Padro WIN 3x. 16 bits. Este padro no muito utilizado, devido ao baixo nmero de Servidores Web que o interpretam (no confunda sistema operacional com servidor web). No Delphi 7 este padro foi descontinuado, apenas oferecendo suporte na compilao. 16
Aplicaes Servidoras 17
ISAPI
O ISAPI (Internet Server Application Programming Interface) foi criado pela Microsoft para o desenvolvimento de contedo dinmico em servidores Web. A principal diferena entre ISAPI e CGI justamente a forma de implementao, onde o CGI gerado no padro EXE, e o ISAPI gerado no padro DLL. Portanto, os processos gerados pelo ISAPI so bem mais leves pelo fato de serem DLLs. Como visto anteriormente, o Apache disponibiliza mdulos que tratam o CGI de maneira semelhante ao ISAPI. Toda vez que uma aplicao ISAPI solicitada ao servidor Web, o mesmo cria um novo thread (um padro de processamento muito utilizado nos sistemas operacionais Win32).
NSAPI
O NSAPI (Internet Server Application Programming Interface) trabalha de forma bastante parecida com o padro ISAPI. Pelo fato de ter sido desenvolvido pela NETSCAPE (www.netscape.com), este padro pouco reconhecido pelos servidores Web.
Padres de Mercado
Sem sombra de dvidas o CGI se tornou padro de mercado pela sua enorme flexibilidade tanto em desenvolvimento como em gerenciamento. Alm do padro EXE gerado pelo Delphi (que j traz consigo todo o ncleo, desde o projeto at as bibliotecas necessrias para a sua execuo), existem outros padres gerados atravs de linguagens como o PERL (o preferido no mundo UNIX), C++, entre outras. Tudo bem Facunte, mas o que o Delphi tem que as outras linguagens no tm? A resposta simples: alta tecnologia disposio do desenvolvedor. Com uma enorme biblioteca de componentes nativos, alm dos milhares de componentes de terceiros, uma excelente gama de funes de manipulao de banco de dados, funes matemticas, dentre outras.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Servidores Web 19
Captulo 3
Servidores Web
Viso Geral
Os servidores web foram projetados para atender a diversas necessidades do mundo WEB, dentre as quais podemos destacar: HTTP (o mais comum) Servidor POP3 e SMTP (correio eletrnico) FTP (gerenciamento de arquivos) entre outros
Aqui falaremos apenas no servio HTTP. A ilustrao a seguir demonstra o trabalho de um servidor HTTP.
19
20 Delphi 7 Internet e Banco de Dados Como vimos na Figura 3.1, o servidor HTTP responsvel pelo processo de recebimento e envio de informaes. Na realidade ele recebe a requisio do cliente (browser), passa a informao aplicao servidora (CGI), e transmite ao cliente a resposta gerada pelo CGI. O mais interessante de tudo isso que o servidor HTTP pode responder s solicitaes de uma rede local, no havendo necessidade da mesma possuir acesso Internet. No mercado existem diversos servidores HTTP para as mais variadas necessidades. Por exemplo: uma empresa que queira disponibilizar aplicaes CGI na Internet para um nmero ilimitado de usurios, necessitar de um excelente servidor, o Apache Server ou at mesmo o IIS da Microsoft. Em caso de disponibilidade apenas para a rede local, existe Xitami, e o OMNIHTTPd. E para desenvolvedores, o mais conhecido o TINY, totalmente desenvolvido em Delphi e com cdigo fonte disponvel. Vamos conhecer um pouco das caractersticas de cada um deles.
IIS
O IIS (Internet Information Server) da Microsoft bastante utilizado em servidores NT. Possui um timo gerenciador, facilitando muito a vida do administrador. Como o seu uso est restrito somente a servidores baseados em Windows NT, perdeu uma enorme fatia no mercado, alm das inmeras vulnerabilidades descobertas a todo o momento. Claro que a Microsoft trabalha rpido para fechar as portas do IIS, mas devido a outras brechas no Windows NT, fica difcil tornar o IIS seguro.
Apache
Amigos, este o queridinho dos administradores de rede. Atualmente est no topo em nmero de servidores, justamente pelo fato de rodar na maioria das plataformas: Windows, Linux, Unix, Solaris, IBM-AIX, HP-UX, entre outras. O Apache um software livre, com cdigo fonte aberto, e a cada semestre surpreende os administradores de
rede, com verses magnficas. Claro que nem tudo so flores, e o Apache tambm tem suas vulnerabilidades; logicamente no Windows mais vulnervel e em outras plataformas muito menos. No possui interface de configurao apenas de terceiros mas sua configurao bastante simples. A dificuldade cresce conforme a necessidade do servidor; por exemplo: um servidor que mantm diversos sites hospedados necessita de uma configurao mais complexa. Altamente recomendvel, pode ser executado at mesmo para testar nossas aplicaes, o que faremos com enorme satisfao neste livro. O Apache um dos produtos da Apache Org e poder ser encontrado no endereo www.apache.org
Xitami
O Xitami um timo servidor HTTP pessoal. Isso mesmo, pessoal. Embora a empresa fabricante do Xitami coloca um time de craques para melhorar o produto, ainda no chegou num nvel comercial pelo menos este meu ponto de vista, ou meu modo de vista como diz uma figurinha global com o apelido de Bam-Bam. Para uma rede local
excelente, pois de fcil configurao e traz consigo alguns recursos interessantes, como o personal proxy. Para maiores informaes, visite o site do fabricante: www.xitami.com
TINY
Amigos, este o menor servidor HTTP que conheo, e o seu nome TINY (minsculo) faz jus ao seu tamanho. Desenvolvido em Delphi e com cdigo fonte aberto, o TINY recomendado para desenvolvedores testarem a sua aplicao, ou at mesmo para pequenas redes locais, com no mximo 20 computadores.
Servidores Web 21
Figura 3.2 Tela Inicial da Instalao do Apache A figura 3.2 ilustra a tela inicial da instalao do Apache. Para prosseguir, pressione o boto Next. Em seguida, como ilustra a figura 3.3 necessrio aceitar os termos de instalao do Apache, selecionando a primeira opo I accept ... e pressionando o boto Next para prosseguir.
22 Delphi 7 Internet e Banco de Dados Em seguida, todas as novidades e informaes sobre o Apache, so apresentadas. A figura 3.4 ilustra este passo. interessante acessar as ltimas novidades do Apache a cada ms, pois alm de uma super-verso 2 estar a caminho (no momento em que escrevia este livro encontrava-se na verso Beta 2.08), outras novidades so implementadas. Pressione Next para prosseguir.
Figura 3.4 Informaes sobre o Apache O prximo passo bastante importante, pois iremos configurar os dados do nosso servidor. Como ilustra a figura 3.5 devemos preencher as seguintes informaes: Network Domain Server Name Administrator Email Informe o domnio da sua rede. Exemplo: facunte.com Informe o nome do seu servidor. Exemplo: elvis Informe o email do administrador. Exemplo: emerson@facunte.com.br
Servidores Web 23 Em seguida devemos optar entre a instalao completa e a customizada. Em nosso caso recomendo a instalao completa. J em caso de servidores comerciais, recomendo a instalao customizada, de forma que possamos eliminar alguns arquivos desnecessrios, como documentao do Apache. Clique em Next para prosseguir.
Figura 3.6 Tipo de configurao. Agora basta clicar no boto Install para dar incio instalao conforme nossa configurao. A figura 3.7 ilustra este momento.
Figura 3.7 Incio da Instalao Aps finalizada a instalao, reinicie o Windows para que o mesmo reconhea o Apache e estabelea o servio de HTTP. Caso voc esteja utilizando Windows 98x (SE, ME), clique em Start no grupo de programas do Apache e o mesmo ser executado em modo console. Para testar o Apache e ver se est tudo ok, entre no seu browser e digite no endereo URL: http://localhost Devero aparecer informaes sobre o Apache Server como ilustra a figura 3.8.
Figura 3.8 Teste do Apache Aps a instalao do Apache, devemos configur-lo para servir uma rede local. No grupo de menus do Apache, temos a seo Configure Apache Server, e dentro desta seo temos a opo Edit the Apache httpd. configuration file. Clique nesta opo e caso o Windows questione sobre qual tipo de programa utilizar para abrir o arquivo, selecione Bloco de Notas, ou NotePad. Ao abrir o arquivo, temos algo parecido com a figura 3.9.
Figura 3.9 httpd.conf Repare que um arquivo no padro texto (ASCII) de fcil edio. Localize a seo de configurao ServerName; veja o quadro a seguir. # # # # # # # # #
ServerName allows you to set a host name which is sent back to clients for your server if it's different than the one the program would get (i.e., use "www" instead of the host's real name). Note: You cannot just invent host names and hope they work. The name you define here must be a valid DNS name for your host. If you don't understand this, ask your network administrator. If your host doesn't have a registered DNS name, enter its IP address here.
Servidores Web 25 # You will have to access it by its address (e.g., http://123.45.67.89/) # anyway, and this will make redirections work in a sensible way. # # 127.0.0.1 is the TCP/IP local loop-back address, often named localhost. Your # machine always knows itself by this address. If you use Apache strictly for # local testing and development, you may use 127.0.0.1 as the server name. # ServerName 127.0.0.1
Em ServerName coloque o IP 127.0.0.1. Repare que o simbolo # utilizado como comentrio no Apache. Neste ponto configuramos o IP ou NOME do nosso Servidor. Como o prprio Apache recomenda, utilizamos o IP 127.0.0.1 para testes e desenvolvimento. O prximo passo configurar o diretrio de scripts, onde executaremos nossas aplicaes servidoras. Localize a seo ScriptAlias como mostra o quadro a seguir. # # ScriptAlias: This controls which directories contain server scripts. # ScriptAliases are essentially the same as Aliases, except that # documents in the realname directory are treated as applications and # run by the server when requested rather than as documents sent to the client. # The same rules about trailing "/" apply to ScriptAlias directives as to # Alias. # ScriptAlias /cgi-bin/ "C:/cursoweb/cgi-bin/" Neste ponto indicamos o diretrio de execuo de scripts, apontando para C:/cursoweb/cgi-bin. Para finalizar nossa configurao no Apache, devemos criar nosso VirtualHost. Esta seo encontra-se no final do arquivo, como segue: # # VirtualHost example: # Almost any Apache directive may go into a VirtualHost container. # The first VirtualHost section is used for requests without a known # server name. # #<VirtualHost *> # ServerAdmin webmaster@dummy-host.example.com # DocumentRoot /www/docs/dummy-host.example.com # ServerName dummy-host.example.com # ErrorLog logs/dummy-host.example.com-error_log # CustomLog logs/dummy-host.example.com-access_log common #</VirtualHost> <VirtualHost localhost> ServerAdmin emerson@facunte.com.br DocumentRoot c:/cursoweb ServerName localhost </VirtualHost> Grave as configuraes do Apache e selecione a opo Restart no grupo de opes. No diretrio C:/cursoweb dever conter o arquivo index.htm, que ser o principal. Nos tpicos seguintes iremos abordar o uso de protocolos HTTP, TCP-IP, bem como o aprendizado do HTML.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Aplicaes Servidoras 27
Captulo 4
Protocolos
Viso Geral
Protocolo a linguagem utilizada para troca de informaes entre computadores. Existem diversos tipos de protocolos, tais como: TCP, IP, TCP/IP, FTP, HTTP, SMTP, etc. Vejamos um breve resumo dos principais protocolos.
TCP/IP
O protocolo TCP/IP na realidade a juno do protocolo TCP (Transmission Control Protocol) com o protocolo IP (Internet Protocol). Hoje o principal protocolo de transmisso entre redes de computadores, seja via Internet, Local, Intranet ou Extranet.
HTTP
O protocolo HTTP (Hyper Text Transfer Protocol) responsvel pela integridade entre o servidor Web (HTTP) e os clientes (browsers).
FTP
O protocolo FTP (File Transfer Protocol) possui funes semelhantes ao Explorer do Windows (alguns iro achar que estou exagerando). Atravs dele podemos transferir arquivos entre servidores e clientes (download e upload), eliminar arquivos, criar diretrios, enfim, operaes bsicas comumente encontradas no Explorer do Windows.
SMTP
O protocolo SMTP (Simple Mail Transfer Protocol) utilizado para enviar mensagens de correio eletrnico para servidor SMTP.
POP
O protocolo POP (Post Office Protocol), utilizado para extrair mensagens de servidor POP3. O servidor POP3 tem como principal funo armazenar as mensagens distribudas pelo servidor SMTP. 27
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
HTML 29
Captulo 5
HTML
A linguagem HTML (HyperText Markup Language) padro para publicao de documentos na Internet. Todos os browsers (navegadores como, Netscape, Internet Explorer, Mosaic, NeoPlanet, entre outros) possuem interpretao de comandos HTML. Existem diversas verses para o padro HTML, neste livro trabalharemos com a verso 4.
Estrutura Bsica
Um documento HTML possui basicamente dois conjuntos de informaes: Contedo Informao a ser visualizada; Tags Comandos a serem interpretados pelo browser. Exemplo: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> Corpo do texto </BODY> </HTML>
29
30 Delphi 7 Internet e Banco de Dados A figura 5.1 demonstra o resultado do nosso primeiro exemplo.
TAGS Bsicos
<HTML> Estrutura HTML Para definir o incio e o fim de um documento HTML, utilizamos esta expresso: <HTML> para definir o incio, e </HTML> para definir o fim do documento. Repare na TAG que define o fim do documento </HTML>, ela possui uma barra (/) antes do comando HTML, e isso define o fechamento do documento. <HEAD> Cabealho do Documento Para definir o cabealho do documento, utilizamos a TAG <HEAD>. <HEAD> para definir o incio do cabealho, e </HEAD> para definir o fim do cabealho.
<TITLE> Ttulo do Documento Para definir o ttulo do documento (aparece na barra de ttulo do browser) , utilizamos a TAG <TITLE>. <TITLE> para definir o incio do cabealho, e </TITLE> para definir o fim do cabealho.
Exemplo:
<TITLE> Facunte On-Line </TITLE>
HTML 31 <BODY> Corpo A TAG <BODY> define o corpo do documento, ou seja, a localizao do contedo do documento. Esta TAG possui alguns atributos, como mostra a Tabela 5.1. ATRIBUTO DESCRIO
BackGround
BGColor Link Alink Vlink Text Exerccio 1:
Exibe uma imagem de fundo para a pgina HTML. Define a cor de fundo do documento Define a cor do Link Define a cor dos Links ativos Define a cor dos Links j visitados Define a cor do texto Tabela 5.1 Atributos da TAG <BODY>
Crie um novo arquivo com o nome exercicio1.html e siga o exemplo: <html> <head> <title>Mtodo Facunte</title> </head> <body bgcolor="#FFFFFF" background="imagens/logo.jpeg"> </body> </html> Repare que estamos utilizando uma figura como fundo do nosso documento HTML (logo.gif), localizado no subdiretrio IMAGENS. Faa o exerccio com outros tipos de imagens, do tipo GIF ou JPEG. A figura 5.2 ilustra o resultado do nosso exerccio. <H> ENFATIZANDO TEXTO Para enfatizar um determinado texto, utilizamos a TAG <H>, a qual chamamos de Header. Esta TAG possui seis tipos de Headers numerados de 1 a 6 <H1>, <H2>...<H6>
Figura 5.2 Exerccio 1 Exerccio 2: <HTML> <HEAD> <TITLE>Ttulo </HEAD> <BODY> <H1> Testando <H2> Testando <H3> Testando <H4> Testando <H5> Testando <H6> Testando </BODY> </HTML>
do Documento</TITLE>
H1 H2 H3 H4 H5 H6
Faa o exerccio anterior, e fique vontade para alterar a posio, bem como o texto. Grave o arquivo como exercicio2.html. Sugiro que utilizem os recursos at aqui apresentados. A figura 5.3 ilustra nosso exemplo.
HTML 33 <P> Pargrafos As TAGS <P> e </P> servem para iniciar e finalizar um pargrafo. A TAG <P> possui o atributo <ALIGN> para alinhar o texto, conforme a tabela 5.2.
VALOR
DEFINIO
Alinha o pargrafo esquerda Alinha o pargrafo direita Alinha o pargrafo no centro Justifica o pargrafo (alguns browsers no aceitam este valor) Tabela 5.2 Vvalores do atributo ALIGN
Com base no exemplo que segue, faa o exerccio 3 utilizando os recursos at aqui apresentados, criando quatro pargrafos diferentes com textos de livre expresso. Grave o arquivo como exercicio3.html A figura 5.4 ilustra nosso exemplo. Exerccio 3: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P>Pargrafo sem a utilizao do atributo ALIGN</P> <P ALIGN=CENTER>Pargrafo com atributo ALIGN=CENTER</P> <P ALIGN=RIGHT>Pargrafo com atributo ALIGN=RIGHT</P> <P ALIGN=LEFT>Pargrafo com atributo ALIGN=LEFT</P> <P ALIGN=JUSTIFY>Pargrafo com atributo ALIGN=JUSTIFY. Para isso estamos utilizando um pargrafo mais longo para ver o efeito de sua utilizao.</P> </BODY> </HTML> <BR> QUEBRA DE LINHA Para definir uma quebra de linha necessrio a utilizao da TAG <BR>. Pois ao contrrio do que parece, o browser no trata os espaos em branco criados atravs da tecla <ENTER>. Veja o exemplo a seguir onde utilizamos dois blocos, sendo o primeiro sem a TAG de quebra de linha, e o segundo utilizando a TAG <BR>.
Figura 5.4 exerccio 3 (tag <P>) Exerccio 4: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P>Pargrafo sem a utilizao da TAG (BR) Segunda linha. Terceira Linha.</P> <P>Pargrafo com a utilizao da TAG (BR) Segunda linha.<BR> Terceira Linha.</P> </BODY> </HTML>
<BR>
Com base no exemplo, faa o exerccio 4 criando dois pargrafos diferentes, sendo o primeiro sem a utilizao da tag <BR> e o segundo com a tag. No se esqueam de utilizar os recursos j apresentados. A figura 5.5 ilustra o nosso exemplo.
HTML 35
Formatando o Texto
Algumas TAGs definem a formatao do texto, como tlico e negrito. Utilizamos a TAG <I> para definir a formatao do texto em itlico e a TAG <B> para definir a formatao em negrito. Exemplos: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P><I>Texto em Itlico</I></P> <BR> <P><B>Texto em negrito</B></P><BR> <P><I><B>Texto em itlico e negrito</I></B></P><BR> <P>Podemos utilizar as <I>TAGs</I> de <B>formatacao</B> texto</P> </BODY> </HTML> A figura 5.6 ilustra o nosso exemplo.
em
qualquer
parte
do
Figura 5.6 Exemplo de Formatao Existem outras TAGs de formatao, como demonstra a tabela 5.3.
TAG
FORMATAO
<BIG> <SMALL>
TAG
FORMATAO
Para sublinhar o texto Para riscar o texto Para texto SUBescrito Para texto SOBrescrito
Tabela 5.3 TAGs de formatao
<HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P><BIG>Texto formatado na TAG ### BIG ### TEXTO GRANDE</BIG></P> <P><SMALL>Texto formatado na TAG ### SMALL ### TEXTO PEQUENO </SMALL></P> <P><U>Texto formatado na TAG ### U ### TEXTO SUBLINHADO</U></P> <P><STRIKE>Texto formatado na TAG ### STRIKE ### TEXTO RISCADO</STRIKE></P> <P>Texto formatado na TAG ### SUB ### Exemplo : H<SUB>2</SUB>O TEXTO SUBESCRITO</P> <P>Texto formatado na TAG ### SUP ### Exemplo : M<SUP>3</SUP> TEXTO SOBRESCRITO</P> </BODY> </HTML> Agora com as tags de formatao devidamente apresentadas, faa o exerccio 5 utilizando-as da melhor maneira possvel. Com um texto de livre pensamento, que poder torn-lo um poeta, quem sabe? A figura 5.7 ilustra o nosso exemplo.
Um recurso bastante utilizado por web-designers a alterao dos tipos de fontes, conforme a ocasio. Atravs da tag <FONT> alteramos as caractersticas de fontes de um determinado pargrafo ou at mesmo de todo o corpo do documento. Os seguintes atributos complementam a TAG <FONT>.
ATRIBUTO DESCRIO
Define a cor da Fonte Define o tipo da Fonte Define o tamanho da Fonte (de 1 a 7) O tamanho tambm poder ser definido por pixel size. Tabela 5.4 Atributos da TAG <FONT>
Exemplos: <html> <head> <title>Mtodo Facunte</title> </head> <body bgcolor="#FFFFFF"> <p> </p> <p><font size="2">Fonte Default</font></p> <p> <font face="Arial">Fonte Arial</font></p> <p><font face="Verdana">Fonte VERDANA</font></p> <p><font face="Trebuchet">Fonte TREBUCHET</font></p> </body> </html> A figura 5.8 ilustra o nosso exemplo. Como exerccio, proponho a criao de um documento HTML com a utilizao dos tipos de fontes conhecidas, bem como a formatao de pargrafos com diversos alinhamentos, e por fim variadas formataes de textos.
Figura 5.9 Exerccio 6 Veja a seguir o exemplo que utilizei para criar o exerccio 6. <html> <head> <title>Mtodo Facunte</title> </head> <body bgcolor="#FFFFFF"> <p align=CENTER><font face="Verdana" size="3"><B>Exerccio 6</B></font></p> <p align=RIGHT> <font face="Arial"><I>Fonte Arial com formatao itlica</I></font></p> <p align=LEFT> <font face="Verdana"><B><I>Fonte VERDANA com negrito e itlico</I></B></font></p>
HTML 39 <p align=CENTER><font face="Trebuchet" size="7">Fonte TREBUCHET com tamanho 7</font></p> </body> </html> <HR> Linhas Horizontais Para criar linhas horizontais utilizamos a TAG <HR>. Normalmente utilizamos esta TAG para separar blocos de texto, formulrios e imagens. Atributos da TAG <HR>
ATRIBUTO
DESCRIO
Width
Define o tamanho da linha em percentual % ou em pixel. Define a altura (espessura) da linha Define o alinhamento da linha (centro, esquerdo ou direito) Define a cor da linha Tabela 5.5 Atributos da TAG <HR>
Size Align
Color
No exemplo que segue, utilizamos trs exemplos da tag <HR>. Exemplo: <HTML> <HEAD> <TITLE>Ttulo do Documento</TITLE> </HEAD> <BODY> <P>Este bloco fala sobre o descobrimento do BRASIL</P><BR> Em 22 de Abril de 1500 o Brasil...<BR> <HR WIDTH=50% SIZE=2 ALIGN=CENTER> <BR> <P>Este bloco fala sobre as cores da Bandeira Nacional</P><BR> As cores que compem a Bandeira Nacional so... <HR WIDTH=310 SIZE=5 ALIGN=LEFT><BR> <P>O que este bloco faz aqui? </P><BR> Deve estar demonstrando alguma coisa <HR WIDTH=70% SIZE=10 COLOR="BLACK" ALIGN=CENTER> </BODY> </HTML> A figura 5.10 ilustra o nosso exemplo. No exerccio 7 crie um documento HTML com quatro pargrafos (lembrem-se de utilizar todos os recursos apresentados), separados por linhas horizontais de variadas formas.
Figura 5.10 Exemplo de linhas horizontais <HR> Veja a figura 5.11 e o cdigo que segue como resoluo do exerccio.
HTML 41 <OL> Listas Ordenadas Para criar listas ordenadas, utilizamos a TAG <OL>. O mais importante atributo da TAG <OL> o Type. Atravs deste atributo podemos definir o esquema de numerao.
DESCRIO
TYPE = A
Utiliza letras maisculas no esquema de numerao. Utiliza letras minsculas no esquema de numerao. Utiliza algarismos romanos no esquema de numerao. Tabela 5.6 Valores para o atributo <TYPE>
TYPE = a
TYPE = I
Para cada item da lista necessria a utilizao da TAG <LI>. Veja o exemplo que segue. <HTML> <HEAD> <TITLE>Exemplo de Listas Ordenadas</TITLE> </HEAD> <BODY> <P> <OL> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </OL> </P> <HR Width=50% SIZE=2 ALIGN=CENTER> <P> <OL TYPE="A"> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </OL> </P> <HR Width=50% SIZE=2 ALIGN=CENTER> <P> <OL TYPE="a"> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </OL> </P> <HR Width=50% SIZE=2 ALIGN=CENTER> <P> <OL TYPE="I"> <LI>Primeiro Item
42 Delphi 7 Internet e Banco de Dados <LI>Segundo Item <LI>Terceiro Item </OL> </P> </BODY> </HTML> A figura 5.12 ilustra o nosso exemplo:
Figura 5.12 Listas ordernadas No exerccio 8 crie um documento com 3 (trs) listas com diferentes numeraes, e em cada lista coloque um conjunto com 5 itens, utilizando os recursos apresentados at aqui. A figura 5.13 ilustra a resoluo deste exerccio.
HTML 43 <BODY><FONT Face=Verdana Size=2> <P> <OL> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item <LI>Quarto Item <LI>Quinto Item </OL> </P> <P> <OL TYPE="A"> <LI>Item 1 <LI>Item 2 <LI>Item 3 <LI>Item 4 <LI>Item 5 </OL> </P> <P> <OL TYPE="a"> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item <LI>Quarto Item <LI>Quinto Item </OL> </P> </FONT> </BODY> </HTML> <UL> Listas No Ordenadas As listas no ordenadas so parecidas com as listas ordenadas, com a diferena de no numerarem os itens. Para criar uma lista ordenada, utilizamos a TAG <UL>. Para indicar os itens da lista utilizamos a TAG <LI> (a mesma utilizada nas listas ordenadas), onde a mesma receber um marcador ao invs de uma numerao. Exemplo: <HTML> <HEAD><TITLE>Listas no ordenadas</TITLE></HEAD> <BODY> <P> <UL> <LI>Primeiro Item <LI>Segundo Item <LI>Terceiro Item </UL> </P> </BODY> </HTML> A figura 5.14 ilustra o nosso exemplo.
Figura 5.14 Listas no ordenadas Como a tag <UL> bem parecida com a <OL>, no faremos exerccio sobre a mesma.
Imagens
Para inserir imagens nos documentos HTML, utilizamos a TAG <IMG>. Os padres de imagens mais utilizados so GIF e JPG, pela qualidade de imagem e tamanho reduzido. Os seguintes atributos complementam a TAG <IMG>. ATRIBUTO DESCRIO
Alt
Exibe um texto enquanto a imagem no exibida Indica o nome do arquivo a ser exibido Alinhamento da imagem na pgina.
ALIGN(Vertical) Alinhamento Vertical da imagem TextTop/Middle/AbsMiddle/BaseLine/Bo ttom/AbsBottom Width Height Largura da imagem em pixels. Altura da imagem em pixels
HTML 45
ATRIBUTO
DESCRIO
HSPACE
Define o nmero de pixels que so deixados entre a imagem e o texto (Horizontal) Define o nmero de pixels que so deixados entre a imagem e o texto (Vertical) Define o tamanho Tabela 5.7 Atributos da TAG <FONT>
VSPACE
BORDER Exemplo:
<HTML> <HEAD> <TITLE>Trabalhando com Imagens</TITLE> </HEAD> <BODY> <IMG SRC="imagens/logo.jpg" WIDTH=140 HEIGHT=200 BORDER=5> <IMG SRC="imagens/logo.jpg" WIDTH=160 HEIGHT=240 NOBORDER> <IMG SRC="imagens/logo.jpg" NOBORDER> <IMG SRC="imagens/logo.jpg" NOBORDER Align=top> <IMG SRC="imagens/logo.jpg" NOBORDER Align=middle> </BODY> </HTML>
Figura 5.15 Trabalhando com Imagens A figura 5.15 ilustra o nosso exemplo. Repare que embora a figura seja a mesma, atravs da tag <IMG> alteramos suas caractersticas, como tamanho, borda e posicionamento vertical. No exerccio 9 crie um documento HTML com 3 (trs) imagens com variadas caractersticas.
PROTOCOLO
DESCRIO
Servidor World Wide Web Servidor de transferncia de arquivos. Enviar e-mail Servidor Gopher, normalmente um texto ASCII.
HTML 47
PROTOCOLO
DESCRIO
Servidor de Notcias NNTP padro Servidor de Notcias NNTP particular Conexo de terminal remoto com um servidor TELNET.
48 Delphi 7 Internet e Banco de Dados Voc poder utilizar imagem, texto, ou at os dois em conjunto. A figura 5.18 ilustra a resoluo do exerccio.
Tabelas
Aprender a trabalhar com tabelas no documento HTML fundamental para o desenvolvimento de excelentes documentos. Para criar uma tabela utilizamos a TAG <TABLE> em conjunto com seus atributos e subtags.
HTML 49
ATRIBUTO/SUB TAG
DESCRIO
Define o incio e o fim de uma linha na tabela Define o incio e o fim de uma clula Define o cabealho da tabela Define a largura da borda Largura da tabela, em percentual %, ou pixels Largura da tabela em percentual % ou pixels Tabela 5.9 Atributos da TAG <TABLE>
Para incrementar as tabelas, as subtags <TD> e <TR> possuem atributos interessantes, veja a tabela que segue.
ATRIBUTO/SUBTAG
DESCRIO Permite definir todas as caractersticas da fonte dentro de uma clula Define a cor de fundo da clula Imagem de fundo da tabela Tabela 5.10 Atributos da TAG
<html> <head> <title>Exemplo Tabela</title> </head><TABLE BORDER=2> <TH> Coluna 1</TH><TH> Coluna 2 </TH> <TR><TD> linha1, coluna 1</td><td> linha 1, coluna 2 </TD></TR> <TR><TD> linha 2, coluna 1</TD><TD>linha 2, coluna 2 </TD></TR> </TABLE> </BODY> </HTML> A figura 5.19 ilustra o primeiro exemplo de tabelas.
Figura 5.19 Exemplo de tabela Vejamos um exemplo parecido, mas sem bordas. Para tanto, basta substituir o valor do BORDER para 0.
Figura 5.20 exemplo sem borda Vejamos um exemplo mais completo. <html> <head> <title>Exemplo Tabela</title> </head> <table width="80%" border="1"> <tr> <td bgcolor=gray><B>Veiculo</B></td> <td bgcolor=gray><B>Marca</B></td> </tr> <tr> <td>Palio</td> <td>Fiat</td> </tr> <tr> <td>Gol</td> <td>Volkswagem</td> </tr> <tr> <td>Corsa</td>
HTML 51 <td>GM</td> </tr> <tr> <td>Ka</td> <td>Ford</td> </tr> </table> </body> </html> A figura 5.21 ilustra o nosso exemplo.
Figura 5.21 Exemplo de tabela No exerccio 11 faa um documento HTML baseado no modelo que segue.
HTML 53
Formulrios
Os formulrios so bastante comuns em aplicaes web. Na realidade so indispensveis. Os formulrios HTML funcionam como os formulrios de programas cliente/servidor, com a finalidade de fazer a interface entre o usurio e o banco de dados. A TAG <FORM> define o incio e o fim do formulrio. Os dois principais atributos da TAG <FORM> so:
ATRIBUTO
DESCRIO
ACTION
Define a localizao do programa ou email aos quais sero enviados os dados do formulrio Define a forma de troca de dados entre o cliente (formulrio) e o programa. Tabela 5.10 Atributo da TAG <FORM>
METHOD
ATRIBUTO
DESCRIO
Nome do objeto Texto do objeto Tamanho do objeto Tamanho mximo permitido para entrada de dados Endereo da imagem utilizada Posio do objeto na ordem de tabulao Quando o objeto for do tipo CheckBox ou Radio, utilizada para atribuir os valores Verdadeiro ou Falso.
ATRIBUTO
Text
DESCRIO
Permite a entrada de dados, como o Edit ou DBEdit
ATRIBUTO
Password
DESCRIO
Permite a entrada de dados, com caractere *, como PassWordChar do Delphi Caixa de seleo, como o CheckBox do Delphi
CheckBox
Como o RadioGroup do Delphi Lista de Seleo, como o ComboBox do Delphi Boto para enviar os dados do formulrio Boto para limpar os campos do formulrio Define um boto de ao prpria do usurio Incorpora um objeto invisvel ao formulrio O mesmo que Submit, mas com uma imagem ao invs do boto Tabela 5.12 Atributos do <TYPE>
Exemplo de Formulrio: <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> <input type="submit" name="Submit"> </form> A figura 5.23 ilustra o nosso exemplo.
HTML 55
F Figura 5.23 Exemplo de formulrio Vejamos outro exemplo: <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Form2"> <p>Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> </p> <p>Sexo <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton"> Feminino</p> <p> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </form> </body> </html> A figura 5.24 ilustra o segundo exemplo.
Figura 5.24 Exemplo de formulrio Vejamos outro exemplo: <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Formulario1"> <p>Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> </p> <p>Sexo <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton"> Feminino</p> <p>Quais produtos deseja conhecer ?</p> <p> <input type="checkbox" name="Produto1" value="checkbox"> Delphi 5 - Desenvolvendo Aplicaes Cliente/Servidor<br> <input type="checkbox" name="produto2" value="checkbox"> Delphi 5 - Solues Empresariais<br> <input type="checkbox" name="produto3" value="checkbox"> Delphi 5 Comrcio Eletrnico</p> <BR> <p> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </form> </body> </html> A figura 5.25 ilustra o exemplo.
HTML 57
Figura 5.25 Exemplo de formulrio Neste exemplo vamos utilizar a maioria das TAGS que aprendemos neste livro, para tornar o formulrio mais simptico. <html> <head> <title>Cadastro</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Formulario"> <table width="80%" border="1" align="center" bgcolor="#3333FF"> <tr> <td><font face="Arial" size="2" color="#FFFFFF"> <b>Formulrio de Cadastro</b></font></td> </tr> </table> <table width="80%" border="0" cellpadding="0" cellspacing="0" bgcolor="#CCCCCC" align="center"> <tr> <td><font face="Verdana" size="2">Nome </font></td> <td> <font face="Verdana" size="2"><br> <input type="text" name="NOME" size="50" maxlength="50"> <br> </font></td> </tr> <tr> <td> <p><font face="Verdana" size="2">Email</font> <br> </p> </td> <td><font face="Verdana" size="2"> <input type="text" name="email" size="50" maxlength="50"> </font></td> </tr> <tr> <td><font face="Verdana" size="2"> Sexo</font></td> <td> <font face="Verdana" size="2"><br> <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton">
58 Delphi 7 Internet e Banco de Dados Feminino<br> </font></td> </tr> <tr> <td><font face="Verdana" size="2"></font></td> <td> <p><font face="Verdana" size="2"><br> Quais produtos deseja conhecer ?</font></p> <p> <font face="Verdana size="2"> <input type="checkbox" name="Produto1" value="checkbox"> Delphi 5 - Desenvolvendo Aplicaes Cliente/Servidor<br> <input type="checkbox" name="produto2" value="checkbox"> Delphi 5 - Solues Empresariais<br> <input type="checkbox" name="produto3" value="checkbox"> Delphi 5 - Comrcio Eletrnico</font></p> </td> </tr> <tr> <td> </td> <td> <p><br> Qual verso do Delphi voc utiliza no momento <select name="versaodelphi"> <option>Delphi 1</option> <option>Delphi 2</option> <option>Delphi 3</option> <option>Delphi 4</option> <option>Delphi 5 Standard</option> <option>Delphi 5 Professional</option> <option selected>Delphi 5 Enterprise</option> </select> </p> <p> </p> </td> </tr> <tr> <td> </td> <td> <p><br> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </td> </tr> </table> </form> </body> </html> A figura 5.26 ilustra este exemplo.
HTML 59
Figura 5.26 Exemplo de Formulrio Amigos, vimos a complexidade em desenvolver um formulrio em HTML, mas no se assustem, pois as ferramentas citadas anteriormente (Dreamweaver, GoLive, etc.) tornam esta tarefa bastante agradvel. Para facilitar a compreenso e o andamento do curso, faremos o exerccio de formulrio em conjunto com as aplicaes servidoras.
60 Delphi 7 Internet e Banco de Dados </STYLE> </head> <body bgcolor="#FFFFFF"> <form method="post" action="mailto:emerson@facunte.com.br" name="Formulario1"> <p>Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> </p> <p>Sexo <input type="radio" name="masculino" value="radiobutton"> Masculino <input type="radio" name="feminino" value="radiobutton"> Feminino</p> <p>Quais produtos deseja conhecer ?</p> <p> <input type="checkbox" name="Produto1" value="checkbox"> Delphi 5 - Desenvolvendo Aplicaes Cliente/Servidor<br> <input type="checkbox" name="produto2" value="checkbox"> Delphi 5 - Solues Empresariais<br> <input type="checkbox" name="produto3" value="checkbox"> Delphi 5 Comrcio Eletrnico</p> <BR> <p> <input type="submit" name="Submit" value="Enviar"> <input type="reset" name="Reset" value="Limpar Campos"> </p> </form> </body> </html> A figura 5.27 ilustra o nosso exemplo.
HTML 61
Atributos de CSS Atributo de CSS Background background-attachment background-image background-color background-position background-repeat Border border-bottom border-bottom-color border-bottom-style border-bottom-width border-color border-left border-left-color border-left-style border-left-width border-right border-right-color border-right-style border-right-width border-style border-top border-top-color border-top-style border-top-width border-width clear clip Color Cursor Display Filter Float Font @font-face font-family font-size font-style Font-variant font-weight height @import O que ele formata Cor de fundo, imagem, transparncia. Rolagem do fundo / Marca d'gua. Imagem de fundo. Cor de fundo ou transparncia. Posicionamento da imagem de fundo. Configurao lado-a-lado da imagem de fundo. Largura, estilo e cor das bordas (superior, inferior, direita e esquerda) Largura, estilo e cor da borda inferior. Cor da borda inferior. Estilo da borda inferior. Largura da borda inferior. Cor das bordas. Largura, estilo e cor da borda esquerda. Cor da borda esquerda. Estilo da borda esquerda. Largura da borda esquerda. Largura, estilo e cor da borda direita. Cor da borda direita. Estilo da borda direita. Largura da borda direita. Estilo de todas as bordas. Largura, estilo e cor da borda superior. Cor da borda superior. Estilo da borda superior. Largura da borda superior. Largura de todas as bordas. Elementos flutuantes esquerda ou direita de um elemento. Parte visvel de um elemento. Cor de primeiro plano. Tipo de ponteiro do mouse. Se o elemento exibido e o espao reservado para ele. Tipo de filtro aplicado ao elemento. Se o elemento flutua. Estilo, variante, peso, tamanho e altura da linha do tipo de fonte. Incorporao da fonte ao arquivo HTML. Tipo de fonte. Tamanho da fonte. Fonte itlico. Fonte bold. Peso da fonte de claro a negrito. Altura exibida ao elemento. Folha de estilo a importar.
Left letter-spacing line-height list-style list-style-image list-style-position list-style-type margin margin-left margin-right margin-bottom margin-top overflow padding padding-bottom padding-left padding-right padding-top page-break-after page-break-before position text-align text-decoration text-indent text-transform top vertical-align visibility width z-index
Posio do elemento em relao margem esquerda da pgina. Distncia entre as letras. Distncia entre linhas de base. Tipo, imagem e posio do estilo da lista. Marcador de item de lista. Posio do marcador de item da lista. Marcador de item de lista alternativo. Tamanho de todas as margens. Tamanho da margem esquerda. Tamanho da margem direita. Tamanho da margem inferior. Tamanho da margem superior. Exibio de imagens que so maiores do que suas molduras. Espao em torno de um elemento em todos os lados. Espao a partir da margem inferior de um elemento. Espao esquerda do elemento. Espao direita do elemento. Espao a partir da margem superior do elemento. Inserir quebra de pgina depois de um elemento. Inserir quebra de pgina antes de um elemento. Como o elemento posicionado na pgina. Alinhamento do texto. Sublinhado, sobrelinhado ou riscado. Recuo da primeira linha do pargrafo. Transformao para todas maisculas, minsculas ou inicial maiscula. Posio do elemento em relao parte superior da pgina. Alinhamento vertical do elemento. Se elemento visvel ou invisvel. Largura do elemento. Posio do elemento na pilha.
HTML 63
JavaScript
Assim como no tpico de CSS, abordaremos apenas alguns itens sobre JavaScript. Aqui abordaremos somente a validao de formulrios utilizando o JavaScript. No exemplo que segue, verificamos se o usurio deixou o campo nome
em branco. Em caso afirmativo, disparado um alerta ao usurio. <html> <head> <title>Exemplo de Formulrio</title> <SCRIPT LANGUAGE=JAVASCRIPT TYPE TEXT/JAVASCRIPT> function ValidaForm(formulario) { if (formulario.NOME.value==) { alert(Voc precisa informar o NOME) formulario.NOME.focus() return false } return true } </SCRIPT> </head> <body bgcolor="#FFFFFF"> <form method="post" onSubmit=return ValidaForm(this) action="mailto:emerson@facunte.com.br" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> <input type="submit" name="Submit"> </form> </body> </html> Caso o usurio deixe em branco o campo nome, o Javascript dispara a mensagem ilustrada na figura 5.28.
Figura 5.28 Mensagem do JavaScript. Vamos analisar o cdigo. <SCRIPT LANGUAGE=JAVASCRIPT TYPE TEXT/JAVASCRIPT> Neste ponto indicamos ao documento HTML o incio do script JavaScript. Entre as tags <SCRIPT> e </SCRIPT> temos a liberdade de inserir cdigos de linguagens de script, como o JavaScript. Em seguida criamos a funo ValidaForm, com o parmetro (formulario). function ValidaForm(formulario) { Na linha seguinte, verificamos se o usurio deixou o campo nome em branco. if (formulario.NOME.value==) { Em caso afirmativo, o JavaScript dispara um alerta ao usurio. alert(Voc precisa informar o NOME)
64 Delphi 7 Internet e Banco de Dados Em seguida focaliza o campo nome e retorna o valor false ao formulrio. formulario.NOME.focus() return false Caso contrrio retorna o valor true, liberando assim o formulrio. return true Para finalizar o script devemos fechar a tag </SCRIPT>. </SCRIPT> Para que o nosso exemplo funcione, colocamos a funo de validao dentro do formulrio, utilizando o evento OnSubmit. <form method="post" onSubmit=return ValidaForm(this) No exerccio 12, crie um documento HTML com dois campos: Nome e Email, e verifique se o usurio deixou em branco um dos campos. Em caso afirmativo dispare a mensagem Favor informar o nome do campo. A seguir, temos a resoluo do exerccio. <html> <head> <title>Exemplo de Formulrio</title> <SCRIPT LANGUAGE=JAVASCRIPT TYPE TEXT/JAVASCRIPT> function ValidaForm(formulario) { if (formulario.NOME.value==) { alert(Voc precisa informar o NOME) formulario.NOME.focus() return false } if (formulario.EMAIL.value==) { alert(Voc precisa informar o EMAIL) formulario.NOME.focus() return false } return true } </SCRIPT> </head> <body bgcolor="#FFFFFF"> <form method="post" onSubmit=return ValidaForm(this) action="mailto:emerson@facunte.com.br" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"><BR><BR> Digite seu Email <input type="text" name="EMAIL" size="50" maxlength="50"><HR> <input type="submit" name="Submit"> </form> </body> </html> Com isso conclumos nosso objetivo com o JavaScript.
HTML 65
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 6
Delphi x Web x WebBroker
Para entender como funcionam as aplicaes servidoras desenvolvidas em Delphi, nada melhor do que aprender na prtica. A cada exerccio iremos evoluir no aprendizado de aplicaes servidoras web.
Figura 6.1 Opo Web Server Application Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.2), e marque a opo Cross Platform, para que nossa aplicao possa ser compilada normalmente no Kylix.
66
Figura 6.2 Seleo do tipo da aplicao Em seguida teremos um WebModule (figura 6.3):
Figura 6.3 WebModule Mas o que um WebModule ? WebModule um repositrio de objetos, com a funo de armazenar os objetos no visuais da aplicao tais como (TPageProducer, TQueryPageProducer, TQuery, etc.), bem como responder s requisies do servidor HTTP. Bem, para que uma aplicao servidora possa trabalhar, devemos delegar tarefas, atravs de ActionsItems, ou simplesmente Itens de Ao. Para explicar melhor o uso de ActionsItems, imagine uma aplicao para incluso e alterao de clientes. Teremos o seguinte cenrio:
Aplicao (clientes.exe)
::: ActionItem (incluso) ao para incluir cliente ::: ActionItem(alterao)- ao para alterar cliente bastante simples, cada ActionItem tem uma funo especfica dentro da aplicao servidora. Para executar no browser uma determinada ActionItem, basta fazer como no exemplo: http://site/cgi-bin/clientes.exe/inclusao
68 Delphi 7 Internet e Banco de Dados Repare que informamos o nome da aplicao (clientes.exe) e o nome da ActionItem (/incluso). A aplicao servidora no possui limite de ActionItems, portanto podemos criar aplicaes complexas. Bem, seguindo o nosso primeiro projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.4).
Figura 6.4 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.5).
Figura 6.5 ActionItem Em seguida altere as seguintes propriedades, como ilustra a figura 6.6.
OBJETO TWebActionItem Objeto Acao1 Propriedade Default Name PathInfo Valor True Acao1 /acao1
Figura 6.6 Propriedades da Action Embora a propriedade PathInfo possua o mesmo valor da propriedade Name, ela que executa a Action, ou seja, no browser o que vale o valor da PathInfo. No evento OnAction coloque o seguinte cdigo: (coloque somente o cdigo em negrito, o restante criado automaticamente pelo Delphi). procedure TWebModule1.WebModule1acao1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content:=Ol Mundo; end; No cdigo anterior, estamos utilizando o mtodo Response da aplicao servidora. Este mtodo responsvel pela resposta do servidor uma requisio. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.7.
Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo1.dpr e a unit como un_1.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo1.exe/acao1
Listagem 6.1
unit un_1; interface uses SysUtils, Classes, HTTPApp; type TWebModule1 = class(TWebModule) procedure WebModule1acao1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation
Delphi x Web x WebBroker 71 {$R *.DFM} procedure TWebModule1.WebModule1acao1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content:='Ol Mundo'; end; end.
. Figura 6.10 Webmodule Para prosseguir altere a propriedade HTMLDOC do PageProducer1 inserindo o seguinte cdigo:
72 Delphi 7 Internet e Banco de Dados <P align=center><B>Ol Mundo</B></P> Reparem que informamos cdigo HTML. Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.11).
Figura 6.11 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.12).
OBJETO TWebActionItem Objeto Acao1 Propriedade Default Name PathInfo Producer Valor True Acao1 /acao1 PageProducer1
Figura 6.13 Propriedade Producer Com isso vinculamos a nossa Action Acao1 com o nosso produtor de pgina PageProducer1. Veremos que no necessrio disparar um cdigo, como no exemplo1. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.14.
Figura 6.14 Configurao do diretrio Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo2.dpr e a unit como un_2.pas Compile o projeto, e digite a seguinte URL no browser:
http://localhost/cgi-bin/exemplo2.exe/acao1
A figura 6.15 ilustra o nosso exemplo.
Figura 6.15 Exemplo 2 Perceberam que no colocamos uma linha sequer de cdigo? Vejam a listagem 6.2, todo o cdigo existente foi gerado automaticamente pelo Delphi.
Listagem 6.2
unit un_2; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} end.
Delphi x Web x WebBroker 75 Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.16).
Figura 6.16 Seleo do tipo da aplicao No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Veja como ficou nosso WebModule (figura 6.17).
. Figura 6.17 Webmodule Para prosseguir, altere a propriedade HTMLFILE do PageProducer1 apontando para o arquivo olamundo.html da seguinte forma: ../olamundo.html Voc deve colocar desta forma mesmo, dois pontos seqenciais seguidos da barra, e por fim o nome do arquivo. Devemos fazer isto desta maneira, pelo fato da nossa aplicao rodar num outro nvel de diretrio (CGI-BIN), e o arquivo HTML no primeiro nvel. Crie um arquivo HTML no diretrio C:\cursoweb com o nome olamundo.html e insira o cdigo que seguinte <P align=center><B>Ol Mundo</B></P> <HR> <P align=center><B>utilizando htmlfile</B></P> Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.18).
Figura 6.18 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.19).
OBJETO TwebActionItem Objeto Acao1 Propriedade Default Name PathInfo Producer Valor True Acao1 /acao1 PageProducer1
Delphi x Web x WebBroker 77 Com isso vinculamos a nossa Action Acao1 com o nosso produtor de pgina PageProducer1. Veremos que no necessrio disparar um cdigo, como no exemplo1. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.21.
Figura 6.21 Configurao do diretrio Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo3.dpr e a unit como un_3.pas Compile o projeto, e digite a seguinte URL no browser:
http://localhost/cgi-bin/exemplo3.exe/acao1
A figura 6.22 ilustra o nosso exemplo.
Listagem 6.3
unit un_3; interface uses SysUtils, Classes, HTTPApp, HTTPProd;
78 Delphi 7 Internet e Banco de Dados type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} end.
Neste exemplo criamos uma Tag Transparente com o nome hora. O contedo desta Tag poder ser substitudo por nossa aplicao servidora. Faremos o exemplo. Crie uma nova aplicao no Delphi atravs das opes File/New..., selecione a opo Web Server Application e clique no boto OK para confirmar. Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 6.23).
Delphi x Web x WebBroker 79 No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Para prosseguir altere a propriedade HTMLDOC (embora eu recomende o uso do HTMLFile, neste caso utilizamos a outra forma para agilizar o curso), colocando o cdigo que segue: <P align=center><B>Teste de Tag Transparente</B></P> <HR> <P align=center><B>Hora Atual: <#hora></B></P> No evento OnHTMLTag do PageProducer1 insira o seguinte cdigo: if TagString=hora then ReplaceText:=timetostr(time); Repare que estamos substituindo o contedo da Tag Transparente hora pela hora atual (funo time). Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.24).
Figura 6.24 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.25).
OBJETO TWebActionItem Objeto Acao1 Propriedade Default Name PathInfo Producer Valor True Acao1 /acao1 PageProducer1
80 Delphi 7 Internet e Banco de Dados A figura 6.26 ilustra a alterao da propriedade Producer.
Figura 6.26 Propriedade Producer Com isso vinculamos a nossa Action Acao1 com o nosso produtor de pgina PageProducer1. Veremos que no necessrio disparar um cdigo, como no exemplo1 (isso est se tornando repetitivo, no acham? Mas para o bem de todos). Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.27.
Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo4.dpr e a unit como un_4.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo4.exe/acao1
A figura 6.28 ilustra o nosso exemplo.
Listagem 6.4
unit un_4; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; procedure PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String); begin if TagString='hora' then ReplaceText:=timetostr(time); end; end.
Figura 6.29 Seleo do tipo da aplicao No WebModule vamos inserir um objeto do tipo TPageProducer, que se encontra na paleta Internet. Para prosseguir altere a propriedade HTMLFILE do PageProducer1 apontando para o arquivo olamundo.html da seguinte forma: ../formulario.html Crie um arquivo HTML no diretrio C:\cursoweb com o nome formulario.html e insira o cdigo que seguinte <html> <head> <title>Exemplo de Formulrio</title> </head> <body bgcolor="#FFFFFF"> <form method="post" action="confirma" name="form1"> Digite seu nome <input type="text" name="NOME" size="50" maxlength="50"> <input type="submit" name="Submit"> </form> </body> </html>
Delphi x Web x WebBroker 83 Seguindo o nosso projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 6.30).
Figura 6.30 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 6.31).
OBJETO TWebActionItem Objeto Formulrio Propriedade Default Name PathInfo Producer Valor True formulario /formulario PageProducer1
Figura 6.32 Propriedade Producer Repare no cdigo HTML do documento, que estamos encaminhando o contedo do formulrio para a Action confirma. Para que o formulrio possa ser processado em nossa aplicao servidora, devemos criar tal item. Crie uma nova Action alterando as propriedades que seguem:
OBJETO TWebActionItem Objeto confirma Propriedade Default Name PathInfo Valor False confirma /confirma
Repare que neste caso no vinculamos o PageProducer, pois daremos uma outra resposta para esta Action. No evento OnAction da Action confirma insira o cdigo que segue: Response.Content:=Seja bem vindo + Request.ContentFields.Values[nome];
Neste caso estamos utilizando o objeto Request, que tem como principal funo extrair informaes do requerente, em nosso caso o formulrio HTML. O mtodo ContenFields extrai informaes enviadas atravs do mtodo POST do formulrio. Em nosso caso, pegamos o contedo do campo nome. Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.33.
Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo5.dpr e a unit como un_5.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo5.exe/formulario. As figuras 6.34 e 6.35
ilustram o nosso exemplo.
Listagem 6.5
unit un_5; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; procedure WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.Content:='Seja bem vindo'+ Request.ContentFields.Values['nome']; end; end.
88 Delphi 7 Internet e Banco de Dados Clique no primeiro boto do editor para inserir uma nova Action (figura 6.38).
OBJETO TWebActionItem Objeto formulario Propriedade Default Name PathInfo Producer Valor True formulario /formulario PageProducer1
Repare no cdigo HTML do documento que estamos encaminhando o contedo do formulrio para a Action soma. Para que o formulrio possa ser processado em nossa aplicao servidora, devemos criar tal item. Crie uma nova Action alterando as propriedades que seguem:
OBJETO TWebActionItem Objeto soma Propriedade Default Name PathInfo Valor False soma /soma
Repare que neste caso no vinculamos o PageProducer, pois daremos uma outra resposta para esta Action. No evento OnAction da Action soma insira o cdigo que segue: (coloque somente o cdigo em negrito, o restante foi criado automaticamente pelo Delphi) procedure TWebModule1.WebModule1somaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var numero1,numero2:single; begin numero1:=StrtoFloat(Request.ContentFields.Values ['NUMERO1']); numero2:=StrtoFloat(Request.ContentFields.Values ['NUMERO2']);
end; Antes de compilar o projeto, devemos configurar uma opo. Atravs da opo Projects/Option (menu), selecione a seo Directories/Conditionals e configure a opo Output Directory para C:\cursoweb\cgi-bin, como ilustra a figura 6.39.
Tudo pronto. Agora devemos gravar o projeto com o nome de exemplo6.dpr e a unit como un_6.pas. Compile o projeto, e digite a seguinte URL no browser: http://localhost/cgi-bin/exemplo6.exe/formulario
As figuras 6.40 e 6.41 ilustram o nosso exemplo.
Listagem 6.6
unit un_6; interface uses SysUtils, Classes, HTTPApp, HTTPProd; type TWebModule1 = class(TWebModule) PageProducer1: TPageProducer; procedure WebModule1somaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.DFM} procedure TWebModule1.WebModule1somaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var numero1,numero2:single; begin numero1:=StrtoFloat(Request.ContentFields.Values['NUMERO1']); numero2:=StrtoFloat(Request.ContentFields.Values['NUMERO2']); Response.Content:='A soma de '+ floattostr(numero1)+' e '+ floattostr(numero2)+' = '+ floattostr(numero1+numero2); end; end.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 7
Projeto Cadastro de Clientes
Neste captulo iremos desenvolver um projeto completo de cadastro de clientes, com as principais funes: incluso, alterao, excluso e consulta de registros. Antes de prosseguir com o Delphi, devemos criar o banco de dados Interbase ou Firebird com todas as suas propriedades.
92
Projeto Cadastro de Clientes 93 No campo UserName digite SYSDBA (com letras maisculas), e no campo PassWord digite masterkey (com letras minsculas). Estas informaes so para o usurio padro. Agora vamos criar o banco de dados Clientes.GDB. Selecione a opo DataBase/Create Database e crie um novo banco de dados como ilustra a figura 7.2.
Figura 7.2 Criao do banco de dados Clientes.GDB Agora iremos criar os objetos do banco de dados Clientes.GDB. Dentro do Interative SQL execute os seguintes comandos: Criao da Tabela TBCLIENTE create table tbcliente ( cod_cliente integer not null, razao_social varchar(50), endereco varchar(50), cidade varchar(50), estado varchar(2), cep varchar(8), email varchar(50), primary key (cod_cliente) ); Execute o comando atravs das teclas CTRL-E. Criao do Generator create generator gen_clientes; Execute o comando atravs das teclas CTRL-E. Criao da Trigger TGClientes set term ||;
94 Delphi 7 Internet e Banco de Dados CREATE TRIGGER TG_CLIENTES FOR TBCLIENTE ACTIVE BEFORE INSERT POSITION 0 AS BEGIN NEW.COD_CLIENTE = GEN_ID(GEN_CLIENTES,1); END || SET TERM; Execute o comando atravs das teclas CTRL-E. Com isso finalizamos a criao dos objetos. Finalize o IBConsole e vamos iniciar nossas atividades no Delphi.
Figura 7.3 Seleo do tipo da aplicao Insira um objeto do tipo TSQLConnection, e crie uma nova conexo clicando no boto + . Altere as seguintes propriedades:
OBJETO TSQLConnection Objeto BancoDados Propriedade DriverName CommitRetaining DataBase SQLDialect LoginPrompt Valor Interbase True localhost:C:/cursoweb /clientes.gdb 3 False
Objetos Bsicos
Insira um objeto do tipo TSQLDataSet e altere as propriedades que seguem:
OBJETO TSQLDataSet Objeto tbClientes Propriedade Name SQLConnection CommandText Valor tbClientes BancoDados select * from tbclientes
OBJETO TSQLQuery Objeto SQLGeral Propriedade Name SQLConnection SQL Valor SQLGeral BancoDados select * from tbclientes where cod_cliente= :pcodigo
Objeto de Incluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.
OBJETO TSQLQuery Objeto SQLInclui Propriedade Valor Name SQLInclui SQLConnection BancoDados SQL INSERT INTO TBCLIENTE VALUES(0,:prazao, :pendereco,:pcidade, :pestado,:pcep,:pemail)
Objeto de Alterao
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.
OBJETO TSQLQuery Objeto SQLAltera Propriedade Valor Name SQLAltera SQLConnection BancoDados SQL UPDATE TBCLIENTE SET RAZAO_SOCIAL=:prazao, ENDERECO=:pendereco, CIDADE=:pcidade, ESTADO=:pestado, CEP=:pcep, EMAIL=:pemail WHERE COD_CLIENTE=:pcodigo
Na propriedade PARAMS do SQLAltera altere os tipos dos parmetros para String, com exceo do parmetro PCODIGO, que deve ser Integer.
Objeto de Excluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem:
OBJETO TSQLQuery Objeto SQLExclui Propriedade Valor Name SQLExclui SQLConnection BancoDados SQL
DELETE FROM TBCLIENTE WHERE COD_CLIENTE=:pcodigo
OBJETO TDataSetTableProducer Objeto ppClientes Propriedade Name DataSet Valor PPClientes tbClientes
Em seguida, atravs do duplo clique adicione os campos, CODIGO e RAZAO_SOCIAL, conforme a figura 7.4
Figura 7.4 Tabela de Clientes Para inserir as colunas ALTERA e EXCLUI clique no primeiro boto. No Object Inspector voc poder alterar as propriedades de cada coluna, melhorando o visual da aplicao. No evento OnCellFormat do objeto PPClientes, insira o cdigo que segue. if (CellRow>0) and (CellColumn=2) then CellData:='<a href="altera?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="\imagens\altera.gif" border=0> </a>'; if (CellRow>0) and (CellColumn=3) then CellData:='<a href="exclui?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="\imagens\elimina.gif" border=0></a>'; Neste ponto indicamos duas funes: para alterar e excluir clientes.
Rotinas de manuteno
Agora insira um objeto do tipo TDataSetPageProducer e altere as seguintes propriedades.
OBJETO TDataSetPageProducer Objeto ppInclui Propriedade Name HTMLFILE Valor PPInclui ../inc_clientes.html
Neste ponto devemos criar o arquivo inc_clientes.html Listagem do arquivo inc_clientes.html <html> <head> <title>INCLUSO DE CLIENTES</title> <STYLE TYPE="text/css"> input { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color:#000066; background:#CCCCCC; border-right:2px solid #000066; border-left:2px solid #000066; border-top:2px solid #000066; border-bottom:2px solid #000066; } </STYLE> </head> <body bgcolor="#FFFFFF" text="#000000"> <table width="100%" border="1" bordercolor="#000066" bgcolor="#000066"> <tr> <td> <div align="center"><font color="#FFFFFF" face="Verdana"><b>INCLUSAO DE CLIENTES</b></font></div> </td> </tr> </table> <table align=center border=1 cellpadding=0 cellspacing=0 width=100% bordercolor="#000066"> <tr> <td bgcolor=white valign=top width="97%"> <p align="center"> </p> <form name="form1" method="post" action="confirma_inc_cliente"> <table width="100%" border="0"> <tr> <td width="23%" height="20"> <div align="right"><font Social:</font></div> </td> <td width="77%" height="20"> <p> <font face="Verdana" size="2">
face="Verdana"
size="2">Razo
Projeto Cadastro de Clientes 99 <input type="text" name="razao_social" size="90" maxlength="70"> </font></p> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Endereo:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="endereco" size="90" maxlength="70"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Cidade:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cidade" size="60" maxlength="50"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Uf:</font></div> </td> <td width="77%"> <input type="text" name="UF" size="4" maxlength="2"> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">CEP:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cep" size="10" maxlength="8"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Email Contato:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="email" size="60" maxlength="50"> </font></td> </tr> </table> <p align="center"> <font face="Verdana" size="2"> <input type="submit" name="Submit" value="Confirma Incluso"> <input type="button" name="Submit2" value="Desiste" onClick="javascript:history.go(-1)"> </font></p> </form> </td> </tr> </table> </body> </html>
100 Delphi 7 Internet e Banco de Dados Agora insira um objeto do tipo TDataSetPageProducer e altere as seguintes propriedades.
OBJETO TDataSetPageProducer Objeto ppAltera Propriedade Name HTMLFILE DataSet Valor PPAltera ../alt_clientes.html SQLGeral
Neste ponto devemos criar o arquivo alt_clientes.html <html> <head> <title>ALTERAO DE CLIENTES</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <STYLE TYPE="text/css"> input { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color:#000066; background:#CCCCCC; border-right:2px solid #000066; border-left:2px solid #000066; border-top:2px solid #000066; border-bottom:2px solid #000066; } </STYLE> </head> <body bgcolor="#FFFFFF" text="#000000"> <table width="100%" border="1" bordercolor="#000066" bgcolor="#000066"> <tr> <td> <div align="center"><font color="#FFFFFF" face="Verdana"><b>ALTERAO DE CLIENTES</b></font></div> </td> </tr> </table> <table align=center border=1 cellpadding=0 cellspacing=0 width=100% bordercolor="#000066"> <tr> <td bgcolor=white valign=top width="97%"> <p align="center"> </p> <form name="form1" method="post" action="confirma_alt_cliente?codigo=<#cod_cliente>"> <table width="100%" border="0"> <tr> <td width="23%" height="20"> <div align="right"><font face="Verdana" size="2">Razão Social:</font></div> </td> <td width="77%" height="20">
Projeto Cadastro de Clientes 101 <p> <font face="Verdana" size="2"> <input type="text" name="razao_social" size="90" maxlength="70" value="<#RAZAO_SOCIAL>"> </font></p> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Endereço:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="endereco" size="90" maxlength="70" value="<#ENDERECO>"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Cidade:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cidade" size="60" maxlength="50" value="<#CIDADE>"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Uf:</font></div> </td> <td width="77%"> <input type="text" name="UF" size="4" maxlength="2" value="<#ESTADO>"> </td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">CEP:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="cep" size="10" maxlength="8" value="<#CEP>"> </font></td> </tr> <tr> <td width="23%"> <div align="right"><font face="Verdana" size="2">Email Contato:</font></div> </td> <td width="77%"> <font face="Verdana" size="2"> <input type="text" name="email" size="60" maxlength="50" value="<#EMAIL>"> </font></td> </tr> </table> <p align="center"> <font face="Verdana" size="2"> <input type="submit" name="Submit" value="Confirma Alterao"> <input type="button" name="Submit2" value="Desiste" onClick="javascript:history.go(-1)"> </font></p> </form>
102 Delphi 7 Internet e Banco de Dados </td> </tr> </table> </body> </html>
Actions de manuteno
Neste ponto iremos criar as Actions. Crie uma Action alterando as propriedades que seguem.
OBJETO TWebActionItem Objeto principal Propriedade Default Name PathInfo Valor True principal /principal
Insira o cdigo que segue no evento OnAction. tbClientes.Close; tbClientes.CommandText:='SELECT * FROM TBCLIENTE WHERE RAZAO_SOCIAL LIKE '+''''+'%'+ Request.ContentFields.Values['razao']+'%'+''''; tbClientes.Open; Response.Content:='<HR><A HREF="inclusao">Incluso de Clientes</A>'+ '<FORM METHOD=POST ACTION="CONSULTA">'+ 'Consulta <INPUT TYPE=TEXT NAME=RAZAO SIZE=40>'+ '<INPUT TYPE=SUBMIT></FORM><HR>'+ ppClientes.Content; Crie outra Action alterando as propriedades que seguem.
OBJETO TWebActionItem Objeto Inclusao Propriedade Default Name PathInfo PageProducer Valor False inclusao /inclusao ppInclui
OBJETO TWebActionItem Objeto Altera Propriedade Default Name PathInfo Valor False Altera /altera
Insira o cdigo que segue no evento OnAction. SQLGeral.ParamByName('pcodigo').value:=StrtoInt(Request.QueryFields.Values['codigo']) ; SQLGeral.Open; Response.Content:=ppAltera.Content; SQLGeral.Close; Crie outra Action alterando as propriedades que seguem.
OBJETO TWebActionItem Objeto Exclui Propriedade Default Name PathInfo Valor False Exclui /exclui
Insira o cdigo que segue no evento OnAction. { Exclui Cliente } SQLExclui.ParamByName('pcodigo').Value:=StrtoInt(Request.QueryFields.Values['codigo'] ); SQLExclui.ExecSQL; Response.Content:='Registro excluido com sucesso'; Crie outra Action alterando as propriedades que seguem.
OBJETO TWebActionItem Objeto confirma_inc_cliente Propriedade Default Name PathInfo Valor False confirma_inc_cliente /confirma_inc_cliente
104 Delphi 7 Internet e Banco de Dados Insira o cdigo que segue no evento OnAction. { Inclui Cliente } SQLInclui.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLInclui.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLInclui.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLInclui.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLInclui.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLInclui.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInclui.ExecSQL; Response.Content:='Registro incluido com sucesso'; Crie outra Action alterando as propriedades que seguem.
OBJETO TWebActionItem Objeto confirma_alt_cliente Propriedade Default Name PathInfo Valor False confirma_alt_cliente /confirma_alt_cliente
Insira o cdigo que segue no evento OnAction. { Altera Cliente } SQLAltera.ParamByName('pcodigo').Value:=Request.QueryFields.Values['codigo']; SQLAltera.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLAltera.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLAltera.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLAltera.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLAltera.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLAltera.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLAltera.ExecSQL; Response.Content:='Registro alterado com sucesso';
Figuras da Aplicao
As figuras que seguem ilustram o resultado da nossa aplicao.
108 Delphi 7 Internet e Banco de Dados if (CellRow>0) and (CellColumn=3) then CellData:='<a href="exclui?codigo='+tbClientes.FieldByName('cod_cliente').AsString+ '"><img src="..\..\imagens\elimina.gif" border=0></a>'; end; procedure TWebModule1.WebModule1confirma_inc_clienteAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin { Inclui Cliente } SQLInclui.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLInclui.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLInclui.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLInclui.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLInclui.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLInclui.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInclui.ExecSQL; Response.Content:='Registro incluido com sucesso'; end; procedure TWebModule1.WebModule1confirma_alt_clienteAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin { Altera Cliente } SQLAltera.ParamByName('pcodigo').Value:=Request.QueryFields.Values['codigo']; SQLAltera.ParamByName('prazao').Value:=Request.ContentFields.Values['razao_social']; SQLAltera.ParamByName('pendereco').Value:=Request.ContentFields.Values['endereco']; SQLAltera.ParamByName('pcidade').Value:=Request.ContentFields.Values['cidade']; SQLAltera.ParamByName('pestado').Value:=Request.ContentFields.Values['uf']; SQLAltera.ParamByName('pcep').Value:=Request.ContentFields.Values['cep']; SQLAltera.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLAltera.ExecSQL; Response.Content:='Registro alterado com sucesso'; end; procedure TWebModule1.WebModule1alteraAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin SQLGeral.ParamByName('pcodigo').value:=StrtoInt(Request.QueryFields.Values['codigo']) ; SQLGeral.Open; Response.Content:=ppAltera.Content; SQLGeral.Close; end;
Projeto Cadastro de Clientes 109 procedure TWebModule1.WebModule1excluiAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin { Exclui Cliente } SQLExclui.ParamByName('pcodigo').Value:=StrtoInt(Request.QueryFields.Values['codigo'] ); SQLExclui.ExecSQL; Response.Content:='Registro excluido com sucesso'; end; procedure TWebModule1.WebModule1consultaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin tbClientes.Close; tbClientes.CommandText:='SELECT * FROM TBCLIENTE WHERE RAZAO_SOCIAL LIKE '+''''+'%'+ Request.ContentFields.Values['razao']+'%'+''''; tbClientes.Open; Response.Content:='<HR><A HREF="inclusao">Incluso de Clientes</A>'+ '<FORM METHOD=POST ACTION="CONSULTA">'+ 'Consulta <INPUT TYPE=TEXT NAME=RAZAO SIZE=40>'+ '<INPUT TYPE=SUBMIT></FORM><HR>'+ ppClientes.Content; end; end.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 8
Enviando E-mails
O recurso mais utilizado na Internet sem dvida o e-mail. Neste captulo iremos tratar deste assunto com extrema facilidade. O Delphi 7 traz incorporado em sua biblioteca de componentes o famoso pacote INDY da empresa Nevrona (www.nevrona.com). Na verso 5, o Delphi trazia o pacote da empresa NETMasters que utilizava API do Windows para executar suas funes, e desde a verso 6, foi includo o pacote INDY. O pacote da NetMasters era muito instvel, devido aos inmeros bugs tanto da parte da NETMasters, como tambm do Windows. A Nevrona adaptou seu excelente pacote (INDY) para o Kylix, baseado na tecnologia CLX. Com isso temos um excelente desempenho devido engenharia do pacote. Neste captulo iremos desenvolver um aplicativo para o envio de e-mails, utilizando os novos componentes da Nevrona. Este aplicativo est registrado na SourceForge com o nome de Mailing.NET em http://sourceforge.net/projects/mailingnet. A SourceForge uma entidade responsvel pelo gerenciamento de aplicaes com cdigo-fonte aberto, distribudos sob a licena pblica GNU. Um fator bastante importante deste projeto que o mesmo poder ser compilado em Kylix, pelo fato de ser baseado na tecnologia CLX.
Incio do Desenvolvimento
Vamos iniciar um novo projeto CLX, e no formulrio principal alterar as seguintes propriedades. OBJETO TForm Objeto fmeMail Propriedade BorderWidth Caption Name Valor 5 Mailing.Net fmeMail
Vamos gravar a unit com o nome f_principal.pas e o projeto como MailingNet.DPR. Insira um objeto do tipo TPanel e altere as propriedades que seguem:
111
OBJETO TPanel Objeto PnConfigura Propriedade Align Caption Height Name Valor alTop ((deixe em branco)) 180 PnConfigura
Agora com o foco no formulrio (objeto fmEmail), insira um objeto do tipo TSplitter e altere as seguintes propriedades: OBJETO TSplitter Objeto Splitter1 Propriedade Align MinSize Valor alTop 30
O objeto TSplitter utilizado para dividir sees de um formulrio. Em nosso projeto, ter a funo de separar as reas de configurao e texto. Ainda com o foco no formulrio insira outro objeto do tipo TPanel e altere as propriedades, como a seguir: OBJETO TPanel Objeto PnTexto Propriedade Align Caption Name Valor alClient (((deixe em branco))) PnTexto
Repare que estamos na fase de desenvolvimento da interface do aplicativo. Claro que uma tarefa um pouco cansativa devido ao grande nmero de objetos do formulrio. Mas amigos, acreditem, vale a pena o pequeno esforo. Agora com o foco no objeto PnTexto, insira um objeto do tipo TMemo e altere as propriedades que seguem: OBJETO TMemo Objeto textodoemail Propriedade Align Lines Name Valor alClient (((deixe em branco))) TextodoEmail
Vamos dar uma pausa e observar como est ficando nosso aplicativo. A figura 8.1 ilustra esse grande momento.
Figura 8.1 Fase inicial do Mailing.Net Dando continuidade ao nosso projeto, vamos inserir os objetos que seguem dentro do painel PnConfigura. Para facilitar, colocamos em destaque a seo em que se encontra o referido objeto. Exemplo: [Standard]. OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Texto 17 19
OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Assunto 17 51
OBJETO TEdit [Standard] Objeto Propriedade Left Name Text Top Width Valor 96 edTexto (((deixe em branco))) 16 320
OBJETO TEdit [Standard] Objeto Propriedade Left Name Text Top Width Valor 96 edAssunto (((deixe em branco))) 46 320
OBJETO TSpeedButton [Additional] Objeto Propriedade Caption Flat Left Name Top Width Valor >> True 420 btArquivo 16 23
OBJETO TButton [Standard] Objeto Propriedade Caption Left Name Top Width Valor Envia 468 btEnvia 85 75
Ainda com o foco no objeto PnConfigura, insira um objeto do tipo TGroupBox e altere as propriedades que seguem: OBJETO TGroupBox [Standard] Objeto Propriedade Caption Height Left Name Top Width Valor Configurao Servidor SMTP 90 16 gbConfigura 80 425
Agora vamos suar a camisa e inserir alguns objetos dentro do container GbConfigura. Vamos ao batalho de objetos do container GbConfigura.
Enviando E-mails 115 OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Host 16 20
OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Usurio 16 44
OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Conta 16 69
OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Porta 327 20
OBJETO TLabel [Standard] Objeto Propriedade Caption Left Top Valor Senha 176 44
116 Delphi 7 Internet e Banco de Dados Name Text edHost coloque o endereo do seu servidor SMTP. Exemplo: smtp.provedor.com.br 16 250
TEdit [Standard] Objeto Propriedade Color Left Name Text Valor clAqua 63 edUsuario coloque o usurio de sua conta SMTP. Exemplo: seunome 40 106
TMaskEdit [Additional] Objeto Propriedade Color Left PassWordChar Name Text Valor clAqua 216 * edSenha coloque a senha do usurio da conta de SMTP. Exemplo: suasenha 40 97
TEdit [Standard] Objeto Propriedade Color Left Name Text Valor clAqua 63 edConta coloque o endereo da conta de SMTP. Exemplo: seunome@provedor.com.br 16 250
Top Width
OBJETO TMaskEdit [Additional] Objeto Propriedade Color EditMask Left Name Text Top Width Valor clAqua 9999;1; 368 edPorta 25 16 48
Puxa, ainda bem que esta parte acabou. Acredito que todos se cansaram, mas temos um belo formulrio para envio de e-mails. A figura 8.2 ilustra o nosso formulrio neste momento.
Detalhes do Projeto
Antes de prosseguirmos com o projeto, vamos conhec-lo melhor. O Mailing.Net utiliza como base o mesmo banco de dados no padro Interbase empregado no captulo 7. Na realidade utilizamos apenas dois campos da tabela de clientes: razao_social e email. O campo razao_social ser utilizado para substituir uma tag em nosso aplicativo e o campo email para compor o destinatrio. O mais interessante neste aplicativo o uso do objeto TDataSetPageProducer, normalmente utilizado no desenvolvimento de aplicaes Web, como vimos nos captulos anteriores. Alm disso, iremos utilizar um arquivo externo no padro HTML para relacionar com o objeto TMemo. Insira um objeto do tipo TSQLConnection, e crie uma nova conexo clicando no boto + . Altere as seguintes propriedades.
118 Delphi 7 Internet e Banco de Dados OBJETO TSQLConnection Objeto BancoDados Propriedade DriverName CommitRetaining DataBase SQLDialect LoginPrompt Name Insira um objeto do tipo TSQLDataSet e altere as propriedades que seguem: OBJETO TSQLDataSet Objeto tbClientes Propriedade Name SQLConnection CommandText Valor tbClientes BancoDados select * from tbclientes Valor Interbase True localhost:C:/cursoweb /clientes.gdb 3 False BancoDados
Codificando o boto btArquivo O objeto btArquivo ser responsvel por carregar um arquivo externo (HTML) no objeto TextodoEmail. Para nos auxiliar nesta tarefa, necessitamos de outro objeto: TOpenDialog. Insira um objeto do tipo TOpenDialog e altere as propriedades que seguem: OBJETO TOpenDialog Objeto AbrirArquivo Propriedade Name Valor AbrirArquivo
Agora vamos inserir o cdigo do boto btArquivo no evento OnClick do mesmo. procedure TfmeMail.btArquivoClick(Sender: TObject); begin if AbrirArquivo.Execute then begin EdTexto:=AbrirArquivo.FileName; // Zera O TextodoEmail TextodoEmail.Clear; // Associa o Arquivo Texto/HTML com o // objeto TextodoEmail TextodoEmail.Lines.LoadFromFile(edTexto.Text); end;
Enviando E-mails 119 end; Vamos estudar o cdigo em detalhe: if AbrirArquivo.Execute then Esta linha verifica se o mtodo Execute do objeto AbrirArquivo foi executado com xito, ou seja, indaga se o usurio selecionou algum arquivo. EdTexto.Text:=AbrirArquivo.FileName; Associa o nome do arquivo selecionado no objeto AbrirArquivo ao objeto EdTexto. TextodoEmail.Clear; O mtodo Clear limpa o contedo do objeto TextodoEmail. TextodoEmail.Lines.LoadFromFile(edTexto.Text); Aqui estamos carregando (LoadFromFile) o arquivo (edTexto.Text) dentro do objeto TextodoEmail. Em resumo, poderemos digitar o texto ou ento carregar um arquivo previamente criado.
Repare que a propriedade ContentType refere-se ao tipo MIME da mensagem, ou seja, o tipo de seu contedo. Configuramos para text/HTML para que as mensagens sejam enviadas com o padro HTML ou texto (o padro HTML predomina por conter recursos de formatao). Agora, amigos, iremos trabalhar com o nosso curinga: TDataSetPageProducer. Como visto nos captulos anteriores, o objeto TDataSetPageProducer responsvel pela substituio automtica de Tags transparentes relacionadas aos campos do DataSet vinculado.
120 Delphi 7 Internet e Banco de Dados Insira um componente do tipo TDataSetPageProducer e altere as propriedades que seguem: OBJETO TDataSetPageProducer Objeto ppMensagem Propriedade DataSet Name Valor tbClientes ppMensagem
Vejamos alguns exemplos da funcionalidade do nosso curinga. Prezado(a) <#RAZAO_SOCIAL>, Estamos enviando este boletim para o seu email<BR> <#EMAIL>. .... Em tempo de execuo teremos: Prezado(a) Emerson Facunte, Estamos enviando este boletim para o seu email emerson@facunte.com.br O interessante que podemos inserir quantas Tags forem necessrias, em qualquer posio. Vejamos outro exemplo: Prezado(a) <#RAZAO_SOCIAL>, Como cliente preferencial, voc tem 10% de desconto em qualquer produto de nossa loja. Entretanto, Sr(a) <#RAZAO_SOCIAL>, esta oferta por tempo limitado. Amigos, como observamos nos captulos anteriores, poderemos produzir documentos HTML com ferramentas de terceiros, como DreamWeaver da Macromedia. Com isso teremos um e-mail mais elegante. Bem, finalmente vamos codificar o nosso glorioso boto btEnvia. Insira o cdigo que segue no evento OnClick do objeto btEnvia. procedure TfmeMail.btEnviaClick(Sender: TObject); begin // Configura Cliente idSMTP1.UserId:=edUsuario.Text; idSMTP1.Password:=edSenha.Text; idSMTP1.Host:=edHost.Text; idSMTP1.Port:=StrtoInt(edPorta.Text); // Atribui o Conteudo do objeto TextodoEmail // ao objeto PPMensagem ppMensagem.HTMLDoc:=TextodoEmail.Lines;
Enviando E-mails 121 // Abre a tabela Clientes tbClientes.Open; tbClientes.First; // Conecta ao Servidor SMTP idSMTP1.Connect; try with Mensagem do begin // Atribui o contedo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o contedo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; // inicia o lao while not(tbClientes.Eof) do begin // Atribui o contedo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; // Atribui o contedo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; // Envia a mensagem idSMTP1.Send(Mensagem); // Prximo registro tbClientes.Next; end; // lao end; // with Mensagem finally // Disconecta Servidor idSMTP1.Disconnect; end; end; Vamos analisar com cuidado este cdigo. No primeiro bloco, estamos configurando o Cliente SMTP atravs do nosso objeto idSMTP1. // Configura Cliente idSMTP1.UserId:=edUsuario.Text; idSMTP1.Password:=edSenha.Text; idSMTP1.Host:=edHost.Text; idSMTP1.Port:=StrtoInt(edPorta.Text); Repare que estamos configurando o usurio da conta UserId, a senha Password, o HOST e a porta de conexo (Port). O bloco seguinte atribui o contedo do objeto TextodaMensagem ao objeto PPMensagem.
122 Delphi 7 Internet e Banco de Dados // Atribui o Conteudo do objeto TextodoEmail // ao objeto PPMensagem ppMensagem.HTMLDoc:=TextodoEmail.Lines; A propriedade HTMLDoc armazena um documento para ser processado pelo prprio objeto. O bloco que segue abre a tabela de Clientes e posiciona o ponteiro no primeiro registro: // Abre a tabela Clientes tbClientes.Open; tbClientes.First; O bloco a seguir conecta o objeto idSMTP1 ao servidor de SMTP. // Conecta ao Servidor SMTP idSMTP1.Connect; Agora estamos protegendo o cdigo seguinte com o comando Try/Except/Finally. Em seguida estamos atribuindo o assunto da mensagem e o responsvel pelo envio da mesma. with Mensagem do begin // Atribui o conteudo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o conteudo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; Como as mensagens so enviadas uma a uma, fizemos um lao percorrendo toda a tabela de Clientes. while not(tbClientes.Eof) do Neste ponto estamos configurando o e-mail destino. // Atribui o conteudo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; Chegamos ao ponto mais interessante do nosso projeto. Neste bloco estamos associando o resultado do ppMensagem ao corpo da mensagem do objeto Mensagem. Quando chamamos o mtodo Content, ativamos o processamento das informaes contidas na propriedade HTMLDOC do objeto. // Atribui o contedo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; E finalmente enviamos a mensagem. // Envia a mensagem idSMTP1.Send(Mensagem); Bem, amigos, acredito que agora basta usar a imaginao para enviar os e-mails de maneira personalizada. Com isso conclumos nosso projeto de envio de e-mails, e de quebra refrescamos nossas idias com um novo tipo de aplicao.
124 Delphi 7 Internet e Banco de Dados IdAntiFreeze1: TIdAntiFreeze; Mensagem: TIdMessage; ppMensagem: TDataSetPageProducer; IdSMTP1: TIdSMTP; procedure btArquivoClick(Sender: TObject); procedure btEnviaClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var fmeMail: TfmeMail; implementation {$R *.xfm} procedure TfmeMail.btArquivoClick(Sender: TObject); begin if AbrirArquivo.Execute then begin EdTexto.Text:=AbrirArquivo.FileName; // Zera O TextodoEmail TextodoEmail.Clear; // Associa o Arquivo Texto/HTML com o objeto // TextodoEmail TextodoEmail.Lines.LoadFromFile(edTexto.Text); end; end; procedure TfmeMail.btEnviaClick(Sender: TObject); begin // Configura Cliente idSMTP1.UserId:=edUsuario.Text; idSMTP1.Password:=edSenha.Text; idSMTP1.Host:=edHost.Text; idSMTP1.Port:=StrtoInt(edPorta.Text); // Atribui o Conteudo do objeto TextodoEmail // ao objeto PPMensagem ppMensagem.HTMLDoc:=TextodoEmail.Lines; // Abre a tabela Clientes tbClientes.Open; tbClientes.First; // Conecta ao Servidor SMTP idSMTP1.Connect; try with Mensagem do
Enviando E-mails 125 begin // Atribui o conteudo do edAssunto // ao objeto Mensagem.Subject Subject:=edAssunto.Text; // Atribui o conteudo do edConta // ao objeto Mensagem.From.Text From.Text:=edConta.Text; // inicia o lao while not(tbClientes.Eof) do begin // Atribui o conteudo do campo EMAIL // ao objeto Mensagem.Recipients.EmailAddresses Recipients.EMailAddresses:=tbClientes.FieldByName('EMAIL').Value; ReceiptRecipient.Address:=tbClientes.FieldByName('EMAIL').Value; // Atribui o contedo do objeto ppMensagem // ao objeto Mensagem.Body.Text Body.Text:=ppMensagem.Content; // Envia a mensagem idSMTP1.Send(Mensagem); // Prximo registro tbClientes.Next; end; // lao end; // with Mensagem finally // Disconecta Servidor idSMTP1.Disconnect; end; end; end.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 9
Desenvolvendo utilitrios para Internet
OBJETO pnTopo TPanel Objeto TPanel Propriedade Align Caption Name Valor alTop pnTopo
127
128 Delphi 7 Internet e Banco de Dados Com o foco no objeto pnTopo insira os seguintes objetos:
OBJETO Label1 TLabel Objeto TLabel Propriedade Caption Left Top Valor HOST 16 14
OBJETO Label2 TLabel Objeto TLabel Propriedade Caption Left Top Valor Porta Inicial 16 43
OBJETO Label3 TLabel Objeto TLabel Propriedade Caption Left Top Valor Porta Final 232 43
Agora vamos inserir os objetos de controle e interatividade com o usurio. Mantenha o foco no objeto pnTopo e insira os seguintes objetos:
OBJETO NomeServidor TEdit Objeto TEdit Propriedade Name Left Top Width Valor NomeServidor 104 10 290
OBJETO Inicio TSpinEdit [Samples] Objeto TSpinEdit Propriedade Name Left Top Valor Inicio 104 40
OBJETO Fim TSpinEdit [Samples] Objeto TSpinEdit Propriedade Name Left Top Valor Fim 320 40
Neste ponto vamos inserir o boto para iniciar o processo de scanner de portas.
OBJETO btScan TButton Objeto TButton Propriedade Name Caption Left Top Valor btScan Scan 416 8
Com isso conclumos a primeira etapa do projeto. Prosseguindo, vamos criar o mdulo de sada das informaes. Agora com o foco no formulrio e no mais no objeto pnTopo, insira um objeto do tipo Tpanel alterando as seguintes propriedades:
OBJETO pnDados TPanel Objeto TPanel Propriedade Align Name Valor alClient pnDados
OBJETO ListadePortas TMemo Objeto TMemo Propriedade Name Height Left Top Width Valor ListadePortas 180 16 76 500
Dentro deste mesmo painel pnDados, insira outro objeto do tipo TPanel alterando as propriedades que seguem:
OBJETO PnProgresso TPanel Objeto TPanel Propriedade Name Caption Height Left Top Width Valor pnProgresso 65 16 8 500
Amigos, sei que um pouco cansativo, mas estamos quase no final. Com o foco no objeto pnProgresso insira os seguintes objetos:
OBJETO btParar TButton Objeto TButton Propriedade Name Caption Left Top Valor btParar Parar 400 32
OBJETO ProgressBar1 TProgressBar Objeto TProgressBar Propriedade Name Left Top Width Valor ProgressBar1 16 8 470
OBJETO Label4 TLabel Objeto TLabel Propriedade Caption Left Top Valor Scaneando Porta... 16 36
OBJETO porta TLabel Objeto TLabel Propriedade Caption Left Top Valor 0 112 36
Ufa!!! E para concluir a enorme lista de objetos, insira um do tipo TTCPClient que se encontra na seo Internet.
OBJETO TCPClient1 TTCPClient [Internet] Objeto TTCPClient Propriedade Name Valor TCPClient1
Finalmente vamos codificar o nosso projeto. Crie uma varivel global pertencente nossa classe Form1., com o nome Parar, do tipo Integer; veja: var Form1: TForm1; parar:integer; implementation A varivel Parar ser utilizada para finalizar o processo de Scanner das Portas. Neste ponto que poderamos criar uma Thread, mas no vamos complicar. S para aliviar um pouco a forte tenso, vamos dar uma olhadinha na interface do nosso projeto (figura 9.1):
// variavel auxiliar
132 Delphi 7 Internet e Banco de Dados Vamos codificar o boto btScan, responsvel pelo ncleo do nosso projeto. No evento onClick do objeto btScan, insira o cdigo que segue (para facilitar, numerei as linhas de programao, de forma que possamos analisar melhor o cdigo). 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 procedure TForm1.BtScanClick(Sender: TObject); var i:integer; begin try ListadePortas.Clear; // Limpa a Lista de Portas parar:=0; // 0 = continua, 1 = conclui
// Definies da barra de progresso ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value; PainelProgresso.Visible:=True; TcpClient1.RemoteHost := NomeServidor.Text; for i := Inicio.Value to Fim.Value do begin if parar=1 then break; // finaliza o lao ProgressBar1.Position:=i; porta.Caption:=inttostr(i); Application.ProcessMessages; TcpClient1.RemotePort := inttostr(i); TcpClient1.Active:=true; if TcpClient1.Connect then ListadePortas.Lines.Add('Porta ['+ inttostr(i) + '] aberta'); TcpClient1.Disconnect; // disconeta porta end; //for loop except on E:Exception do begin ListadePortas.Lines.Add('Erro: ' + E.Message); end; // end on do begin end; //try block ListadePortas.Lines.Add('Scaneamento das portas finalizado !');
040 PainelProgresso.Visible:=False; 041 end; 042 Vamos ao detalhamento do cdigo: A linha 002 declara uma varivel i que ir auxiliar no lao de contagem das portas. var i:integer; Na linha 004 iniciamos uma proteo de erros da aplicao.
Desenvolvendo utilitrios para Internet 133 try A linha 005 limpa o contedo do objeto ListaPortas. ListadePortas.Clear Na linha 007 inicializamos a varivel parar com o valor 0, de forma que o sistema continue scanneando as portas at o limite solicitado pelo usurio, ou atravs do pressionamento da tecla Parar, fazendo com que a varivel receba o valor 1. parar:=0; As linhas 011 e 012 configuram o objeto ProgressBar1 de maneira que o mesmo fique compatvel com as informaes porta inicial e final. Com isso temos um progresso adequado. ProgressBar1.Max:=Fim.Value; ProgressBar1.Min:=Inicio.Value; A linha 014 torna visvel o objeto PainelProgresso. PainelProgresso.Visible:=True; A linha 015 configura o servidor remoto do objeto TcpClient1. TcpClient1.RemoteHost := NomeServidor.Text; A linha 017 inicia um loop baseado nas informaes Porta Inicial e Final. for i := Inicio.Value to Fim.Value do J na linha 019 nossa aplicao verifica se existe a obrigao de paralisar o loop. Esta informao vem do boto btParar. if parar=1 then break; A linha 021 posiciona a barra de progresso em relao ao andamento do loop. ProgressBar1.Position:=i; Na linha 022 apenas mostramos ao usurio atravs do objeto Porta, qual porta est sendo scanneada no momento. porta.Caption:=inttostr(i); A linha 024 solicita ao Windows que processe as informaes da aplicao, de maneira que a mesma no tenha o efeito congelamento. Application.ProcessMessages; A linha 025 configura a porta que deve ser scanneada, a 026 tenta ativar, e a 028 verifica se houve sucesso na ativao, e em caso afirmativo, a linha 029 adiciona no objeto ListadePortas a informao de que a Porta est aberta. TcpClient1.RemotePort := inttostr(i); TcpClient1.Active:=true; if TcpClient1.Connect then ListadePortas.Lines.Add('Porta ['+ inttostr(i) + '] aberta'); A linha 031 desconecta a porta independente do seu estado (aberta ou fechada).
134 Delphi 7 Internet e Banco de Dados TcpClient1.Disconnect; A linha 032 finaliza o loop. As linhas 033, 034 e 035 tratam qualquer exceo ocorrida no bloco protegido (try...except...end). end; //for loop except on E:Exception do begin ListadePortas.Lines.Add('Erro: ' + E.Message); end; // end on do begin end; //try block Concluindo esta rotina, a linha 039 apresenta uma mensagem indicando o fim do scanneamento das portas e a 041 torna o objeto PainelProgresso invisvel. ListadePortas.Lines.Add('Scaneamento das portas finalizado !'); PainelProgresso.Visible:=False; Para concluir o nosso projeto, devemos codificar o boto btParar com o seguinte cdigo (no evento OnClick): Parar:=1; Amigos, agora s executar o aplicativo, informar o nome do servidor (caso seja seu prprio equipamento, digite localhost, no campo Nome do Servidor), e o intervalo de portas a serem scanneadas. A figura 9.2 ilustra nosso utilitrio scanneando um servidor.
IMPORTANTE Embora seja possvel, no recomendo o uso deste aplicativo para scannear portas de servidores no-autorizados. Normalmente utilizamos este tipo de aplicativo para vigiar nosso quintal e no o do vizinho. Artigo originalmente publicado na Revista The Club, n 94
Listagem 9.1
unit un_scan; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, Sockets, ComCtrls, ExtCtrls, Spin; type TForm1 = class(TForm) TcpClient1: TTcpClient; pnTopo: TPanel; BtScan: TButton; NomeServidor: TEdit; Label2: TLabel; Panel2: TPanel; ListadePortas: TMemo; PainelProgresso: TPanel; ProgressBar1: TProgressBar; Label1: TLabel; porta: TLabel; Inicio: TSpinEdit; Label3: TLabel; Label4: TLabel; Fim: TSpinEdit; btParar: TButton; procedure BtScanClick(Sender: TObject); procedure btPararClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; parar:integer; implementation {$R *.dfm} procedure TForm1.BtScanClick(Sender: TObject); var i:integer; begin try ListadePortas.Clear; // Limpa a Lista de Portas parar:=0; // 0 = continua, 1 = conclui
// variavel auxiliar
136 Delphi 7 Internet e Banco de Dados PainelProgresso.Visible:=True; // Visualiza painel progresso TcpClient1.RemoteHost := NomeServidor.Text; // define o HOST for i := Inicio.Value to Fim.Value do begin if parar=1 then break; // finaliza o lao ProgressBar1.Position:=i; porta.Caption:=inttostr(i); // atualiza ProgressBar // atualiza Label Porta
Application.ProcessMessages; // solicita ao Windows prioridade no processamento da aplicao TcpClient1.RemotePort := inttostr(i); // define porta a ser scaneada TcpClient1.Active:=true; // tenta ativar a porta if TcpClient1.Connect then ListadePortas.Lines.Add('Porta ['+ inttostr(i) + '] aberta'); TcpClient1.Disconnect; // disconecta porta end; //for loop except on E:Exception do begin ListadePortas.Lines.Add('Erro: ' + E.Message); end; // end on do begin end; //try block ListadePortas.Lines.Add('Scaneamento das portas finalizado!'); PainelProgresso.Visible:=False; end; procedure TForm1.btPararClick(Sender: TObject); begin Parar:=1; end; end.
Ping
Neste tpico vamos desenvolver uma nova verso para o ping. Mas Facunte, o que ping? O utilitrio ping, encontrado na maioria dos sistemas operacionais, como Windows e Linux, utilizado para ouvir uma resposta de um determinado servidor, e medir o tempo da mesma. Esta resposta pode ser nula, quando no se consegue estabelecer uma comunicao com o servidor, ou terminal remoto. Normalmente os testes de ping so feitos em servidores de Internet, firewall, roteadores e servidores de banco de dados. Vejamos um exemplo deste utilitrio rodando no sistema operacional Windows:
Figura 9.3 Ping sendo executado no Windows XP Neste exemplo, executamos o utilitrio ping no sistema operacional Windows XP, solicitando uma resposta do computador Servidor. Repare que o ping dispara um pacote de 32 bytes no endereo IP (200.173.173.142), relacionado ao Servidor, e ouve quatro respostas num tempo menor que 1ms (um milesegundo). Com isso poderemos medir a eficincia no trfego de dados entre cliente/servidor, seja l qual for a sua origem (servidor de banco de dados, aparelho celular, servidor Internet, PDA, entre outros). Veja alguns exemplos ilustrativos do utilitrio Ping (figuras 9.4, 9.5 e 9.6).
138 Delphi 7 Internet e Banco de Dados Como vimos, existem trs possibilidades de resultado: satisfatrio, sem resposta e lento. Com isso podemos fazer testes de performance em diversos tipos de servidores, e descobrir, em alguns casos, onde est o problema de lentido. Bem, amigos, agora vem a parte boa: mo-na-massa. Inicie um projeto do tipo CLX (Delphi 6 ou superior), pois poderemos executar nossa aplicao no Linux, compilando o projeto no Kylix. Grave a unit com o nome un_ping.pas e o projeto como ping.dpr. Insira o seguinte objeto, alterando suas propriedades.
Com o foco no objeto pnEndereco, insira os objetos que seguem, alterando suas respectivas propriedades:
Objeto TLabel[Standard]
Caption Left Top Endereo 12 20
Agora com o foco no formulrio, insira outro objeto do tipo TPanel e altere as propriedades que seguem:
Com o foco no objeto pnResultado insira um objeto do tipo TMemo e altere as seguintes propriedades:
Figura 9.7 Aplicao Ping em tempo de projeto Neste ponto iremos inserir o nosso objeto chave: TidICMPClient. Muita hora nesta calma, ou melhor, muita calma nesta hora, amigos, no mais um imposto do governo, apenas o nosso componente chave. Facunte, que nome complicado de componente! O que quer dizer ICMP? ICMP quer dizer Internet Control Message Protocol, ou Protocolo Internet de Controle de Mensagens. Este protocolo normalmente utilizado pelos utilitrios que iremos desenvolver, e basicamente serve para enviar mensagens a servidores remotos. Ok, ento vamos inserir o nosso objeto TidICMPClient, e alterar as seguintes propriedades:
Perceba que alteramos a propriedade ReceiveTimeout. Esta propriedade indica o tempo mximo em milessegundos para uma resposta do servidor, gerando um timeout quando ultrapassado este tempo. Vamos codificar o boto btPing, inserindo o cdigo que segue no evento OnClick: var i: integer; begin btPing.Enabled:=False; try NossoICMP.Host := edEndereco.Text; for i := 1 to 4 do begin NossoICMP.Ping; Application.ProcessMessages; end; finally btPing.Enabled := True; end; end; Vamos analisar o cdigo. Primeiro, estamos declarando uma varivel do tipo integer para nos auxiliar no lao do ping. var i: integer; Em seguida desabilitamos o boto btPing, impedindo o usurio de clicar vrias vezes e causar um efeito redundante. btPing.Enabled:=False;
140 Delphi 7 Internet e Banco de Dados No prximo ponto, protegemos o cdigo com try para que eventuais erros sejam ignorados em nossa aplicao. try Em seguida configuramos a propriedade Host do nosso objeto NossoICMP de acordo com a informao do usurio extrada do objeto edEndereco. NossoICMP.Host := edEndereco.Text; Finalmente iniciamos o lao, executando o comando Ping 4 vezes (padro), e solicitando ao S.O. uma atualizao da aplicao. for i := 1 to 4 do begin NossoICMP.Ping; Application.ProcessMessages; end; E para concluir esta parte do cdigo, finalizamos o bloco protegido, habilitando novamente o boto btPing. finally btPing.Enabled := True; end; Agora, iremos codificar o evento OnReply do objeto NossoICMP. Este evento responsvel pelas informaes de resposta. Coloque o cdigo a seguir no evento OnReply: var sTime:string; begin if (AReplyStatus.MsRoundTripTime = 0) then sTime := '<1' else sTime := '='; mmResultado.Lines.Add(Format('%d bytes de %s: sequencia#=%d tempo-de-vida(ttl)=%d tempo%s%d ms', [AReplyStatus.BytesReceived, AReplyStatus.FromIpAddress, AReplyStatus.SequenceId, AReplyStatus.TimeToLive, sTime, AReplyStatus.MsRoundTripTime])); end; Nossa Facunte, agora complicou! Que cdigo maluco esse? Amigos, primeira vista, realmente meio maluco, mas iremos desvendar rapidamente o mistrio. Primeiro declaramos uma varivel para nos auxiliar na composio da resposta: var sTime:string; Em seguida estamos verificando a propriedade MsRoundTripTime da constante AReplyStatus. Tudo bem, e de onde vem esta constante, e o que quer dizer MsRoundTripTime? Bem, a constante foi declarada no cabealho do evento OnReply, vejam: procedure TForm1.NossoICMPReply(ASender: TComponent; const AReplyStatus: TReplyStatus);
Desenvolvendo utilitrios para Internet 141 Esta uma declarao padro para o evento OnReply do objeto NossoICMP. Com relao propriedade MsRoundTripTime, ela representa o tempo em milessegundos do resultado de retorno do pacote. Caso o resultado seja 0, ento atribumos o valor < 1 nossa varivel sTime, seno, atribumos o valor = . Prosseguindo com a nossa anlise, agora vem o ponto forte da nossa aplicao: a linha de resultado. mmResultado.Lines.Add(Format('%d bytes de %s: sequencia#=%d tempo-de-vida(ttl)=%d tempo%s%d ms', [AReplyStatus.BytesReceived, AReplyStatus.FromIpAddress, AReplyStatus.SequenceId, AReplyStatus.TimeToLive, sTime, AReplyStatus.MsRoundTripTime])); Percebam que estamos adicionando contedo ao nosso objeto mmResultado: mmResultado.Lines.Add Estamos nos aproveitando da funo Format para facilitar a composio da linha de resultado. Para quem no conhece a funo Format, sugiro uma breve visita no Help do Delphi, onde sempre encontramos ricas informaes. Vejamos os significados das propriedades da constante AReplyStatus. BytesReceived FromIpAddress SequenceId TimeToLive = = = = bytes recebidos endereo do Host nmero da sequncia Tempo de vida do pacote
Agora vamos executar o nosso projeto e ver o resultado. A figura 9.8 ilustra o nosso projeto em execuo.
Misso Cumprida
Ao final deste tpico, espero ter esclarecido a todos a utilidade do Ping, bem como ter transmitido com clareza as funcionalidades do objeto TidICMPClient.
Desenvolvendo utilitrios para Internet 143 Application.ProcessMessages; end; finally btPing.Enabled := True; end; end; procedure TForm1.NossoICMPReply(ASender: TComponent; const AReplyStatus: TReplyStatus); var sTime:string; begin if (AReplyStatus.MsRoundTripTime = 0) then sTime := '<1' else sTime := '='; mmResultado.Lines.Add(Format('%d bytes de %s: sequencia#=%d tempo-de-vida(ttl)=%d tempo%s%d ms', [AReplyStatus.BytesReceived, AReplyStatus.FromIpAddress, AReplyStatus.SequenceId, AReplyStatus.TimeToLive, sTime, AReplyStatus.MsRoundTripTime])); end; end.
TraceRoute (Tracert)
Neste tpico vamos desenvolver uma nova verso para o trace route. Muito semelhante ao nosso utilitrio ping, mas com funcionalidades mais completas, apresentando todos os servidores por onde trafegam os pacotes de informaes, entre cliente e servidor final. A figura 9.9 ilustra uma simulao do trace route.
Cliente (Brasil)
Provedor de Acesso
BackBone Embratel
Figura 9.9 Simulao do Trace Route Com o trace route poderemos descobrir falhas ou lentido de resposta em todos os servidores envolvidos no processo de envio e recebimento de pacotes. Normalmente falamos que o site X est extremamente lento. Nem sempre o prprio site, pode ser um dos servidores envolvidos (conhecido como hope) no processo. Nosso utilitrio uma adaptao de um programa de demonstrao que vem no pacote da INDY Components. Vamos iniciar o desenvolvimento do nosso utilitrio. Atravs das opes File/New...CLX Application, crie uma nova aplicao. Grave a unit com o nome un_tracert.pas e o projeto como tracert.dpr. Insira os objetos que seguem alterando suas respectivas propriedades.
Desenvolvendo utilitrios para Internet 145 Com o foco no objeto pnTopo, insira os objetos que seguem, alterando suas respectivas propriedades:
Ainda com o foco no PnTopo, insira um objeto do tipo TMemo, e altere as seguintes propriedades.
Agora com o foco no objeto PnDados, insira os objetos que seguem, alterando suas respectivas propriedades:
Objeto TLabel[Standard]
Caption Left Top Host Destino 12 8
Objeto TLabel[Standard]
Caption Left Top Mximo Hopes 12 40
Agora com o foco no Formulrio, insira outro componente do tipo TPanel alterando as seguintes propriedades.
Com o foco no objeto pnInfo insira um componente do tipo TListView, alterando as seguintes propriedades.
Figura 9.10 Columns.items do listview1 Insira os objetos que seguem, alterando as respectivas propriedades.
Figura 9.11 Formulrio do projeto Tracert Para facilitar a organizao das nossas procedures e aes, vamos utilizar o componente ActionList. Insira um objeto do tipo TActionList e atravs do duplo-clique insira as seguintes aes (figura 9.12).
: Figura 9.12 Aes do projeto Agora vamos codificar nosso projeto. Na seo private insira o cdigo que segue. bResolved: Boolean; ResolvedHost: String; Stopped: Boolean; function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; Nesta seo, definimos algumas variveis e funes com o objetivo de auxiliar em alguns processos. bResolved: Boolean; ResolvedHost: String; Stopped: Boolean;
148 Delphi 7 Internet e Banco de Dados bResolved ResolvedHost Stopped para atribuir true ou false na operao de ping para atribuir o host (hope) em operao atribui o valor true para informar a paralisao das operaes.
function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; Na clusula uses insira as seguintes Units. uses idStack, IdException; Agora vamos codificar as aes: No evento OnExecute da Action acGO, insira o cdigo que segue: try Stopped := false; acGo.Enabled := false; acStop.enabled := true; acResolve.execute; if bResolved and not stopped then begin acPing.execute; if not stopped then acTrace.Execute; end; acGo.Enabled := true; acStop.enabled := false; finally { ok } end; { try/finnaly } Nesta rotina estamos atribuindo as definies iniciais do nosso projeto, e executando as rotinas de ping e trace. No evento OnExecute da Action acResolve, insira o cdigo que segue: bResolved := false; lbLog.Items.Append(Format('resolvendo %s', [edTarget.text])); try Application.ProcessMessages; ResolvedHost := gStack.WSGetHostByName(edTarget.text); bResolved := true; lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost])); except on e: EIdSocketError do lbLog.Items.text := lbLog.Items.text + e.message; end; Neste cdigo estamos resolvendo um host (hope), ou melhor, verificando informaes e possibilidade de contato com o host. Repare que estamos utilizando a funo WSGetHostByName, da unit IdStack, para mapear e resolver o host. ResolvedHost := gStack.WSGetHostByName(edTarget.text); Se a operao for bem sucedida, adicionamos no lbLog o resultado; caso contrrio, a mensagem de erro. Operao bem sucedida lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost]));
Desenvolvendo utilitrios para Internet 149 Erro. except on e: EIdSocketError do lbLog.Items.text := lbLog.Items.text + e.message; No evento OnExecute da Action acPing, insira o seguinte cdigo. PingHost(ResolvedHost, seMaxHops.value); Application.ProcessMessages; Aqui estamos executando a chamada da funo PingHost (ser criada posteriormente), com o host atual, e o mximo de hopes. No evento OnExecute da Action acTrace, insira o cdigo que segue. var TTL: Integer; Reached: boolean; aItem: TListItem; begin TTL := 0; reached := false; lvTrace.Items.Clear; repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Reached in : %d ms', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); reached := true; end; rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end; rsTimeOut: begin aItem.SubItems.Append('?.?.?.?'); aItem.SubItems.Append('Timed out.'); end; rsErrorUnreachable: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Destination network [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress);
unreachable',
150 Delphi 7 Internet e Banco de Dados aItem.SubItems.Append(format('TTL=%d', [IdIcmpClient.ReplyStatus.TimeToLive])); end; end; // case Application.ProcessMessages; until reached or (TTL > seMaxHops.value) or Stopped; Este cdigo um pouco mais complexo, mas vamos analisar passo a passo. Inicialmente, estamos definindo algumas variveis auxiliares. TTL Reached aItem define o hope atual. define se o TTL atual foi resolvido objeto do tipo TListItem para ser adicionado em nosso LvTrace.
var TTL: Integer; Reached: boolean; aItem: TListItem; Em seguida temos a atribuio inicial das variveis. TTL := 0; reached := false; lvTrace.Items.Clear; O bloco que segue inicia um lao, at que uma das trs situaes (resolvido reached = true, TTL > hopes, ou solicitao de cancelamento) seja verdadeira. Incrementamos o TTL, e atribumos ao objeto idICMPClient algumas configuraes, como Host e TTL. Executamos o mtodo ping do idICMPClient, e em seguida preparamos o objeto aItem para receber a informao do resultado da operao. repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear; Os prximos blocos tratam os diversos tipos de resultado do mtodo ping. O bloco que segue trata o tipo de resposta (rsEcho) e adiciona um subitem ao objeto aItem. case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Reached in : %d ms', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); reached := true; end; O bloco seguinte recebe um tipo de resposta de erro (rsError) e tambm adiciona um subitem ao objeto aItem. rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end;
Desenvolvendo utilitrios para Internet 151 O prximo bloco trata o TimeOut excedido (rsTimeOut), definido como 5000 milesegundos. rsTimeOut: begin aItem.SubItems.Append('?.?.?.?'); aItem.SubItems.Append('Timed out.'); end; Em seguida, temos o tratamento de uma operao no resolvida (rsErrorUnreachable). rsErrorUnreachable: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Destination network unreachable', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; E por fim, temos o tratamento de erro (rsErrorTTLExceeded), onde excedido o nmero mximo de tentativas. rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('TTL=%d', [IdIcmpClient.ReplyStatus.TimeToLive])); end; end; // case Application.ProcessMessages; until reached or (TTL > seMaxHops.value) or Stopped; um cdigo realmente complexo, mas estudando com calma e ateno, entenderemos cada mtodo implementado. Agora no evento OnExecute da Action acStop, insira o cdigo que segue. Stopped := true; acStop.enabled := false; Com isso estamos solicitando uma parada nas operaes. Agora vamos atribuir as Actions acGO e acStop, ao objeto btExecuta e btCancela, respectivamente. Para tanto, basta selecionar a Action desejada do objeto em questo. Para finalizar nosso projeto, devemos criar as rotinas que seguem. function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; Primeiro vamos criar a rotina PingHost. Insira o cdigo que segue em nossa unit. function Tform1.PingHost(Host: string; TTL: Integer): Boolean; begin result := false; IdIcmpClient.Host := Host; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin
152 Delphi 7 Internet e Banco de Dados lbLog.Items.Append(format('resposta do host %s in %d milesegundos',[ IdIcmpClient.ReplyStatus.FromIpAddress, IdIcmpClient.ReplyStatus.MsRoundTripTime])); result := true; end; rsError: lbLog.Items.Append('Erro desconhecido'); rsTimeOut: lbLog.Items.Append('Timed out.'); rsErrorUnreachable: lbLog.Items.Append(format('Host %s no resolvido', [IdIcmpClient.ReplyStatus.FromIpAddress])); rsErrorTTLExceeded: lbLog.Items.Append(format('Hope %d %s: TTL expirou', [IdIcmpClient.TTL, idIcmpClient.ReplyStatus.FromIpAddress])); end; // case end; Repare que muito parecida com a Action acTrace, s que neste caso, estamos resumindo o resultado das operaes em nosso objeto lbLog. Agora vamos criar a rotina FindItem. Insira o cdigo que segue em nossa unit. function Tform1.FindItem(TTL: Integer; Add: boolean): TListItem; var i: Integer; begin result := nil; // Find the TTL item if lvTrace.Items.Count < TTL Then begin for i := 0 to lvTrace.Items.Count - 1 do begin if StrToIntDef(lvTrace.Items[i].Caption, -1) = TTL then begin result := lvTrace.Items[i]; Break; end; end; end; if not assigned( result ) then begin // Not found, add it result := lvTrace.Items.Add; result.Caption := IntToStr(TTL); end; end; O objetivo desta funo retornar informaes adicionadas no objeto lvTrace, baseada na TTL atual, e utilizada pela Action acTrace. Agora vamos gravar e compilar nossa aplicao. A figura 9.13 ilustra nossa aplicao sendo executada.
154 Delphi 7 Internet e Banco de Dados acPing: TAction; acTrace: TAction; acStop: TAction; IdAntiFreeze1: TIdAntiFreeze; IdIcmpClient: TIdIcmpClient; lbLog: TListBox; procedure acGoExecute(Sender: TObject); procedure acResolveExecute(Sender: TObject); procedure acPingExecute(Sender: TObject); procedure acTraceExecute(Sender: TObject); procedure acStopExecute(Sender: TObject); private { Private declarations } bResolved: Boolean; ResolvedHost: String; Stopped: Boolean; function PingHost(Host: string; TTL: Integer): boolean; function FindItem(TTL: Integer; Add: boolean): TListItem; public { Public declarations } end; var Form1: TForm1; implementation uses idStack, IdException; {$R *.xfm} procedure TForm1.acGoExecute(Sender: TObject); begin try Stopped := false; acGo.Enabled := false; acStop.enabled := true; acResolve.execute; if bResolved and not stopped then begin acPing.execute; if not stopped then acTrace.Execute; end; acGo.Enabled := true; acStop.enabled := false; finally { ok } end; { try/finally } end; procedure TForm1.acResolveExecute(Sender: TObject); begin bResolved := false; lbLog.Items.Append(Format('resolvendo %s',[edTarget.text]));
Desenvolvendo utilitrios para Internet 155 try Application.ProcessMessages; ResolvedHost := gStack.WSGetHostByName(edTarget.text); bResolved := true; lbLog.Items.Append(format('%s resolvido %s',[edTarget.text, ResolvedHost])); except on e: EIdSocketError do lbLog.Items.text := lbLog.Items.text + e.message; end; end; procedure TForm1.acPingExecute(Sender: TObject); begin PingHost(ResolvedHost, seMaxHops.value); Application.ProcessMessages; end; procedure TForm1.acTraceExecute(Sender: TObject); var TTL: Integer; Reached: boolean; aItem: TListItem; begin TTL := 0; reached := false; lvTrace.Items.Clear; repeat inc(TTL); IdIcmpClient.Host := ResolvedHost; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; aItem := FindItem(TTL, True); aItem.SubItems.Clear; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Reached in : %d ms', [IdIcmpClient.ReplyStatus.MsRoundTripTime])); reached := true; end; rsError: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append('Unknown error.'); end; rsTimeOut: begin aItem.SubItems.Append('?.?.?.?'); aItem.SubItems.Append('Timed out.'); end; rsErrorUnreachable: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('Destination network unreachable',
156 Delphi 7 Internet e Banco de Dados [IdIcmpClient.ReplyStatus.MsRoundTripTime])); break; end; rsErrorTTLExceeded: begin aItem.SubItems.Append(IdIcmpClient.ReplyStatus.FromIpAddress); aItem.SubItems.Append(format('TTL=%d', [IdIcmpClient.ReplyStatus.TimeToLive])); end; end; // case Application.ProcessMessages; until reached or (TTL > seMaxHops.value) or Stopped; end; procedure TForm1.acStopExecute(Sender: TObject); begin Stopped := true; acStop.enabled := false; end; function TForm1.PingHost(Host: string; TTL: Integer): Boolean; begin result := false; IdIcmpClient.Host := Host; IdIcmpClient.TTL := TTL; IdIcmpClient.ReceiveTimeout := 5000; IdIcmpClient.Ping; case IdIcmpClient.ReplyStatus.ReplyStatusType of rsEcho: begin lbLog.Items.Append(format('response from host %s in %d millisec.', [ IdIcmpClient.ReplyStatus.FromIpAddress, IdIcmpClient.ReplyStatus.MsRoundTripTime ])); result := true; end; rsError: lbLog.Items.Append('Unknown error.'); rsTimeOut: lbLog.Items.Append('Timed out.'); rsErrorUnreachable: lbLog.Items.Append(format('Host %s reports destination network unreachable.', [ IdIcmpClient.ReplyStatus.FromIpAddress ])); rsErrorTTLExceeded: lbLog.Items.Append(format('Hope %d %s: TTL expired.', [ IdIcmpClient.TTL, IdIcmpClient.ReplyStatus.FromIpAddress ])); end; // case end;
Desenvolvendo utilitrios para Internet 157 function TForm1.FindItem(TTL: Integer; Add: boolean): TListItem; var i: Integer; begin result := nil; // Find the TTL item if lvTrace.Items.Count < TTL Then begin for i := 0 to lvTrace.Items.Count - 1 do begin if StrToIntDef(lvTrace.Items[i].Caption, -1) = TTL then begin result := lvTrace.Items[i]; Break; end; end; end; if not assigned( result ) then begin // Not found, add it result := lvTrace.Items.Add; result.Caption := IntToStr(TTL); end; end;
end.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 10
Viso geral
Amigos, neste captulo iremos aprender a desenvolver aplicaes WAP para celulares. Mas Facunte, o WAP no foi um fracasso no Brasil? Depende muito do ponto de vista de cada empresa, de cada brasileiro. O WAP uma realidade para muitas empresas, que mesmo aps diversas resistncias, adotaram a tecnologia em suas culturas empresariais. Cultura? isso mesmo! Cultura. O grande problema do WAP que ns brasileiros demoramos para nos acostumar com novidades, alm, claro, da barreira de resistncia a tornar um hbito certas coisas. verdade que o WAP no atingiu o que as teles previam, onde todos os seus assinantes utilizariam o WAP para algum tipo de servio. Isso mesmo, servio. A que est o pecado da coisa. Como pagar por uma coisa que nem sabemos utilizar? Faltou incentivo cultural. Mas, hoje em dia, muitas empresas aproveitam da tecnologia para fora de vendas, troca de mensagens em grupo, pesquisa de campo, entre outras aplicaes que veremos ao longo do captulo.
WAP no Brasil
Continuando com a nossa discusso, ser que temos oportunidades de lucro no Brasil? A oportunidade existe, mas poucas empresas esto investindo nesta rea, certamente lucrativa. Ser que sou um romntico sonhador? Sonhando com o lucro em tempos de vacas magras? Amigos, posso afirmar que no, pois em 2000, quando lancei meu livro de WAP (Wap Guia de Tecnologia), o mercado estava muito aquecido, devido s fortes propagandas de empresas de telefonia em torno do WAP, mas na poca, a barreira cultural de nosso pas quase levou o sonho destas empresas por gua abaixo. Sabem o que elas fizeram? Deixaram o WAP de lado e continuaram a investir em aparelhos mveis, mas destacando apenas sua beleza e algumas funcionalidades. Facunte, ento o sonho do lucro ficou ainda mais distante? Amigos, a que entra o consultor, para explicar aos gerentes de tecnologia, CEOs, que a relao custo benefcio com o WAP muito boa, e que o desenvolvimento quase transparente, pois podemos criar aplicaes WAP na maioria das linguagens, como: Delphi, .NET (VB, C#, ASP), PHP, Java (JSP, EJB), entre outras.
159
Modelos de Aparelhos
A disponibilidade de aparelhos no Brasil muito grande, e o preo um forte atrativo, variando entre R$ 199,00 (modelo LG DM 160), at R$ 1.999,00 (Nokia 9210). Imaginem uma equipe de vendas, ou at mesmo uma equipe de pesquisadores, com modelos mais baratos, em torno de R$ 199,00, fechando negcios, elaborando pesquisas, consultando clientes, disponibilidade de estoque, entre outros.
Motorola v.8160
LG DM 160
Startac 7860
Ericsson T60
LG TM 520
LG DM 515
Siemens SX45
Nokia 9210
Cases de Sucesso
Para provar a fora do WAP, vamos conhecer alguns cases de sucesso.
InvestShop.COM.BR
A instituio financeira InvestShop desenvolveu em conjunto com a EverSystem (talvez a maior empresa de desenvolvimento deste setor) uma soluo bastante robusta oferecendo ao usurio um controle total de suas aplicaes. S para ter uma idia, a aplicao disponibiliza at grficos de aes em celulares WAP. realmente incrvel.
DETRAN-SP
Um dos pioneiros na tecnologia WAP, o DETRAN de So Paulo disponibiliza informaes de Multas, Pontuaes na Carteira, entre outros. Viram como o poder do WAP grande? Basta uma idia para transform-lo em lucro!
HTTP/WML
WML/HTTP
celular (cliente)
Servidor
GateWay
162 Delphi 7 Internet e Banco de Dados Na ilustrao, temos um celular, que funciona como o nosso cliente (terminal), onde solicita os servios ao servidor. Os dados (WML) trafegam atravs do protocolo HTTP. Quando os dados chegam no servidor, o mesmo tem que interpretar a requisio, e esse servio feito pelo GateWay. O GateWay tambm tem como funo empacotar o resultado da requisio, para que o servidor retransmita ao celular. Em resumo, necessitamos de duas aplicaes bsicas no servidor: Servidor HTTP (recomendo o Apache Server) Nossa aplicao servidora.
Um detalhe bastante interessante que o Apache Server traz consigo embutido um excelente GateWay WAP. Embora esteja documentado que o Apache apenas suporta aplicaes WAP, ele possui toda a implementao necessria para um perfeito funcionamento. Para que possamos prosseguir no desenvolvimento de nossas aplicaes, precisamos tambm de um simulador WAP. Existem vrios no mercado, mas particularmente prefiro o Deck-it da PyWeb. A figura 10.2 ilustra a interface do Deck-it.
Figura 10.2 Deck-it O Deck-it est disponvel no site da PyWeb (www.pyweb.com) e, assim como o Apache, totalmente freeware.
Mime-Types WAP
Outra coisa importante a saber so os MimeTypes WAP. Mas o que so MimeTypes? Para que os servidores HTTP reconheam um tipo de requisio, ou ento, um mtodo de envio, necessria a definio dos MimeTypes. S para clarear um pouco a informao, uma imagem do tipo JPG definida como image/JPG. Com isso o servidor saber qual o melhor mtodo de transmisso para este tipo de arquivo.
Mime Types do WAP Tipo de Arquivo Cdigo-fonte WML WML compilado Cdigo-fonte WMLScript WMLScript compilado Imagem bitmap Extenso .wml .wmlc .wmls .wmlcs .wbmp MIME Type text/vnd.wap.wml application/vnd.wap.wmlc text/vnd.wap.wmlscript application/vnd.wap.wmlscriptc image/vnd.wap.wbmp
Aplicaes para Celulares 163 Vamos adicionar os Mime-Types ao Apache, embora a partir da verso 1.3.1 j estejam implementados todos os tipos necessrios. No arquivo httpd.conf adicione as seguintes linhas: AddType AddType AddType AddType text/vnd.wap.wml image/vnd.wap.wbmp text/vnd.wap.wmlscript application/vnd.wap.wmlscriptc .wml .wbmp .wmls .wlsc
WML
O WML, Wireless Markup Language, a linguagem de programao para o desenvolvimento de documentos WAP. Muito parecida com o HTML e tambm com alguns conceitos do XML. Uma das caractersticas desta linguagem a adoo do case sensitive, ou seja, deck diferente de Deck ou DECK. Fique atento. Normalmente utilizamos letras minsculas para trabalhar com as Tags WML.
Minha opinio
O WML evoluiu muito durante os tempos e o consrcio formado para a criao deste padro continua investindo na tecnologia. Muitas pessoas comentam que o WAP ruim, que isso, que aquilo, mas como disse anteriormente, a oportunidade est a, batendo na sua porta. Voc vai ficar dando ouvidos a quem nunca ao menos tentou fazer a coisa certa?.
TAGS WML
<a> Cria um hiperlink ligando uma URL, ou ID de outra Tag. recomendado o uso desta Tag ao invs da Tag <anchor>. Exemplo
Obrigatrio No No No Sim No
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Definio da linguagem XML Link de referncia Texto, descrevendo o link
A Tag <access> define o controle de acesso a um deck. Na realidade controla acessos preestabelecidos de acordo com a combinao domain+path, ou seja, voc poder definir se determinado deck poder ser acessado a partir de um determinado domnio ou path (caminho). Exemplo:
permitido
www.facunte.com.br/VIP/x.wml www.facunte.com.br/VIP/index.wml
no permitido
www.facunte.com.br/livros.wml www.facunte.com.br/x.wml
Neste exemplo determinamos que o deck atual s poder ser acessado, a partir de uma requisio da domnio facunte.com.br, e do caminho /VIP, ou seja, somente quem estiver no diretrio /VIP poder acessar as informaes do deck em questo. Atributos
Obrigatrio No No No No
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Domnio que poder acessar o elemento Caminho dentro do domain (domnio) que poder acessar o elemento. Se no for especificado, todos os caminhos do domain podero acessar o elemento
Aplicaes para Celulares 165 <b> Tag utilizada para formatar textos em negrito. recomendado o uso da Tag <strong> ao invs de <b>, <i> ou <u>. Exemplo:
<card id =menu> ... </card> <card id =opcao1> .. </card> <card id =opcao2> .. </card> <card id =opcao3> .. </card>
Obrigatrio No No No No No No
Padro
No Sim
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Indentificao do carto Indica ao browser para trazer o card em questo atualizado Organiza o card
Descrio Utilizado em conjunto com o elemento GO (veja nas prximas pginas) Utilizado em conjunto com o elemento PREV (veja nas prximas pginas) Utilizado para disparar uma referncia, que pode ser um CARD ou outra URL, quando o tempo determinado expirar
<do> Esta Tag utilizada para acessar informaes acima do card atual. Exemplos:
Obrigatrio No No No Sim No No No
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Tipos definidos do elemento (veja tabela a seguir) Texto descritivo do elemento, visvel para o usurio Identifica o nome de ligao Define o elemento como opcional
Descrio Reconhecimento positivo Navegao de retorno Ajuda Limpar, ou resetar Solicitao para opes ou operaes adicionais Apagar item De uso genrico
Utilizada para formatar o texto de maneira enfatizada, parecida com a Tag <big>. Exemplo:
Obrigatrio No No No No
<fieldset title=endereco> Endereco: <input type=text name=fendereco maxlength=50/> <br/> Cidade: <input type=text name=fcidade maxlength=30/> <br/> Estado: <input type=text name=festado maxlength=2/> <br/> Cep: <input type=text name=fcep maxlength=8/> <br/> </fieldset> <fieldset title=telefones> Fone_Residencial: <input type=text name=fresidencial maxlength=20/> <br/> Fone_Comercial: <input type=text name=fcomercial maxlength=20/>
Obrigatrio No No No No No No
Padro
method optional
Exemplo:
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Endereo URL (caminho) Em caso verdadeiro(True), o browser do usurio dever especificar o URL do deck contendo esta tarefa Mtodo de envio de dados (POST ou GET) Define o elemento como opcional
... <card id=inicio title=teste > <do type=accept label=envia> <go href=#recebe> </do> <p>clique em envia para ir ao card recebe</p> </card> <card id=recebe title=teste > <do type=accept label=volta> <go href=#inicio> </do> <p>clique em volta para retornar</p>
Aplicaes para Celulares 169 <head> A tag <head> contm informaes sobre o documento, como os metadatas e as tags de controle de acesso. Atributos
Nome id class
Descritivo dos Atributos
Obrigatrio No No
Padro
Atributo id class
<i>
Utilizada para formatar o texto em itlico. Exemplo: <i> Seja bem-vindo </i> <img> A tag <img> utilizada para incluir uma imagem no documento. As imagens devem seguir o padro WBMP. Veremos um tpico abordando este assunto. Atributos
Nome id class xml:lang alt scr localscr vspace hspace align height width
Descritivo dos Atributos
Tipo String String String String URL String Length Length String Length Length
Obrigatrio No No No No Sim No No No No No No
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Texto a ser exibido enquanto a imagem carregada, ou numa possvel falha em seu carregamento
height width
Exemplos:
Descrio Especifica o caminho da imagem Alternativa imagem Espao em branco vertical Espao em branco horizontal Alinhamento da imagem em relao pgina top topo da pgina middle meio bottom alinhada abaixo da pgina Tamanho vertical da imagem Tamanho horizontal da imagem
<img src=logo.WBMP> <img alt=logo src=logo.WBMP> <img alt=logo src=logo.WBMP width=32 height=32> <img alt=logo src=logo.WBMP width=32 height=32 vspace=2> <img alt=logo src=logo.WBMP width=32 height=32 hspace=2> <img alt=logo src=logo.WBMP align=top>
<input> A tag <input> utilizada para definir a entrada de dados para o usurio. Atributos
Nome id class xml:lang name type value format emptyok size maxlength tabindex title
Tipo String String String String Input_Type String String Boolean Number Number Number String
Obrigatrio No No No Sim No No No No No No No No
Padro
Atributo id class name type value format emptyok size maxlength tabindex title
Mscaras (A)
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Nome do elemento muito importante para tratar o dado Tipo da entrada de dados, que pode ser texto (text), ou senha (pass) Valor padro do campo Mscara do campo (veja a tabela que segue (A)) Permite a escolha de campos opcionais Largura da rea de entrada de dados Tamanho mximo, em caracteres, para a entrada de dados Como no Delphi ordem de entrada Titulo do campo
Mscara A a N X x M m *f nf
Exemplos
Descrio Letras maisculas e caracteres de pontuao Letras minsculas e caracteres de pontuao Somente nmeros Somente letras maisculas Somente letras minsculas Qualquer caractere e assume maisculo (dependendo do browser) Qualquer caractere e assume minsculo (dependendo do browser) Somente caractere numrico Caractere numrico 0 a 9
<input name=nome type=text maxlength=50> <input name=cep type=text maxlength=8 format=NNNNNNNN> <input name=nome type=text maxlength=50> <input name=pais type=text value=Brasil>
<meta> A tag <meta> contm informaes genricas relativas ao deck do WML. Assim, como no padro HTML, utilizada para definir alguns dados do documento.
Nome Id class http-equiv name forua content scheme Descritivo dos Atributos Atributo id class http-equiv forua
Obrigatrio No No No No No Sim No
Padro
content scheme
<noop>
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Indica que a propriedade deve ser interpretada como um cabealho http Em caso de false, o intermedirio dever remover o elemento meta antes do mesmo ser enviado ao cliente; seno (true), os dados so enviados ao browser do usurio Contedo do metadata, como por exemplo, um tipo Estrutura que dever ser utilizada para interpretar o metadata
Nome id class
<onevent>
Obrigatrio No No
Padro
Obrigatrio No No Sim
Padro
A tag <optgroup> utilizada para agrupar elementos criados com a tag <option> , definindo assim uma hierarquia.
Obrigatrio No No No No
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Referncia do grupo
<optgroup title=estado> <option title=So Paulo value=SP> <option title=Rio de Janeiro value=RJ> <option title=Bahia value=BA> .... </optgroup>
<option> A tag <option> cria uma opo de escolha em um elemento selecionado. Atributos
Obrigatrio No No No No No No
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Valor atribudo opo Expresso apresentada ao usurio Dispara a chamada de uma URL, quando a opo for selecionada
<optgroup title=sexo> <option title=Masculino value=M> <option title=Feminino value=F> .... </optgroup> <optgroup title=idioma> <option title=Portugus value=P onpick=/port.wml> <option title=Ingls value=I onpick=/ingles.wml> .... </optgroup>
<p> A tag <p> inicia um pargrafo com os atributos especificados. Atributos
Obrigatrio No No No No No
Padro
left wrap
mode
Exemplos:
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Alinhamento do pargrafo left = esquerda right = direita center = centralizado Especifica o modo de parada do texto
<p align=left> Estou alinhado a esquerda </p> <p align=right> Estou alinhado a direita </p> <p align=left> Estou alinhado a esquerda </p>
<p align=center wrap=nowrap> Este texto dever ser visto sem rolagem e centralizado </p>
<postfield> A tag <postfield> define o nome de um campo e valor para transmisso a um servidor de origem, durante uma requisio de URL. Atributos
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Nome do campo Valor do campo
Nome id class
Sintaxe
Obrigatrio No No
Padro
<prev>
<refresh> A tag <refresh> atualiza a URL em atividade e o contexto do dispositivo, de acordo com os dados atuais do servidor.
Nome Id class
Sintaxe
Obrigatrio No No
Padro
<refresh>
<select> A tag <select> inicia uma lista de seleo. Os itens da lista so criados atravs da tag <option>. Atributos
Nome id class xml:lang title name value iname ivalue multiple tabindex
Descritivo dos Atributos
Tipo String String String String String String String String Boolean Number
Obrigatrio No No No No Sim No No No No No
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Define o ttulo a ser exibido ao usurio Nome do elemento (campo) Recebe o nome da opo selecionada; o nome definido no atributo iname, e o valor no ivalue Declarao do nome do elemento Valor da opo selecionada na lista de opes
<select name=linguagens iname=L ivalue=1;2;3;4 multiple=true> <option value=A>Delphi</option> <option value=B>Java</option> <option value=A>C++</option> <option value=A>.Net</option> </select>
<setvar>
Aplicaes para Celulares 177 A tag <setvar> utilizada para definir o valor de uma varivel. Atributos
Padro
Obrigatrio No No No
Padro
Obrigatrio No No No
Padro
Obrigatrio No No No No No Sim
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Define o ttulo da tabela Alinhamento dos elementos da tabela Nmero de colunas
<table align=center columns=3> <tr> <td>marca</td> <td>ano</td> <td>modelo</td> </tr> <tr> <td>fiat</td> <td>2002</td> <td>palio elx</td> </tr> <tr> <td>mercedes</td> <td>2001</td> <td>E500</td> </tr>
<tr> <td>honda</td> <td>1999</td> <td>civic</td> </tr> <tr> <td>GM</td> <td>1998</td> <td>blazer</td> </tr> </table>
Resultado do exemplo marca fiat mercedes honda gm <template> A tag <template> define caractersticas comuns a todos os cards do dispositivo, disparando alguns eventos. Atributos ano 2002 2001 1999 1998 modelo palio elx e500 civic blazer
Obrigatrio No No No No No
Padro
Descrio Identificao do elemento (nome nico) Classe a que o elemento pertence Define a URL a ser disparada, caso o usurio acesse um carto atravs da tag <do> Define a URL a ser disparada, caso o usurio acesse um carto atravs da tag <prev> Define a URL a ser disparada, caso o tempo definido na tag <timer> expire
ontimer=/login.wml> </template>
<timer> A tag <timer> utilizada para disparar um evento ou chamada a partir de um determinado tempo, especificado na propriedade value (100 = 1 segundo). Atributos
Obrigatrio No No Sim
Padro
<card name=card1 ontimer=#card2> <timer value=100/> <p>Esta mensagem ser destruda em 10 segundos</p> </card> <card name=card2> <p>Mensagem Destruda</p> </card>
Acentos em WML
Nome ¡ ¢ £ ¤ ¥ ¦ § ¨ © ¬ ® ° ± ´ ¼ ½ ¾ ¿ À Á Â Cdigo   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ¬ ® ° ± ´ ¼ ½ ¾ ¿ À Á Â Resultado espao
Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ñ ò
Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ñ ò
ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
Figura 10.3 Opo Web Server Application Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 10.4).
Figura 10.4 Seleo do tipo da aplicao Em seguida teremos o nosso WebModule (figura 10.5),
Figura 10.5 WebModule Bem, seguindo o nosso primeiro projeto, atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 10.6).
Figura 10.6 editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 10.7).
OBJETO TWebActionItem Objeto padrao Propriedade Default Name PathInfo Valor True padrao /padrao
Esta ser nossa Action padro, ou seja, caso o usurio no digite nada, alm do nome da nossa aplicao, esta Action ser executada. Embora a propriedade PathInfo possua o mesmo valor da propriedade Name, ela que executa a Action, ou seja, no browser o que vale o valor da PathInfo. No evento OnAction coloque o seguinte cdigo: 001 002 003 004 Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Ola Mundo!</p></card></wml>';
No se assustem com as denominaes do cabealho <DOCTYPE wml...., isso um padro, e o restante iremos conhecendo aos poucos. Vamos analisar o cdigo: Na linha 001, estou dizendo ao servidor, atravs do mtodo Response.ContentType, que o tipo de informao no padro WAP. Response.ContentType:='text/vnd.wap.wml'; Em, seguida, nas linhas 002,003 e 004, estou empacotando a resposta (Response.Content) e enviando ao servidor, que por sua vez, envia ao celular. Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Ola Mundo!</p></card></wml>'; Grave a unit do nosso projeto como un_ola.pas e o projeto como ola.dpr. Habitualmente testamos nossas aplicaes servidoras num browser, como o Internet Explorer, mas neste caso iremos test-la no nosso simulador Deck-It. Lembram dele?
Aplicaes para Celulares 185 No Deck-It digite o que segue na barra de endereos: http://localhost/cgi-bin/ola.exe A figura 10.8 ilustra o resultado da nossa aplicao:
Figura 10.8 Resultado da aplicao S para ter uma idia, voc poderia simular em seu prprio celular WAP este exemplo. Mas Facunte, como eu faria isso? Conecte seu computador Internet, anote o nmero do IP fornecido no momento da conexo, exemplo: 200.198.12.1, e digite no seu celular (o modo de entrada para comunicao WAP varia de celular para celular, consulte o manual de instrues), o endereo: http://200.198.12.1/cgi-bin/ola.exe Repare que o nmero, na realidade o seu endereo de IP atual (exemplo). Continuando com a nossa aplicao, vamos criar mais uma Action com as seguintes propriedades:
OBJETO TWebActionItem Objeto Theclub Propriedade Default Name PathInfo Valor False theclub /theclub
No evento OnAction coloque o seguinte cdigo: 001 002 003 004 Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Sejam bem-vindos ao The Club</p></card></wml>';
O cdigo exatamente igual ao anterior, em que apenas substituimos a mensagem. Vamos testar o cdigo? No Deck-It digite o que segue na barra de endereos: http://localhost/ola.exe/theclub Repare que estamos colocando o pathinfo theclub. A figura 10.9 ilustra o resultado da nossa segunda Action.
Figura 10.9 Segunda Action interessante, no acham? E a, amigos, esto preparados para brincar com banco de dados e WAP?
Listagem 10.1
unit un_ola; interface uses SysUtils, Classes, HTTPApp; type TWebModule1 = class(TWebModule) procedure WebModule1padraoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); procedure WebModule1theclubAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation
Aplicaes para Celulares 187 {$R *.DFM} procedure TWebModule1.WebModule1padraoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Ola Mundo !</p></card></wml>'; end; procedure TWebModule1.WebModule1theclubAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>Sejam bem-vindos ao THE CLUB</p></card></wml>'; end; end.
188 Delphi 7 Internet e Banco de Dados Em seguida, selecione o tipo de aplicao CGI, e marque a opo Cross Platform (figura 10.11). Perceba que com isso poderemos executar a mesma aplicao num servidor Linux, sendo que o cdigo dever ser recompilado em Kylix.
Figura 10.11 Escolha do tipo da aplicao servidora Agora, neste ponto, precisamos estabelecer a conexo com o nosso banco de dados. Insira um objeto do tipo TSQLConnection, e atravs do duplo-clique, j na tela de configurao, crie uma nova conexo do tipo Interbase, alterando as propriedades que seguem. A figura 10.12 ilustra o dilogo de propriedades do componente TSQLConnection.
PROPRIEDADE
VALOR
Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.
Figura 10.12 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades:
PROPRIEDADE
VALOR
Oba, j estamos chegando l. Agora vamos inserir um objeto do tipo TdataSetTableProducer. No confundam com TdataSetPageProducer. Altere o nome do componente para producerCliente, e a propriedade DataSet para SQLCliente. Atravs de um duplo-clique teremos a seguinte tela (assistente de configurao figura 10.13).
190 Delphi 7 Internet e Banco de Dados Caso no esteja vendo uma tela parecida (perceba que os dados j esto inseridos no banco e que voc dever inserir seus prprios registros), verifique se est tudo certo com a sua conexo. Deixe somente o campo e-mail, pois iremos listar apenas esta informao em nosso celular. Para realizar a tarefa, selecione os outros campos e aperte a tecla delete. Veja o resultado desta operao, na figura 10.14.
Figura 10.14 Neste ponto, iremos criar nossa Action para apresentar a informao no celular. Crie uma Action com o nome dados, atravs do duplo-clique no WebModule. Veja a figura 10.15.
Figura 10.15 Action dados No evento OnClick da Action dados, insira o cdigo que segue. // Abre o SQLCliente SQLCliente.Open; // Define o tipo do contedo Response.ContentType:='text/vnd.wap.wml'; // Monta a cabealho padro
Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>'; // Insere o conteudo da nossa Tabela producer_Cliente na resposta e finaliza Response.Content:=Response.Content+producerCliente.Content+ '</p></card></wml>'; // Fecha o SQLCliente SQLCLiente.Close;
Com base no exemplo anterior, fica bastante simples entender este cdigo. Primeiro, estamos abrindo o nosso DataSet (SQLCliente). SQLCliente.Open; Em seguida estamos atribuindo resposta, o tipo de empacotamento WML. Response.ContentType:='text/vnd.wap.wml'; Na prxima instruo, estamos fazendo as definies iniciais, como cabealho <?xml...>, card <card>, e incio de um pargrafo <P>. Isso imprescindvel. Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>'; Agora vem a parte interessante. Estamos adicionando ao pacote de resposta (Response.Content), a informao obtida atravs do componente producer_Cliente, e finalizando o pargrafo<P>, o Card</card> e o documento WML </wml>. Response.Content:=Response.Content+producerCliente.Content+ '</p></card></wml>'; Amigos, agora s compilar e testar no Deck-It. http://localhost/cgi-bin/wap_bd.exe/dados Vejam o resultado (figura 10.16).
Listagem 10.2
unit un_wap_bd; interface uses SysUtils, Classes, HTTPApp, DBXpress, FMTBcd, DB, SqlExpr, DBWeb; type TWebModule1 = class(TWebModule) ConexaoBD: TSQLConnection; SQLCliente: TSQLDataSet; producer_Cliente: TDataSetTableProducer; procedure WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModule1: TWebModule1; implementation {$R *.xfm} procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin // Abre o SQLCliente SQLCliente.Open; // Define o tipo do contedo Response.ContentType:='text/vnd.wap.wml'; // Monta a cabealho padro
Response.Content:='<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM" "http://www.wapforum.org/DTD/wml_1.1.xml">'+ '<wml><card id="cartaum"><p>'; // Insere o conteudo da nossa Tabela producer_Cliente na resposta e finaliza Response.Content:=Response.Content+producer_Cliente.Content+ '</p></card></wml>'; // Fecha o SQLCliente SQLCLiente.Close; end; end.
Figura 10.17 Item Web Server Application Em seguida, selecione o tipo de aplicao CGI, e marque a opo Cross Platform (figura 10.18).
Figura 10.18 Escolha do tipo da aplicao servidora Agora, neste ponto, precisamos estabelecer a conexo com o nosso banco de dados. Insira um objeto do tipo TSQLConnection, e atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo.
PROPRIEDADE
VALOR
Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.
Figura 10.18 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades:
PROPRIEDADE
VALOR
SQLConnection CommandText
Repare que estamos colocando dois parmetros, (pRAZAO e pEMAIL), que devero ser configurados atravs da propriedade PARAMS (figura 10.20).
196 Delphi 7 Internet e Banco de Dados Atravs do duplo-clique na propriedade Params, acessamos o editor de parmetros (figura 10.21). Configure os dois parmetros para o tipo ftString, atravs da propriedade DataType.
Figura 10.21 Configurao dos Parmetros Ok amigos, agora vamos continuar nossa aplicao inserindo um componente do tipo TPageProducer e alterar as seguintes propriedades:
PROPRIEDADE
VALOR
Name HTMLDoc
Insira este cdigo na propriedade HTMLDoc do objeto ppInclusao. <wml> <card id="inclusao"> <p align="center"> Inclusao Clientes <br/> <br/> </p> <p> Razao Social: <input type="text" name="razao"/> <br/> eMail : <input type="text" name="email"/> <do type="accept" label="CONFIRMA"> <go href="confirma" method="post"> <postfield name="razao" value="$razao"/> <postfield name="email" value="$email"/> </go> </do> </p> </card> </wml> Agora vamos criar uma varivel em nosso WebModule para facilitar nas respostas ao cliente, em nosso caso, o celular. Antes da seo implementation, crie a nossa varivel cabealho, como segue: var WebModule1: TWebModule1; cabecalho:string = '<?xml version="1.0"?>'+ '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EM"
Aplicaes para Celulares 197 "http://www.wapforum.org/DTD/wml_1.1.xml">'; implementation Neste ponto, iremos criar nossas Actions (figura10.22).
Figura 10.22 Actions Teremos uma Action para apresentar a tela de incluso, e outra para confirmar. Primeiro vamos criar a Action inclusao.(sem acento mesmo). No evento OnAction, insira o cdigo que segue: Response.ContentType:='text/vnd.wap.wml'; Response.Content:=cabecalho+ppInclusao.Content; Neste cdigo, estamos informando o tipo de pacote e utilizando nossa varivel auxiliar cabealho para compor a nossa resposta, alm, claro, do contedo do Producer ppInclusao. Bem simples, no? Em seguida, precisamos criar a nossa Action confirma. No evento OnAction, insira o cdigo que segue: try SQLInsere.ParamByName('pRazao').Value:=Request.ContentFields.Values['razao']; SQLInsere.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInsere.ExecSQL(); Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Registro Incluido</p></card></wml>'; except Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Erro na Incluso</p></card></wml>'; end; Neste cdigo estamos atribuindo aos parmetros de nossa Query SQLInsere, o contedo informado pelo usurio, e transmitido atravs do mtodo POST. O cdigo est protegido atravs dos comandos try/except e, em caso de sucesso, apresentamos ao usurio a mensagem Registro Includo. Caso contrrio, apresentamos a mensagem Erro na Incluso. As figuras 10.23, 10.24, 10.25 e 10.26 ilustram nossa aplicao em ao. Para chamar a aplicao, utilize: http://localhost/cgi-bin/wap_inc.exe/dados
Figura 10.26 Registro includo com sucesso Amigos, com um pouquinho de esforo, d para criar uma aplicao bem completa para celulares. Digo esforo pois existem vrios limites nos aparelhos, como tamanho de tela, capacidade de dados, entre outras coisas, que nos fazem voltar ao tempo da magia e dedicao, onde fazamos malabarismos com o Clipper, o C e o Turbo Pascal para oferecer telas agradveis aos nossos usurios. Encerramos por aqui este tpico, e espero que tenham gostado.
200 Delphi 7 Internet e Banco de Dados implementation {$R *.xfm} procedure TWebModule1.WebModule1inclusaoAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType:='text/vnd.wap.wml'; Response.Content:=cabecalho+ppInclusao.Content; end; procedure TWebModule1.WebModule1confirmaAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin try SQLInsere.ParamByName('pRazao').Value:=Request.ContentFields.Values['razao']; SQLInsere.ParamByName('pemail').Value:=Request.ContentFields.Values['email']; SQLInsere.ExecSQL(); Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Registro Incluido</p></card></wml>'; except Response.ContentType:='text/vnd.wap.wml'; Response.Content:='<wml><card id="ok"><p>Erro na Incluso</p></card></wml>'; end;
end; end.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 11
WebSnap
O WebSnap, presente desde a verso 6 do Delphi, e a verso 2 do Kylix, tem como proposta e objetivo principal o desenvolvimento de aplicaes para Internet com o conceito RAD (Rapid Application Development), ou desenvolvimento rpido de aplicaes. Na realidade no foi incorporada para substituir o WebBroker, e sim complementar e estender suas funcionalidades. Uma das coisas mais interessantes nesta tecnologia a possibilidade de utilizar inmeros formulrios para uma mesma aplicao. Em WebBroker no era possvel, pelo menos no de maneira organizada e documentada. Na tecnologia WebBroker as equipes de desenvolvimento precisavam criar projetos diferentes para produzir de maneira adequada. Com o WebSnap essa barreira foi quebrada, permitindo compartilhar diversas units entre as equipes. A tecnologia WebSnap tambm permitiu o desenvolvimento de outros frameworks bastante produtivos e que esto fazendo o maior sucesso entre os desenvolvedores. Prova disso foi a incorporao de um desses frameworks nesta verso do Delphi: o Intraweb, que veremos no prximo captulo.
Algumas curiosidades
O modelo de desenvolvimento Web no Delphi vem crescendo a cada verso, provando a forte tendncia deste modelo. Grandes empresas esto partindo para este modelo de desenvolvimento, justamente pela portabilidade, economia e praticidade. Sinceramente, sugiro que todos explorem o mximo este modelo de desenvolvimento, pois o mercado est indo para este lado.
Conhecendo os componentes
Embora a melhor maneira de conhecer os componentes do WebSnap seja praticando alguns exemplos, darei um breve descritivo de cada um deles.
202
Figura 11.1 Componentes WebSnap Componente Descrio Fornece uma interface de scripts e execuo de comandos TAdapter Fornece uma camada lgica para diviso de pginas de dados. Tecnologia comumente encontrada em sites de busca. Fornece solues de controles e comandos para DataSets. Adiciona funes semelhantes aos Adapters, relacionando com os DataSets. Utilizado para criar formulrios de Login. TLoginFormAdapter Fornece aos Adapters uma lista de nomes e valores. Exemplo: Nome e Senha, Cdigo e Razo Social, e assim por diante Semelhante ao TStringValuesList, mas vinculado a um DataSet. TDataSetValuesList Principal componente da tecnologia WebSnap. Fornece toda a interface para o desenvolvimento de aplicaes WebSnap. Fornece interface de scripts relacionados informao da aplicao. TApplicationAdapter Controle de informao sobre o usurio, como Nome, ID, sesso. TEndUserAdapter Controle completo sobre a informao de sesso do usurio. Normalmente utilizado com TSessionsService e TendUserAdapter.
TPagedAdapter
TDataSetAdapter
TStringsValuesList
TWebAppComponents
TEndUserSessionAdapter
204 Delphi 7 Internet e Banco de Dados Componente Descrio Responsvel pela interface de request HTTP de aplicaes WebSnap. necessrio apenas um por aplicao. Fornece interface de tratamento de submisses de formulrios HTML e imagens. necessrio para que a aplicao trabalhe com os adapter actions, alm de imagens provenientes de adapter fields. Fornece controle sobre arquivos de template e arquivos script-server-side. Facilita a manipulao destes arquivos.
TPageDispatcher
TAdapterDispatcher
TLocateFileService
TSessionService
Armazena informaes de sesses temporariamente. Possui TimeOut, nmero mximo de sesses, entre outras funcionalidades. Controla uma lista predefinida de usurios, fazendo validao de login e controle de acesso. Faz um parse em documentos XML, baseados no template XSL. Muito utilizado na tecnologia Web, cria um documento HTML com diversas funcionalidades e controles.
TWebUserList
TXSLPageProducer
TAdapterPageProducer
C:\CursoWeb WebSnap
WebSnap 205
Primeiro Exemplo
Neste primeiro exemplo, faremos uma simples demonstrao da tecnologia WebSnap. O mais importante neste tpico compreender toda a estrutura da tecnologia. Todos os passos sero analisados para que voc compreenda de maneira satisfatria cada detalhe. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.2).
Figura 11.2 Selecionando o modelo da aplicao Em seguida teremos uma janela assistente (figura 11.3) com diversas opes de configurao da aplicao.
206 Delphi 7 Internet e Banco de Dados Vamos analisar as opes: Tipo do servidor Primeiro, devemos escolher o tipo do servidor (CGI, ISAPI, Apache ou Web App Debugger). Escolha a opo Web App Debugger e informe o nome da classe (necessrio apenas para esta opo). Para este exemplo vamos nomear como classExemplo1. O Web App Debugger na realidade um servidor HTTP que oferece um timo nvel de depurao para a nossa aplicao. Escolhendo esta opo gerado um modelo de servidor COM, para interagir com o Web App Debugger. Esta opo utilizada nica e exclusivamente para o desenvolvimento e nunca para a distribuio. Componentes da Aplicao Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.4) com opes de servio.
Figura 11.4 Opes de servio Nesta caixa de dilogo escolhemos os servios bsicos de nossa aplicao. Na realidade cada servio poder ser adicionado sua aplicao conforme a necessidade. Para este primeiro exemplo, mantenha as opes padro e clique no boto OK. Opes da Aplicao Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.5) com opes da aplicao.
WebSnap 207
Figura 11.5 Opes da aplicao Aqui temos um nvel bastante interessante de configurao. Na primeira seo, temos a configurao do nosso Producer, com os seguintes tipos: AdapterPageProducer DataSetPageProducer InetXPageProducer PageProducer XLSPageProducer Selecione a opo PageProducer. Dependendo do tipo selecionado, temos as seguintes opes para o script engine: JScript VBScript Mantenha a seleo em JScript. Em seguida temos a seo HTML. Esta seo permite ao desenvolvedor criar uma pgina automaticamente, seja a partir de um modelo (Standard) ou em branco (Blank). Selecione a opo Standard e deixe marcada a opo New File. E, por fim, temos as informaes da nossa pgina HTML. Name Title Published Login Required Mantenha as opes padro e pressione o boto OK. Retornando caixa de dilogo inicial, pressione OK para concluir o assistente e gerar nossa primeira aplicao. A figura 11.6 ilustra o PageModule criado. Utilizado como referncia para requisies HTTP e lgica da sua aplicao. Ttulo que ser apresentado na janela do browser. habilita o recurso de resposta as requisies HTTP. Verifica se existe a necessidade do usurio fazer Login para entrar nesta pgina.
Figura 11.6 Page Module Agora vamos gravar nosso primeiro projeto no diretrio \WebSnap\Exercicio1, como segue. Unit PageModule Unit Formulrio Projeto un_ex1.PAS un_form.PAS wsnap1.DPR
Aps a gravao do nosso projeto, repare que foi gerado automaticamente um arquivo un_ex1.HTML, com o seguinte contedo. <html> <head> <title> <%= Page.Title %> </title> </head> <body> <h1><%= Application.Title %></h1> <% if (EndUser.Logout != null) { %> <% if (EndUser.DisplayName != '') { %> <h1>Welcome <%=EndUser.DisplayName %></h1> <% } %> <% if (EndUser.Logout.Enabled) { %> <a href="<%=EndUser.Logout.AsHREF%>">Logout</a> <% } %> <% if (EndUser.LoginForm.Enabled) { %> <a href=<%=EndUser.LoginForm.AsHREF%>>Login</a> <% } %> <% } %> <h2><%= Page.Title %></h2> <table cellspacing="0" cellpadding="0"> <td>
WebSnap 209 <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += ' | ' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++ } } if (c>1) Response.Write(s)
</body> </html> Podemos visualizar o documento atravs das Tabs do nosso editor de cdigo (figura 11.7).
Figura 11.7 Tabs do editor de cdigo Antes de executar nossa primeira aplicao, insira uma frase qualquer no corpo do documento un_ex1.HTML, como segue. Nossa primeira aplicao </body> </html> Grave o documento para que possamos executar a aplicao. Execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Perceba que o formulrio em branco, apresentado na tela. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. A figura 11.8 ilustra o WebAppDebugger em execuo. Clique no boto Start para iniciar o servidor e, em seguida, no link Default URL.
Figura 11.8 Web App Debugger Ao clicar no link Default, ser apresentado um documento HTML (figura 11.9) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.
Figura 11.9 Servios registrados A figura 11.10 ilustra o resultado da nossa primeira aplicao WebSnap.
Figura 11.10 Primeira aplicao WebSnap Com isso conclumos nossa primeira aplicao.
WebSnap 211
uses WebReq, WebCntxt, WebFact, Variants; function index: Tindex; begin Result := Tindex(WebContext.FindModuleClass(Tindex)); end; initialization if WebRequestHandler <> nil then WebRequestHandler.AddWebModuleFactory(TWebAppPageModuleFactory.Create(Tindex, TWebPageInfo.Create([wpPublished {, wpLoginRequired}], '.html'), caCache) ); end.
Segundo Exemplo
No segundo exemplo vamos conhecer os conceitos de Server Scripts e dos Adapters. Os Server Scripts nos auxiliam em diversas tarefas, seja para acessar valores em objetos criados atravs do Delphi, ou at mesmo rotinas dinmicas geradas no servidor. A grande vantagem de utilizar Server Scripts justamente a facilidade da manuteno do projeto, onde muitas vezes, apenas o arquivo HTML sofre mudanas. Com isso no h necessidade de uma nova compilao.
212 Delphi 7 Internet e Banco de Dados J os Adapters, como voc ir perceber ao longo deste captulo, sero nossos grandes aliados. Na realidade os Adapters fornecem uma interface de scripts para a sua aplicao servidora. Vamos aprender na prtica esses conceitos. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.11).
Figura 11.11 Selecionando o modelo da aplicao Em seguida (figura 11.12) selecione a opo Web App Debugger, e informe o nome da classe (necessrio apenas para esta opo). Para este exemplo vamos nomear como classExemplo2.
WebSnap 213 Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.13) com opes de servio.
Figura 11.13 Opes de servio Assim como no primeiro exemplo, mantenha as opes padro e clique no boto OK. Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.14) com opes da aplicao.
Figura 11.14 Opes da aplicao Selecione Page Producer para o Producer Type e mantenha a seleo JScript. no Script Engine. Em seguida temos a seo HTML. Selecione a opo Standard e deixe marcada a opo New File. Retornando caixa de dilogo inicial, pressione OK para concluir o assistente e gerar nossa segunda aplicao. A figura 11.15 ilustra o PageModule criado.
Figura 11.15 Page Module Agora vamos gravar nosso segundo projeto no diretrio \WebSnap\Exercicio2, como segue. Unit PageModule Unit Formulrio Projeto un_ex2.PAS un_form.PAS wsnap2.DPR
Agora vamos inserir um objeto do tipo TAdapter e, em seguida, acessar a propriedade Data deste objeto, clicando no boto relacionado (figura 11.16).
Figura 11.16 Propriedade Data Em seguida temos o editor de campos para o objeto Adapter (figura 11.17).
WebSnap 215
Figura 11.17 Editor de campos Clique com o boto direito do mouse sob o editor e selecione a opo New Component ou clique no primeiro boto, como ilustra a figura 11.17. Em seguida teremos uma lista com os possveis componentes do nosso objeto Adapter1.
Figura 11.18 Componentes do Adapter Selecione o componente AdapterField e clique no boto OK. Modifique a propriedade Name do componente criado para MeuFieldAdapter. A figura 11.19 ilustra os eventos do nosso objeto MeuFieldAdapter.
216 Delphi 7 Internet e Banco de Dados Prosseguindo com nosso exemplo, vamos atribuir um valor dinmico ao nosso objeto MeuFieldAdapter. No evento OnGetValue insira o cdigo que segue: procedure Tindex.MeuFieldAdapterGetValue(Sender: TObject; var Value: Variant); begin Value:=TimetoStr(Time); end; Agora vamos acessar o valor do nosso objeto, no arquivo index.HTML criado pelo assistente. Insira o comando que segue, na seo <BODY> do documento. <B><%Response.Write(Adapter1.MeuFieldAdapter.value)%></B> Grave o nosso projeto e execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. Clique no boto Start para iniciar o servidor, e em seguida no link Default URL. Ao clicar no link Default ser apresentado um documento HTML (figura 11.20) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.
Figura 11.20 Servios registrados Amigos, obviamente o exemplo bastante simples, mas imaginem que atravs dos objetos Adapters poderemos acessar valores de clculos, resultados de instrues SQL, imagens dinmicas, entre outras funcionalidades.
WebSnap 217 MeuFieldAdapter: TAdapterField; procedure MeuFieldAdapterGetValue(Sender: TObject; var Value: Variant); private { Private declarations } public { Public declarations } end; function index: Tindex; implementation {$R *.dfm} {*.html}
uses WebReq, WebCntxt, WebFact, Variants; function index: Tindex; begin Result := Tindex(WebContext.FindModuleClass(Tindex)); end; procedure Tindex.MeuFieldAdapterGetValue(Sender: TObject; var Value: Variant); begin Value:=TimetoStr(Time); end; initialization if WebRequestHandler <> nil then WebRequestHandler.AddWebModuleFactory(TWebAppPageModuleFactory.Create(Tindex, TWebPageInfo.Create([wpPublished {, wpLoginRequired}], '.html'), caCache) ); end.
<h2><%= Page.Title %></h2> <table cellspacing="0" cellpadding="0"> <td> <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += ' | ' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++ } } if (c>1) Response.Write(s) %> </td> </table> <B><% Response.Write(Adapter1.MeuFieldAdapter.value) %></B> </body> </html>
Terceiro Exemplo
No terceiro exemplo vamos trabalhar com mltiplos Page Modules, alm de dispensar o assistente para criao automtica de pginas. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.21).
WebSnap 219 Em seguida, (figura 11.22) selecione a opo Web App Debugger e informe o nome da classe. Para este exemplo vamos nomear como classExemplo3.
Figura 11.22 Opes da aplicao WebSnap Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.23) com opes de servio.
Figura 11.23 Opes de servio Assim como nos exemplos anteriores, mantenha as opes padro e clique no boto OK.
220 Delphi 7 Internet e Banco de Dados Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.24) com opes da aplicao. Selecione Page Producer para o Producer Type e mantenha a seleo JScript. no Script Engine. Em seguida temos a seo HTML. Desmarque a opo New File e clique no boto OK.
Figura 11.24 Opes da aplicao Agora vamos gravar nosso terceiro projeto no diretrio \WebSnap\Exercicio3, como segue. Unit PageModule Unit Formulrio Projeto un_ex3.PAS un_form.PAS wsnap3.DPR
Como dispensamos a criao automtica do arquivo HTML, vamos utilizar os novos assistentes do Delphi, para cri-lo. Atravs das opes File/New/Other..., acesse a seo Web Documents como ilustra a figura 11.25 e selecione a opo HTML.
WebSnap 221 Veja que o seguinte documento foi criado. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Untitled1.html </TITLE> </HEAD> <BODY>
</BODY> </HTML> No editor do Delphi, perceba que existe um assistente code completation para HTML (figura 11.26).
Figura 11.26 Code completation HTML Faa as modificaes (em negrito) como segue: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> Pgina Principal </TITLE> </HEAD> <BODY> <% e = new Enumerator(Pages) s = '' c = 0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c>0) s += ' | ' if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title c++
222 Delphi 7 Internet e Banco de Dados } } if (c>1) Response.Write(s) %> </BODY> </HTML> Vamos analisar o cdigo script, normalmente utilizado pelo padro Standard do Page Module: No primeiro bloco, estamos criando um objeto do tipo Enumerator e iniciando as variveis s e c. A varivel s ser a nossa string para montagem dos links que sero apresentados e a varivel c uma auxiliar para contagem de nmeros de pginas da aplicao. <% e = new Enumerator(Pages) s = '' c = 0
No bloco seguinte estamos iniciando um lao baseado no objeto e criado anteriormente e movendo uma posio no objeto a cada ciclo. Perceba que o objeto e cria uma matriz de Page Modules da aplicao. for (; !e.atEnd(); e.moveNext()) No bloco que segue, estamos verificando se o item atual (Page Module) do objeto e possui o mtodo de publicao. if (e.item().Published) Em caso afirmativo, acrescenta-se varivel s, espao | espao, onde igual a espao na linguagem HTML. if (c>0) s += ' | ' Seguindo com o nosso script, este prximo bloco verifica se o item em questo diferente do que solicita o script, ou seja, verifica se diferente dele mesmo. Em caso afirmativo cria o link da pgina baseado no item atual, seno apenas apresenta o ttulo da pgina. if (Page.Name != e.item().Name) s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>' else s += e.item().Title Em seguida apenas incrementamos a varivel c. c++ E por fim, escrevemos no HTML todo o contedo da varivel s caso a varivel c seja maior que 1, isto , apenas se nossa aplicao contiver 2 ou mais PageModules. if (c>1) Response.Write(s) %> Agora vamos adicionar Page Modules ao nosso projeto. Atravs das opes File/New..Other..., seo WebSnap, selecione o assistente WebSnap PageModule (figura 11.27).
WebSnap 223
Figura 11.27 Novo PageModule Em seguida, configure as opes como ilustra a figura 11.28.
Figura 11.28 Configurao Page Module Grave a unit como un_ex3_pag2.pas. Insira o cdigo que segue no HTML associado a unit un_ex3_pag2, em nosso caso un_ex3_pag2.HTML. <B> Estamos na Pgina 2 </B>
224 Delphi 7 Internet e Banco de Dados Grave o nosso projeto e execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. Clique no boto Start para iniciar o servidor, e em seguida no link Default URL. Ao clicar no link Default ser apresentado um documento HTML (figura 11.29) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.
Figura 11.29 Aplicaes registradas As figuras 11.30 e 11.31 ilustram o resultado de nossa aplicao.
WebSnap 225
Quarto Exemplo
No quarto exemplo vamos trabalhar com a interatividade do usurio. Atravs das opes File/New/Other..., selecione a seo WebSnap e escolha a opes WebSnap Application (figura 11.32).
226 Delphi 7 Internet e Banco de Dados Em seguida (figura 11.33) selecione a opo Web App Debugger e informe o nome da classe. Para este exemplo vamos nomear como classExemplo4.
Figura 11.33 Opes da aplicao WebSnap Em seguida temos a seo Application Module Components, responsvel pela configurao dos mdulos da aplicao. Clicando no boto Components, voc ter acesso outra caixa de dilogo (figura 11.34) com opes de servio.
Figura 11.34 Opes de servio Assim como nos exemplos anteriores, mantenha as opes padro, e clique no boto OK.
WebSnap 227 Em seguida temos a seo Application Module Options, responsvel pela configurao das opes da aplicao. Clicando no boto Page Options, voc ter acesso caixa de dilogo (figura 11.35) com opes da aplicao. Selecione Page Producer para o Producer Type e mantenha a seleo JScript. no Script Engine. Em seguida temos a seo HTML. Desmarque a opo New File e clique no boto OK.
Figura 11.35 Opes da aplicao Agora vamos gravar nosso quarto projeto no diretrio \WebSnap\Exercicio4, como segue. Unit PageModule Unit Formulrio Projeto un_ex4.PAS un_form.PAS wsnap4.DPR
Agora vamos criar um novo Web Page Module atravs das opes File/New...Other... e na seo WebSnap, selecione WebSnap Page Module. Configure de acordo com a figura 11.36.
228 Delphi 7 Internet e Banco de Dados Pressione OK, e grave a unit como un_formulario.ps. Repare que selecionamos AdapterPageProducer, ao invs do tradicional Page Producer. Vamos criar trs variveis na seo private, com o objetivo de executar um clculo futuro. private v1:single; v2:single; vResultado:single; Agora insira um objeto do tipo TAdapter para que possamos trabalhar com objetos Fields. Inclua um Adapter Field, atravs da propriedade Data do objeto Adapter1, como ilustra a figura 11.37.
Figura 11.37 Adapter Field Altere a propriedade Name para Valor1 e insira o cdigo que segue no evento OnGetValue: procedure Tformulario.Valor1GetValue(Sender: TObject; var Value: Variant); begin Value:=v1; end; Agora vamos criar outro AdapterField com o nome Valor2 e insira o seguinte cdigo no evento OnGetValue: procedure Tformulario.Valor2GetValue(Sender: TObject; var Value: Variant); begin Value:=v2; end; Agora vamos incluir um AdapterField para exibir o resultado da operao, com o nome Resultado. Insira o cdigo que segue no evento OnGetValue: Value:= vResultado; Antes de definir o layout da aplicao vamos definir a ao que ir alimentar nossas variveis. Selecione o objeto Adapter1 e atravs da propriedade Actions (figura 11.38) crie uma nova Action para o nosso objeto. Altere o nome da Action para calcula.
WebSnap 229
Figura 11.38 Actions No evento OnExecute da Action calcula, insira o cdigo a seguir. procedure Tformulario.calculaExecute(Sender: TObject; Params: TStrings); begin v1:= Valor1.ActionValue.Values[0]; v2:= Valor2.ActionValue.Values[0]; vResultado:=v1+v2; end; O cdigo bastante simples, onde estamos atribuindo s variveis v1,v2 e vResultado, os valores resgatados atravs de um formulrio HTML que iremos criar. Na realidade, a varivel vResultado est sendo alimentada com o resultado da operao (v1+v2). Agora vamos criar o formulrio HTML utilizando o nosso AdapterPageProducer. Atravs do duplo-clique AdapterPageProducer1, adicione um novo componente do tipo AdapterForm no objeto
Figura 11.39 Web Component Agora clique no AdapterForm1 e insira um objeto do tipo AdapterFieldGroup. Devemos vincular o AdapterFieldGroup ao objeto Adapter1, atravs da propriedade Adapter. A figura 11.40 ilustra nosso formulrio aps o vnculo.
Figura 11.40 Formulrio criado atravs do Adapter Em nosso caso desejamos configurar manualmente as propriedades de cada campo. Para realizar tal operao, devemos adicionar os Fields, clicando com o boto direito do mouse em AdapterFieldsGroup e selecionar a opo Add All Fields. A figura 11.41 ilustra nossa operao.
Figura 11.41 Fields Altere as propriedades dos objetos criados como segue: Objeto FldValor1 Valor Informe o primeiro valor Objeto FldValor2 Valor Informe o segundo valor
Propriedade Caption
Propriedade Caption
WebSnap 231 Agora vamos inserir o boto com a nossa ao. Selecione o AdapterForm1 e insira um novo componente do tipo AdapterCommandGroup. No objeto criado, faa o vnculo da propriedade DisplayComponent com o objeto AdapterFieldGroup1. Na realidade estamos colocando o nosso boto dentro do AdapterFieldGroup1. A figura 11.42 ilustra nosso formulrio atual.
Figura 11.42 Formulrio Agora vamos inserir o campo Resultado. Selecione o objeto AdapterForm1 e insira um novo componente do tipo AdapterFieldGroup. Ser criado o AdapterFieldGroup2. Faa o vnculo com o objeto Adapter1, atravs da propridade Adapter. Ainda no AdapterFieldGroup2, adicione o field fldResultado atravs da opo Add Field. Altere a propriedade ViewMode do field adicionado para vwDisplay. A figura 11.43 ilustra o resultado da nossa operao.
232 Delphi 7 Internet e Banco de Dados Grave o nosso projeto e execute normalmente a aplicao atravs da tecla F9, ou da opo Run/Run... do menu. Atravs das opes Tools/WebAppDebugger vamos executar o nosso servidor e depurador de aplicaes. Clique no boto Start para iniciar o servidor e, em seguida, no link Default URL. Ao clicar no link Default ser apresentado um documento HTML (figura 11.44) com todos os servios registrados. Selecione o nosso exemplo e clique no boto GO.
Figura 11.44 Servios registrados A figura 11.45 ilustra o resultado de nossa aplicao.
WebSnap 233
uses WebReq, WebCntxt, WebFact, Variants; function formulario: Tformulario; begin Result := Tformulario(WebContext.FindModuleClass(Tformulario)); end; procedure Tformulario.Valor1GetValue(Sender: TObject; var Value: Variant); begin Value:=v1; end;
234 Delphi 7 Internet e Banco de Dados procedure Tformulario.Valor2GetValue(Sender: TObject; var Value: Variant); begin Value:=v2; end; procedure Tformulario.calculaExecute(Sender: TObject; Params: TStrings); begin v1:= Valor1.ActionValue.Values[0]; v2:= Valor2.ActionValue.Values[0]; vResultado:=v1+v2; end; procedure Tformulario.ResultadoGetValue(Sender: TObject; var Value: Variant); begin Value:=vResultado; end; initialization if WebRequestHandler <> nil then WebRequestHandler.AddWebModuleFactory(TWebPageModuleFactory.Create(Tformulario, TWebPageInfo.Create([wpPublished {, wpLoginRequired}], '.html'), crOnDemand, caCache) ); end.
WebSnap 235
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 12
Intraweb
A grande revoluo, e por que no dizer, a agradvel surpresa presente na nova verso do Delphi: Intraweb. Desenvolvido pela empresa Atozed Software, e rapidamente adotado pela Borland numa distribuio especial (existe uma verso mais poderosa), vem ganhando simpatizantes em todo o mundo. Diversas empresas esto desenvolvendo componentes para trabalhar em conjunto com o Intraweb, dando ainda mais poder a esta incrvel tecnologia. Desenvolver aplicaes com o Intraweb bastante agradvel e prtico e certamente vai encorajar excelentes desenvolvedores Delphi, que antes torciam o nariz para a tecnologia WebBroker, devido s dificuldades comuns encontradas no desenvolvimento de aplicaes para Internet, como o aprendizado de HTML, JavaScript, alguma ferramenta aliada, como o DreamWeaver, entre outros. Desenvolvedores Delphi, criem coragem para entrar no mundo Internet com o Intraweb. Digo isso a todos que chegaram nesse captulo, passando pelos anteriores, ou at mesmo a quem abriu o livro aqui, neste tpico.
Algumas curiosidades
A Borland vem trabalhando com extremo profissionalismo, apoiando diversas empresas parceiras em projetos de tecnologia para as suas ferramentas. S para ter uma idia disso tudo, incorporou na verso 7 diversas tecnologias, como o prprio Intraweb, Rave Report (fantstico gerador de relatrios, e forte substituto do QuickReport), RxLib agora vem no CD 2, Indy Components, j visto no captulo 9, entre outras tecnologias. Se a tecnologia boa, pode ter certeza de que ser adotada nas prximas verses, e isso vem crescendo a cada dia. Sorte nossa! Antes de colocar a mo-na-massa, vou apresentar seus principais componentes: Os componentes esto divididos em quatro sees: IWStandard, IWData, IWClientSide e IWControl.
236
Intraweb 237
Componentes IWStandard
COMPONENTE DESCRIO/USO
Para inserir uma Applet Java em sua pgina, oferecendo a configurao dos controles atravs do Object Inspector. Boto de formulrio, com funes adversas, inclusive Submit. Controles de CheckBox para formulrio. ComboBox para seleo, com opes de preenchimento de lista. Campo para edio com diversas propriedades de controle, como tamanho, se requerido, tipo password, entre outras. Linha horizontal. Para exibio de imagens estticas ou dinmicas. Transforma automaticamente a maioria dos formatos para JPEG. Utilizado para exibir imagens estticas, armazenadas num arquivo. Semelhante ao Label do Delphi. Cria um hyperlink, controlado atravs do evento OnClick. Utilizado para apresentar listas de marcao ou numeradas. Lista de opes que podem ser selecionadas. Possui um forte controle de propriedades. rea de edio (assim como o Delphi), com mltiplas linhas. Componente fantstico, que cria um menu a partir de um componente TMainMenu do Delphi. Muito bom mesmo. Agora suas aplicaes Web tero um aspecto mais profissional. Conjunto de opes ao usurio, semelhante ao RadioGroup do Delphi. Amigos, fiquei impressionado com o poder deste componente. Semelhante ao StringGrid, com opo individual de controle de clulas. Muito bom mesmo.
TIWMemo TIWMenu
TIWRadioGroup TIWTable
COMPONENTE
DESCRIO/USO
Este componente permite associar um template HTML ao nosso formulrio. Apresenta textos com mltiplas linhas, sem suporte edio. Cria um Timer no lado servidor para disparar eventos. Apresenta um TreeView com diversos controles. Muito bom. Hyperlinks externos. Este componente quebra um galho incrvel. Quem j tentou fazer rotinas de upload com a tecnologia WebBroker sabe do que estou falando. Era muito difcil, mas agora ficou muito fcil com este componente. Grid sem vnculo com banco de dados. Apresenta figuras retangulares, com diversas opes de preenchimento. Amigos, fiquei de boca aberta com os recursos deste componente. Tem a funo de um container, como o Panel do Delphi. Fantstico!
Componentes IWData
COMPONENTE DESCRIO/USO
TIWDBCheckbox TIWDBCombobox
CheckBox Data Ware, com diversas opes de configurao. ComboBox Data Ware, com incrveis propriedades, como tipo do cursor, ordenao, controle de scripts, entre outros. DBEdit Data Ware, com todos os eventos do HTML, alm de propriedades controladas pelo JavaScript. DBGrid muito bacana e funcional, com diversos controles e eventos. DBImage Data Ware. DBLabel Data Ware. DBListBox com diversos controles e propriedades.
Intraweb 239
COMPONENTE
DESCRIO/USO
TIWDBLookupCombobox
Fantstico componente semelhante ao DBLookupComboBox do Delphi. Quem j desenvolveu aplicaes padro WebBroker sabe o enorme trabalho que d para fazer um LookupComboBox. Outra maravilha, semelhante ao DBLookupListBox do Delphi. DBMemo com diversos controles e propriedades. Amigos, este componente incrvel, tem todos os controles do DBNavigator do Delphi e possui controle de mensagens de diversos nveis. Voc poder configurar a prpria mensagem de confirmao para excluso. Muito bom. Nota 10. Semelhante ao DBText. Utilizado para associar um campo do tipo stream com a funo de uploads de arquivo.
TIWDBText TIWDBFile
Componentes IWClientSide
COMPONENTE DESCRIO/USO
TIWCSLabel TIWCSNavigator
TIWDynamicChart
TIWDynamicChartLegend TIWDynGrid
Apresentao de campos de uma tabela do lado cliente (veja controles IWControl). Controle de Navegao dos dados de uma tabela do lado Cliente. Imagine voc acessando uma tabela prconfigurada no lado cliente, e navegando vontade. Grfico com diversas opes, baseados em dados do lado cliente embora seja possvel alimentar com os dados do lado Servidor, pois no existe vnculo com DataWare, e sim com um IWClientDataSet (IW Control). Legendas do grfico, para ser utilizado em conjunto com o TIWDynamicChart. Grid ligado ao IWClientDataSet (IW Control).
Componentes IWControl
COMPONENTE DESCRIO/USO
TIWClientSideDataSet TIWClientSideDataSetDBLink
TIWLayoutMgrForm TIWLayoutMgrHTML
TIWModuleController TIWPageProducer
TIWStandAloneServer
Controle DataSet para armazenar informaes e disponibilizar aos controles IWClientSide. Controle DataSet no padro DataWare, onde voc dever ligar diretamente a um DataSource. Isso muito legal, pois o DataSource poder coletar dados de diversas origens. Controle de layout dos objetos de um formulrio. Permite a edio do formulrio no padro HTML. Quer dar o seu toque pessoal? Ento este o componente certo. Habilita o controle do servidor para o padro PageMode do Intraweb. Com este componente voc poder utilizar toda a tecnologia Intraweb com WebSnap, e tambm aproveitar a tecnologia dos Page Producers do WebBroker. Controle da aparncia e outras propriedades da aplicao.
Antes de Comear
Este tpico muito importante, pois precisamos conhecer alguns conceitos do Intraweb. Na verso distribuda com o Delphi 7, o Intraweb coloca automaticamente o nome das units iniciais bem como do projeto. Isso pode dificultar um pouco no comeo, mas em nosso caso iremos criar uma estrutura de diretrios com o intuito de organizar nossos exerccios com o Intraweb, e evitar conflitos. Crie a seguinte estrutura de diretrios (diagrama 12.1)
Intraweb 241
C:\CursoWeb Intraweb
Figura 12.1 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa primeira aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio1).
Figura 12.2 Seleo do diretrio Perceba que o Intraweb criou um mdulo principal, com alguns controles (figuras 12.3 e 12.4).
Figura 12.4 Formulrios padro da aplicao Stand Alone O Intraweb cria a seguinte estrutura de arquivos para o tipo de aplicao Stand Alone:
Intraweb 243 x x x IWProject.DPR IWUnit1.PAS ServerController.PAS Projeto Unit principal, contendo o formulrio principal da aplicao Controle principal da aplicao, com sesses de usurio, tipo de acesso, protocolos de segurana (SSL), browsers, entre outros.
Agora com o foco no formulrio (selecione o formulrio da unit IWUnit1), insira um componente do tipo IWLabel e altere sua propriedade caption para Exerccio 1. A figura 12.5 ilustra o formulrio principal com o objeto IWLabel1.
Figura 12.5 Formulrio principal Agora, meus amigos, para quem estava com saudades do famoso F9 para executar e depurar as aplicaes, o Intraweb retorna aos bons tempos e habilita esta opo. Aperte F9 para executar nosso primeiro exerccio. Dever aparecer o servidor de testes do Intraweb, como ilustra a figura 12.6.
Figura 12.6 Servidor de Aplicaes Intraweb Repare que no existe nenhuma sesso ativa (Active Sessions). Para executar nossa aplicao, voc poder teclar novamente F9, ou pressionar o primeiro speed button, ou ento acessar o menu File/Run.. A figura 12.7 ilustra o resultado do nosso primeiro exerccio.
Figura 12.7 Resultado do primeiro exerccio Tente pressionar F9 algumas vezes no Intraweb Server Application, e repare que so criadas novas sesses (figura 12.8).
Figura 12.8 Sesses ativas O mais interessante de tudo isso, que o Intraweb possui um forte controle de sesses. Repare na figura 12.9 que o Intraweb utiliza um nmero extenso, definindo a sesso do usurio. Este controle bastante robusto e facilita muito a vida do desenvolvedor no controle de sesses.
Figura 12.9 Controle de sesses Encerre o servidor de aplicaes, e retorne ao Delphi. Vejamos agora, todo o cdigo criado pelo Intraweb em nossa primeira aplicao.
Intraweb 245 TformMain = class(TIWAppForm) IWLabel1: TIWLabel; public end; implementation {$R *.dfm} uses ServerController; end. Basicamente define a classe TformMain com o objeto IWLabel1. Para analisar mais profundamente nosso primeiro exerccio, clique com o boto direito do mouse no formulrio principal e selecione a opo Preview. A figura 12.10 ilustra o Preview do Intraweb.
Figura 12.10 Preview do Intraweb muito interessante essa versatilidade do Intraweb. Agora, selecione a seo Source logo abaixo do Preview e repare o cdigo HTML gerado, inclusive com CSS (figura 12.11).
Figura 12.11 Cdigo HTML Como o cdigo dinmico, o modelo gerado e visto na figura 12.11 apropriado para o modelo de servidor IntraWeb Server Application, no modo Preview. Veja a verso HTML gerada fora do Preview, mas ainda no servidor Intraweb.
Intraweb 247 <span id="IWLABEL1" class="IWLABEL1CSS">IWLabel1</span> </body> </html> Complicado, no acham? Podem ficar tranqilos, pois dificilmente teremos que dar manuteno no cdigo HTML. A idia justamente essa, utilizar o RAD (Rapid Application Development) do Intraweb para criar e dar manuteno s nossas aplicaes. S para finalizar a parte de cdigos deste tpico, vamos analisar a unit ServerController.
248 Delphi 7 Internet e Banco de Dados function UserSession: TUserSession; begin Result := TUserSession(RWebApplication.Data); end; procedure TIWServerController.IWServerControllerBaseNewSession( ASession: TIWApplication; var VMainForm: TIWAppForm); begin ASession.Data := TUserSession.Create; end; end. Amigos, analisando o cdigo da unit ServerController, podemos perceber a flexibilidade no controle de sesses por usurio. possvel criar variveis similares s globais, mas com instncias por sesso, ou seja, cada usurio ter a sua prpria varivel. Eu explico melhor.Vamos imaginar uma varivel que totaliza o valor da compra, ou at mesmo uma matriz, contendo diversas informaes sobre a compra atual, e poder acessar em nvel de usurio, ou melhor, por sesso, cada varivel. Veja o cenrio: Usurio 1 Sesso 08A197007D9506F23B52E240 Valor 300 Usurio 2 Sesso E4949A0062C7BBC23C52E240 Valor 180 Usurio 3 Sesso D0679B0010B757C63C52E240 Valor 180 Repare que cada sesso possui uma identificao diferente. Imagine quando o usurio solicitar a finalizao da compra, onde necessrio apresentar o resumo e o valor total. Com o Intraweb extremamente simples; basta acessar o contedo das variveis definidas no ServerController. Mas como ele faz isso? Uma mistura de cookies com persistncia. Com isso conclumos nosso primeiro exerccio e conhecemos alguns conceitos do Intraweb.
Intraweb 249
Figura 12.12 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio2). Grave toda a aplicao, e insira os componentes que seguem:
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Segundo Exemplo 120 16
OBJETO TIWEdit Objeto edNome Propriedade Name Left MaxLength Top Width Valor edNome 72 30 56 225
OBJETO TIWButton Objeto btConfirma Propriedade Name Caption Left Top Valor btConfirma Confirma 136 104
OBJETO TIWLabel Objeto lbMensagem Propriedade Name Caption Left Top Visible Valor lbMensagem deixe em branco 24 152 False
Figura 12.13 Formulrio segundo exemplo Agora vamos codificar um pouco. Selecione o objeto btConfirma (boto) e insira o cdigo que segue, no evento OnClick. lbMensagem.Caption:='Seja bem vindo(a) '+edNome.Text; lbMensagem.Visible:=True; O mais interessante de tudo isso, que estamos colocando cdigo Object Pascal puro, ou melhor, Delphi Language como chamado agora.
Intraweb 251 Execute a aplicao, e seguindo o mesmo procedimento do primeiro exemplo, no Intraweb Server Application, pressione novamente a tecla F9. A figura 12.14 ilustra o resultado do nosso segundo exemplo.
Figura 12.15 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio3). Insira a unit SysUtils, na clusula uses da aplicao, para que possamos fazer algumas operaes. Grave toda a aplicao, e insira os componentes que seguem:
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Terceiro Exemplo 112 16
OBJETO TIWHRule Objeto IWHRule1 Propriedade Left Top Width Valor 56 40 225
Intraweb 253
OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top OBJETO TIWEdit Objeto edN1 Propriedade Name Left Text Top Valor edN1 56 (deixe em branco) 80 Valor IWLabel2 Insira dois nmeros e selecione a operao 56 56
OBJETO TIWEdit Objeto edN2 Propriedade Name Left Text Top Valor edN2 56 (deixe em branco) 112
OBJETO TIWHRule Objeto IWHRule1 Propriedade Left Top Width Valor 56 144 73
OBJETO TIWEdit Objeto edTotal Propriedade Name Left Text Top Valor edTotal 56 (deixe em branco) 152
OBJETO TIWButton Objeto btAdicao Propriedade Name Caption Left Tag Width Valor btAdicao + 144 1 25
TIWButton Objeto btSubtracao Propriedade Name Caption Left Tag Width Valor btSubtracao 176 2 25
TIWButton Objeto btMultiplicacao Propriedade Name Caption Left Tag Width Valor btMultiplicacao x 208 3 25
importante >>>
Intraweb 255
OBJETO TIWButton Objeto btDivisao Propriedade Name Caption Left Tag Width Valor btDivisao : 240 4 25
importante >>>
A figura 12.16 ilustra nosso formulrio.
Figura 12.16 Formulrio terceiro exemplo Agora vamos codificar o boto btAdicao. No evento OnClick do boto, insira o cdigo que segue: var n1,n2,total:single; operacao:integer; begin try n1:=StrtoFloat(edN1.Text); n2:=StrtoFloat(edN2.Text); total:=0; operacao:=(Sender as TIWButton).Tag; case operacao of 1:total:=n1+n2; 2:total:=n1-n2; 3:total:=n1*n2; 4:total:=n1/n2; end;
256 Delphi 7 Internet e Banco de Dados edTotal.Text:=FloatToStr(total); except on EZeroDivide do WebApplication.ShowMessage('Diviso por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; Antes de analisar o cdigo, selecione os demais botes e associe o cdigo do evento OnClick, como ilustra a figura 12.17.
Figura 12.17 Associao do evento OnClick aos demais botes. Vamos analisar o cdigo. var n1,n2,total:single; operacao:integer; Neste primeiro bloco estamos declarando variveis para execuo da operao matemtica (n1, n2 e total), bem como uma varivel auxiliar (operao) com o intuito de associar o boto que est chamando o evento. Em cada boto, definimos valores diferentes para a propriedade TAG, que ser facilmente assimilada por nossa aplicao. try n1:=StrtoFloat(edN1.Text); n2:=StrtoFloat(edN2.Text); total:=0; operacao:=(Sender as TIWButton).Tag; Em seguida, iniciamos um bloco protegido (try) e convertemos o contedo dos campos de edio edN1 e edN2, para o tipo float. Neste mesmo bloco estamos iniciando a varivel total e atribuindo varivel operacao, o valor contido na propriedade TAG de um objeto do tipo TIWButton, que em nosso caso, so representadas pelos botes btAdicao, btSubtracao, btMultiplicacao e btDivisao. case operacao of 1:total:=n1+n2; 2:total:=n1-n2; 3:total:=n1*n2; 4:total:=n1/n2; end; Neste bloco, fazemos as devidas operaes de acordo com o boto pressionado. edTotal.Text:=FloatToStr(total);
Intraweb 257 Em seguida, atribumos ao objeto edTotal o resultado da operao. except on EZeroDivide do WebApplication.ShowMessage('Diviso por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; Por fim, tratamos duas excees: EZeroDivide (diviso por zero), e EOverFlow (Overflow na operao). Repare que em caso de erro, estamos apresentando mensagens ao usurio. muito parecido com o famoso Application.ShowMessage. Neste caso, utilizamos o WebApplication.ShowMessage. As figuras 12.18, 12.19 e 12.20 ilustram nossa aplicao em tempo de execuo.
Figura 12.18 Operao de adio A figura 12.18 ilustra o sucesso da operao de adio. Em seguida temos nossa primeira mensagem de erro. A figura 12.19 ilustra um erro de diviso por zero.
Figura 12.19 Diviso por zero Em seguida temos um erro de OverFlow (figura 12.20).
Intraweb 259
begin try n1:=StrtoFloat(edN1.Text); n2:=StrtoFloat(edN2.Text); total:=0; operacao:=(Sender as TIWButton).Tag; case operacao of 1:total:=n1+n2; 2:total:=n1-n2; 3:total:=n1*n2; 4:total:=n1/n2; end; edTotal.Text:=FloatToStr(total); except on EZeroDivide do WebApplication.ShowMessage('Diviso por zero !'); on EOverFlow do WebApplication.ShowMessage('Aconteceu OverFlow !'); // end; end; end.
Figura 12.21 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio4). Grave toda a aplicao, e insira os componentes que seguem:
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Quarto Exemplo 112 16
OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top OBJETO TIWLabel Objeto lbMensagem Propriedade Name Caption Left Top Font.Color Valor lbMensagem Mensagem 32 168 clRed Valor IWLabel2 Selecione o arquivo para UpLoad 32 48
OBJETO TIWFile1 Objeto IWFile1 Propriedade Name Left Top Width Valor IWFile1 32 72 200
Intraweb 261
OBJETO TIWButton1 Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 UpLoad 32 104 75
Figura 12.22 Formulrio para UpLoad Agora vamos codificar a rotina de UpLoad. No evento OnClick do objeto IWButton1, coloque o cdigo que segue: try IWFile1.SaveToFile(ExtractFilePath(ParamStr(0)) + IWFile1.FileName); lbMensagem.Caption:='O arquivo'+IWFile1.Filename+' foi gravado no diretrio '+#13#10+ ExtractFilePath(ParamStr(0))+' com xito'; lbMensagem.Visible := True; except lbMensagem.Caption:='Houve um problema com a rotina de UPLOAD'; lbMensagem.Visible := True; end; Amigos, a linha em negrito (IWFile1,SaveToFile...), a nica linha necessria para fazer o UpLoad do arquivo. Em nosso caso estamos fazendo uma rotina de tratamento de erros e exibindo a mensagem do resultado da operao. Caso seja bem sucedida, apresenta o nome do arquivo e em qual diretrio foi gravado no servidor. Em caso de erro, apresenta apenas uma mensagem : Houve um problema.... A figura 12.23 ilustra nossa aplicao sendo executada.
Dica
Voc poder configurar o diretrio que receber os arquivos. Normalmente numa Intranet, existe um servidor de arquivos, onde sua aplicao poder gravar as informaes provenientes da rotina de UpLoad. Veja o exemplo:
IWFile1.SaveToFile(F:\arquivos\+ IWFile1.FileName);
Intraweb 263 uses ServerController; procedure TformMain.IWButton1Click(Sender: TObject); begin try IWFIle1.SaveToFile(ExtractFilePath(ParamStr(0)) + IWFile1.FileName); lbMensagem.Caption:='O arquivo'+IWFile1.Filename+' foi gravado no diretrio '+#13#10+ ExtractFilePath(ParamStr(0))+' com xito'; lbMensagem.Visible := True; except lbMensagem.Caption:='Houve um problema com a rotina de UPLOAD'; lbMensagem.Visible := True; end; end; end.
Figura 12.24 Escolha do tipo da Aplicao Em seguida, selecione o diretrio de nossa segunda aplicao, em nosso caso (c:\cursoweb\intraweb\exercicio5). Grave toda a aplicao, e insira os componentes que seguem:
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Quinto Exemplo 112 16
OBJETO TIWButton Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 Formulrio 2 120 56 115
OBJETO TIWButton Objeto IWButton2 Propriedade Name Caption Left Top Width Valor IWButton2 Formulrio 3 225 124 115
OBJETO TIWEdit1 Objeto edNome Propriedade Name Left Text Top Width Valor edNome 40 (deixe em branco) 126 175
Agora vamos criar um segundo formulrio. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.25).
Intraweb 265
Figura 12.25 Criando um novo formulrio Altere a propriedade Name do formulrio para Form2. Grave a unit com o nome un_formulrio2. Insira os componentes que seguem no Form2.
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Formulrio 2 136 36
OBJETO TIWButton Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 Fecha 136 96 75
Vamos codificar este formulrio. No evento OnClick do objeto IWButton1, insira o seguinte cdigo Hide; No cdigo que acabamos de inserir, estamos escondendo o formulrio, e retornando origem. Para entender o funcionamento, vamos codificar o nosso formulrio principal.
266 Delphi 7 Internet e Banco de Dados Insira a unit un_formulario2 na clusula uses do formulrio principal. Agora vamos codificar o evento OnClick do objeto IWButton1 do formulrio principal. var Form2:TForm2; begin Form2 := TForm2.Create(WebApplication); Form2.Show; end; Estamos fazendo uma operao bastante simples. Primeiro declaramos uma varivel do tipo TForm2 (classe herdada da TForm2 que est contida na unit un_formulario2). var Form2:TForm2; Em seguida instanciamos o objeto. Form2 := TForm2.Create(WebApplication); E por fim, apresentamos o objeto. Form2.Show; As figuras 12.26 e 12.27 ilustram nossos dois primeiros formulrios.
Intraweb 267
Figura 12.27 Formulrio 2 Vamos dar uma olhadinha no resultado desta primeira parte de nossa aplicao. Execute a aplicao e clique no boto que representa a chamada do primeiro formulrio. As figuras 12.28 e 12.29 ilustram o resultado da primeira parte de nossa aplicao.
268 Delphi 7 Internet e Banco de Dados Agora vamos criar a segunda parte de nossa aplicao, fazendo uma interatividade entre os formulrios. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Application Form (figura 12.30).
Figura 12.30 Criando um novo formulrio Altere a propriedade Name do formulrio para Form3. Grave a unit com o nome un_formulrio3. Insira os componentes que seguem no Form3.
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Formulrio 3 136 36
OBJETO TIWLabel Objeto lbMensagem Propriedade Name Caption Left Top Valor lbMensagem Mensagem 32 72
Intraweb 269
OBJETO TIWButton Objeto IWButton1 Propriedade Name Caption Left Top Width Valor IWButton1 Fecha 128 120 75
Vamos codificar este formulrio. No evento OnClick do objeto IWButton1, insira o seguinte cdigo Hide; Voltando ao formulrio principal, coloque a unit un_formulario3 na clusula uses. Vamos codificar o boto IWButton2 do formulrio principal. Coloque o cdigo que segue no evento OnClick do boto. var Form3:TForm3; begin Form3 := TForm3.Create(WebApplication); Form3.lbMensagem.Caption:=edNome.Text+', seja bem-vindo(a)'; Form3.Show; end; Assim como na primeira fase da aplicao, declaramos uma varivel do tipo TForm3 (classe herdada da TForm3 que est contida na unit un_formulario3). var Form3:TForm3; Em seguida instanciamos o objeto. Form3 := TForm3.Create(WebApplication); E agora, que temos o controle total do objeto, estamos alterando a propriedade Caption do objeto lbMensagem. Form3.lbMensagem.Caption:=edNome.Text+', seja bem-vindo(a)'; E por fim, apresentamos o objeto. Form3.Show; As figuras 12.31 e 12.32 ilustram o resultado da segunda fase de nossa aplicao.
Figura 12.32 Formulrio 3 em ao Este exemplo, embora bastante simples, demonstra a interatividade entre formulrios. Bastante comum em aplicaes Internet, tenho certeza que utilizaro muito este conceito.
Intraweb 271 IWLabel1: TIWLabel; edNome: TIWEdit; IWLabel2: TIWLabel; IWButton2: TIWButton; procedure IWButton1Click(Sender: TObject); procedure IWButton2Click(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController, un_formulario2, un_formulario3; procedure TformMain.IWButton1Click(Sender: TObject); var Form2:TForm2; begin Form2 := TForm2.Create(WebApplication); Form2.Show; end; procedure TformMain.IWButton2Click(Sender: TObject); var Form3:TForm3; begin Form3 := TForm3.Create(WebApplication); Form3.lbMensagem.Caption:=edNome.Text+', seja bem-vindo(a)'; Form3.Show; end; end.
272 Delphi 7 Internet e Banco de Dados ServerController; procedure TForm2.IWButton1Click(Sender: TObject); begin Hide; end; end.
Intraweb 273
Figura 12.33 Iniciando a aplicao A nica diferena na opo with Data Module, justamente a criao automtica de um Data Module, bem como suas referncias. Insira um objeto do tipo TSQLConnection, e atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo. PROPRIEDADE VALOR
Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.
Figura 10.34 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet e altere as seguintes propriedades: PROPRIEDADE VALOR
timo, agora vamos para o formulrio principal. Insira a unit DataModuleUnit na clusula uses, e grave a aplicao. Insira os componentes que seguem.
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Sexto Exemplo 128 208
Intraweb 275
OBJETO TDataSource [DataAccess] Objeto DataSource1 OBJETO TIWDBGrid Objeto IWDBGrid1 Propriedade Name Align DataSource Valor IWDBGRID1 alTop DataSource1 Propriedade Name DataSet Valor DataSource1 DataModule1.SQLDataSet1
Figura 12.35 Formulrio principal No colocamos nenhum cdigo nesta aplicao. Assim como em aplicaes desktop, apenas associamos os objetos. Vamos executar a aplicao e ver o resultado (figura 12.36).
Figura 12.36 Sexto exemplo em execuo Demonstrei neste exemplo uma forma simples de disponibilizar informaes de banco de dados na Internet. O grande momento deste exemplo foi justamente a simplicidade e a semelhana com o mtodo tradicional de desenvolvimento. No prximo tpico vamos desenvolver uma aplicao completa, a mesma que desenvolvemos no Captulo 7.
Intraweb 277
interface uses {$IFDEF Linux}QForms, {$ELSE}Forms, {$ENDIF} SysUtils, Classes, DBXpress, FMTBcd, DB, SqlExpr; type TDataModule1 = class(TDataModule) SQLConnection1: TSQLConnection; SQLDataSet1: TSQLDataSet; private public end; // Procs function DataModule1: TDataModule1; implementation {$R *.dfm} uses IWInit, ServerController; // Since we are threaded we cannot use global variables to store form / datamodule references // so we store them in WebApplication.Data and we could reference that each time, but by creating // a function like this our other code looks "normal" almost as if its referencing a global. // This function is not necessary but it makes the code in the main form which references this // datamodule a lot neater. // Without this function ever time we would reference this datamodule we would use: // TDataModule1(WebApplication.Data).Datamodule.<method / component> // By creating this procedure it becomes: // TDataModule1.<method / component> // Which is just like normal Delphi code. function DataModule1: TDataModule1; begin Result := TUserSession(RWebApplication.Data).Datamodule1; end; end.
Cadastro de Clientes
Agora iremos desenvolver uma aplicao parecida com a do Captulo 7, onde faremos um cadastro de clientes com as principais operaes. Atravs das opes File/New/Other..., selecione a seo Intraweb e escolha o modelo Stand Alone Application with Data Module (figura 12.37).
Definies iniciais
Figura 12.37 Iniciando a aplicao Selecione o DataModule e insira um objeto do tipo TSQLConnection. Atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo. PROPRIEDADE VALOR
Altere tambm a propriedade LoginPrompt para false. Nunca esquea de fazer esta alterao, pois numa aplicao servidora, no existe a possibilidade do usurio interagir no login do banco de dados.
Intraweb 279
Figura 10.38 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades: PROPRIEDADE SQLConnection CommandText Active VALOR ConexaoBD select * from TBCLIENTE True
Objeto de Incluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.
OBJETO TSQLQuery Objeto SQLInclui Propriedade Valor Name SQLInclui SQLConnection ConexaoBD SQL INSERT INTO TBCLIENTE VALUES(0,:prazao, :pendereco,:pcidade, :pestado,:pcep,:pemail)
Objeto de Alterao
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.
OBJETO TSQLQuery Objeto SQLAltera Propriedade Valor Name SQLAltera SQLConnection BancoDados SQL UPDATE TBCLIENTE SET RAZAO_SOCIAL=:prazao, ENDERECO=:pendereco, CIDADE=:pcidade, ESTADO=:pestado, CEP=:pcep, EMAIL=:pemail WHERE COD_CLIENTE=:pcodigo
Na propriedade PARAMS do SQLAltera altere os tipos dos parmetros para String, com exceo do parmetro PCODIGO, que deve ser Integer.
Objeto de Excluso
Insira um objeto do tipo TSQLQuery e altere as propriedades que seguem.
Intraweb 281
OBJETO TSQLQuery Objeto SQLExclui Propriedade Valor Name SQLExclui SQLConnection BancoDados SQL DELETE FROM TBCLIENTE WHERE COD_CLIENTE=:pcodigo
Figura 12.39 Menu Principal Insira um objeto do tipo TIWMenu (seo IW Standard) e altere a propriedade Attached Menu para MainMenu1. Na realidade estamos vinculando nosso objeto MainMenu1 com o IWMenu1 do Intraweb. Configure a propriedade BackGroundColor do objeto FormMain para $00DDFFFF. Amigos, isto apenas uma sugesto de cor. Insira os componentes que seguem no FormMain.
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Cadastro de Clientes 136 80
Valor IWImmage1 168 insira uma figura qualquer, exemplo: logo.jpg 120
Figura 12.40 Formulrio principal Agora iremos codificar duas opes do menu principal: Finaliza e Informaes/Sobre. Selecione a opo Finaliza no objeto MainMenu1 e insira o cdigo que segue no evento OnClick. WebApplication.Terminate('At logo !'); Neste evento estamos finalizando a aplicao e apresentando a mensagem At Logo!, ao usurio. Agora selecione a opo Informaes/.Sobre e insira o cdigo que segue.
Intraweb 283 WebApplication.ShowMessage('Cadastro de Clientes' +#13#10+ 'Verso 1.0',smAlert); Neste evento apresentamos uma janela de dilogo ao usurio, com as informaes da aplicao. Bastante simples, no?
Figura 12.41 Criando um novo formulrio Altere a propriedade Name do formulrio para FmInclusao e BackGroundColor para $00DDFFFF. . Grave a unit com o nome un_inclusao. Insira os componentes que seguem no FmInclusao..
OBJETO TIWRectangle Objeto IWRectangle1 Propriedade Name Align Color Font.Color Font.Size Font.Style.fsBold Text Valor IWRectangle1 alTop clNavy clWhite 16 True Cadastro de Clientes (Incluso)
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Razo Social 24 88
OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top Valor IWLabel2 Endereo 24 120
OBJETO TIWLabel Objeto IWLabel3 Propriedade Name Caption Left Top Valor IWLabel3 Cidade 24 152
OBJETO TIWLabel Objeto IWLabel4 Propriedade Name Caption Left Top Valor IWLabel4 UF 328 152
Intraweb 285
OBJETO TIWLabel Objeto IWLabel5 Propriedade Name Caption Left Top Valor IWLabel5 CEP 448 152
OBJETO TIWLabel Objeto IWLabel6 Propriedade Name Caption Left Top Valor IWLabel6 e-Mail 24 184
OBJETO TIWEdit Objeto edRazao Propriedade Name BgColor Height Left Text Top Width Valor edRazao clYellow 21 128 deixar em branco 88 450
OBJETO TIWEdit Objeto edEndereco Propriedade Name BgColor Height Left Text Top Width Valor edEndereco clYellow 21 128 deixar em branco 120 450
OBJETO TIWEdit Objeto edCidade Propriedade Name BgColor Height Left Text Top Width Valor edCidade clYellow 21 128 deixar em branco 152 185
OBJETO TIWComboBox Objeto edUF Propriedade Name Height Left Items Sorted Top Width OBJETO TIWEdit Objeto edCEP Propriedade Name BgColor Height Left Text Top Width Valor edCEP clYellow 21 488 deixar em branco 152 90 Valor edUF 21 360 Insira a sigla de todos os estados brasileiros True 152 65
Intraweb 287
OBJETO TIWEdit Objeto edEmail Propriedade Name BgColor Height Left Text Top Width Valor edEmail clYellow 21 128 deixar em branco 184 450
OBJETO TIWButton1 Objeto btConfirma Propriedade Name Caption Height Left Top Width Valor btConfirma Confirma 25 128 232 75
OBJETO TIWButton1 Objeto btDesiste Propriedade Name Caption Height Left Top Width Valor btDesiste Desiste 25 216 232 75
Agora vamos codificar o formulrio. Insira a unit DataModuleUnit na clusula uses do formulrio. uses ServerController, DatamoduleUnit; No evento OnClick do objeto btDesiste insira o cdigo que segue: Hide; Para que possamos retornar ao formulrio de origem, utilizamos o mtodo Hide do formulrio. Agora vamos codificar o evento OnClick do objeto btConfirma.
288 Delphi 7 Internet e Banco de Dados try {Inclui Cliente} with DataModule1.SQLInclui do begin ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve smSameWindow); end; Hide; um problema na incluso do cliente',
Vamos analisar o cdigo. Nesta primeira parte, iniciamos um bloco protegido. try Em seguida, estamos atribuindo parmetros ao objeto SQLInclui do DataModule1. {Inclui Cliente} with DataModule1.SQLInclui do begin ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; E, finalmente, executando a operao e apresentando a mensagem de sucesso na opero. ExecSQL; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); Em caso de erro, estamos criando o bloco except. except WebApplication.ShowMessage('Houve smSameWindow); end; um problema na incluso do cliente',
E apresentando a mensagem do problema. A figura 12.42 ilustra o nosso formulrio de incluso de clientes.
Intraweb 289
Figura 12.43 Criando um novo formulrio Altere a propriedade Name do formulrio para FmAltera e BackGroundColor para $00DDFFFF. Grave a unit com o nome un_alteracao. Insira os componentes que seguem no FmAltera.
OBJETO TIWRectangle Objeto IWRectangle1 Propriedade Name Align Color Font.Color Font.Size Font.Style.fsBold Text Valor IWRectangle1 alTop clNavy clWhite 16 True Cadastro de Clientes (Alterao)
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Razo Social 24 88
OBJETO TIWLabel Objeto IWLabel2 Propriedade Name Caption Left Top Valor IWLabel2 Endereo 24 120
OBJETO TIWLabel Objeto IWLabel3 Propriedade Name Caption Left Top Valor IWLabel3 Cidade 24 152
Intraweb 291
OBJETO TIWLabel Objeto IWLabel4 Propriedade Name Caption Left Top Valor IWLabel4 UF 328 152
OBJETO TIWLabel Objeto IWLabel5 Propriedade Name Caption Left Top Valor IWLabel5 CEP 448 152
OBJETO TIWLabel Objeto IWLabel6 Propriedade Name Caption Left Top Valor IWLabel6 e-Mail 24 184
OBJETO TIWLabel Objeto IWLabel7 Propriedade Name Caption Left Top Valor IWLabel7 Cdigo Cliente 24 56
OBJETO TIWLabel Objeto lbCodigo Propriedade Name Caption Left Top Valor lbCodigo cdigo 144 56
OBJETO TIWEdit Objeto edRazao Propriedade Name BgColor Height Left Text Top Width Valor edRazao clYellow 21 128 deixar em branco 88 450
OBJETO TIWEdit Objeto edEndereco Propriedade Name BgColor Height Left Text Top Width Valor edEndereco clYellow 21 128 deixar em branco 120 450
OBJETO TIWEdit Objeto edCidade Propriedade Name BgColor Height Left Text Top Width Valor edCidade clYellow 21 128 deixar em branco 152 185
Intraweb 293
OBJETO TIWComboBox Objeto edUF Propriedade Name Height Left Items Sorted Top Width OBJETO TIWEdit Objeto edCEP Propriedade Name BgColor Height Left Text Top Width Valor edCEP clYellow 21 488 deixar em branco 152 90 Valor edUF 21 360 Insira a sigla de todos os estados brasileiros True 152 65
OBJETO TIWEdit Objeto edEmail Propriedade Name BgColor Height Left Text Top Width Valor edEmail clYellow 21 128 deixar em branco 184 450
OBJETO TIWButton1 Objeto btConfirma Propriedade Name Caption Height Left Top Width Valor btConfirma Confirma 25 128 232 75
OBJETO TIWButton1 Objeto btDesiste Propriedade Name Caption Height Left Top Width Valor btDesiste Desiste 25 216 232 75
Agora vamos codificar o formulrio. Insira a unit DataModuleUnit na clusula uses do formulrio. uses ServerController, DatamoduleUnit; No evento OnClick do objeto btDesiste insira o cdigo que segue: Hide; Para que possamos retornar ao formulrio de origem, utilizamos o mtodo Hide do formulrio. Agora vamos codificar o evento OnClick do objeto btConfirma. try {Altera Cliente} with DataModule1.SQLAltera do begin ParamByName('pcodigo').Value:=StrtoInt(lbCodigo.Text); ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente alterado com sucesso',smSameWindow);
Intraweb 295
um
problema
na
alterao
do
cliente',
Vamos analisar o cdigo. Nesta primeira parte, iniciamos um bloco protegido. try Em seguida, estamos atribuindo parmetros ao objeto SQLAltera do DataModule1. {Inclui Cliente} with DataModule1.SQLAltera do begin ParamByName('pcodigo').Value:=StrtoInt(lbCodigo.Text); ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; E finalmente executando a operao e apresentando a mensagem de sucesso na opero. ExecSQL; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); Em caso de erro, estamos criando o bloco except. except WebApplication.ShowMessage('Houve smSameWindow); end; E apresentando a mensagem do problema. Embora o Intraweb fornea objeto com conexo direta a DataSets, estamos utilizando os objetos convencionais, sem nenhum vnculo com DataSet. Quando trabalhamos com Internet, complicado disponibilizar objeto de conexo direta com DataSets, justamente porque no sabemos o que poder ocorrer com a conexo. Sugiro adotar este modelo de desenvolvimento pela segurana. Ento, para que nossos campos sejam preenchidos automaticamente com as informaes do banco de dados, vamos utilizar o TDataSource e TSQLDataSet. um problema na incluso do cliente',
OBJETO TSQLDataSet Objeto SQLDataSet1 Propriedade Name SQLConnection CommandText Valor SQLDataSet1 DataModule1.ConexaoBD select * from TBCLIENTE WHERE COD_CLIENTE=:pCodigo Query
CommandType
Defina o parmetro pCodigo como Integer.
OBJETO TDataSource Objeto DataSource1 Propriedade Name DataSet Valor DataSource SQLDataSet1
Pronto, agora conclumos o nosso formulrio de alterao de clientes. A figura 12.44 ilustra o nosso formulrio.
Intraweb 297
Figura 12.45 Criando um novo formulrio Altere a propriedade Name do formulrio para FmManutencao e BackGroundColor para $00DDFFFF. . Grave a unit com o nome un_manutencao. Insira os componentes que seguem no FmManutencao..
OBJETO TIWRectangle Objeto IWRectangle1 Propriedade Name Align Color Font.Color Font.Size Font.Style.fsBold Text Valor IWRectangle1 alTop clNavy clWhite 16 True Cadastro de Clientes (Manuteno)
OBJETO TIWRegion1 Objeto IWRegion1 Propriedade Name Align Color Height Valor IWRegion1 alTop clWhite 56
OBJETO TIWLabel Objeto IWLabel1 Propriedade Name Caption Left Top Valor IWLabel1 Razo Social 16 16
OBJETO TIWEdit Objeto edPesquisa Propriedade Name BgColor Height Left Text Top Width Valor edPesquisa clYellow 21 112 deixar em branco 16 175
OBJETO TIWButton Objeto btPesquisa Propriedade Name Caption Height Left Top Width Valor btPesquisa Confirma 25 296 16 75
OBJETO TIWButton Objeto btVolta Propriedade Name Caption Height Left Top Width Valor btVolta Menu Principal 25 384 16 122
Intraweb 299 Em nosso formulrio iremos utilizar objetos de acesso a dados. Insira um objeto do tipo TDataSource e outro do tipo TSQLQuery (dbExpress), configurando as propriedades que seguem.
OBJETO TSQLQuery Objeto SQLPesquisa Propriedade Name SQLConnection SQL OBJETO TDataSource Objeto DS1 Propriedade Name DataSet Valor DS1 SQLPesquisa Valor SQLPesquisa DataModule1.ConexaoBD select * from TBCLIENTE
Repare que estamos colocando o comando SELECT * na propriedade SQL do objeto SQLPesquisa. Fazemos isso apenas para nos auxiliar na montagem do Grid. Com o foco no formulrio, insira um objeto do tipo TIWDBGrid e altere as propriedades que seguem.
OBJETO TIWDBGrid Objeto IWDbGrid1 Propriedade Name DataSource Rollover RollOverColor Valor IWDbGrid1 DS1 True $00E1FFE1
Curiosidade
Repare que estamos repetindo o campo COD_CLIENTE diversas vezes. Fazemos isto para substituir os mtodos de chamada de operaes, devido a um BUG no Intraweb. At a verso 5.51 (que vem junto com o D7), o BUG de vnculo com controles (Control) ainda no estava corrigido. Existe uma maneira de associar um objeto, como por exemplo, um boto, a um evento do Grid. Iramos fazer isso para disparar as rotinas de alterao e excluso, mas infelizmente, devido ao BUG, estamos substituindo por outro mtodo.
Coluna [ 0 ] Cod_Cliente Objeto Propriedade IWDbGrid1>Columns[0] DataField LinkField Title.Text Coluna [ 1 ] Razao_Social Objeto Propriedade IWDbGrid1>Columns[1] DataField Title.Text Coluna [ 2 ] EMAIL Objeto IWDbGrid1>Columns[2] Propriedade DataField Title.Text Coluna [ 3 ] Cod_Cliente Objeto Propriedade IWDbGrid1>Columns[3] DataField LinkField Title.Text Coluna [ 4 ] Cod_Cliente Objeto Propriedade IWDbGrid1>Columns[4] DataField LinkField Title.Text
Valor Cod_Cliente Cod_Cliente Cdigo Valor Razao_Social Razo Social Valor email e-Mail Valor Cod_Cliente Cod_Cliente Altera Valor Cod_Cliente Cod_Cliente Exclui
Agora vamos codificar o nosso formulrio. Na clusula uses insira as seguintes units. uses ServerController, DataModuleUnit, un_alteracao;
Intraweb 301 Em seguida devemos criar uma procedure pblica para auxiliar no posicionamento do registro, de maneira que possamos atribuir o contedo do banco de dados, aos campos do formulrio fmAltera. Defina a procedure LOCALIZA, como segue. public procedure Localiza(Cliente: integer); E na seo implementation, insira o cdigo a seguir. procedure Tfmmanutencao.Localiza(Cliente:integer); begin SQLPesquisa.Locate('cod_cliente', Cliente, []); end; Neste cdigo estamos apenas posicionando o ponteiro do registro de acordo com a seleo do usurio. Agora vamos codificar o objeto btPesquisa. Insira o cdigo que segue no evento OnClick. SQLPesquisa.SQL.Clear; SQLPesquisa.SQL.Add('SELECT * FROM '+''''+'%'+edPesquisa.Text+'%'+''''); SQLPesquisa.Open; TBCLIENTE WHERE RAZAO_SOCIAL LIKE
Neste cdigo estamos preparando uma consulta SQL, baseada na informao do usurio, extrada do objeto edPesquisa. As informaes so apresentadas no Grid, devido ao vnculo com o objeto. Coloque o cdigo a seguir, no evento OnClick do objeto btVolta. Hide; Agora vamos codificar a operao de alterao do Grid. Atravs da propriedade Columns do IWDBGrid1, selecione a coluna 3 (Altera) e insira o cdigo que segue no evento OnClick. var fmAltera:TfmAltera; begin fmAltera:=TFmAltera.Create(WebApplication); {Atribui o cdigo a Query} with fmAltera do begin FmAltera.SQLDataSet1.Params[0].Value:=StrtoInt(AValue); fmAltera.SQLDataSet1.Open; edRazao.Text:=SQLDataSet1RAZAO_SOCIAL.AsString; edEndereco.Text:=SQLDataSet1ENDERECO.AsString; edCidade.Text:=SQLDataSet1CIDADE.AsString; edCEP.Text:=SQLDataSet1CEP.AsString; edUF.ItemIndex:=edUF.Items.IndexOf( QLDataSet1ESTADO.AsString); edEmail.Text:=SQLDataSet1EMAIL.AsString; {Atribui os valores} fmAltera.lbCodigo.Caption:=Avalue; fmAltera.Show; end; Vamos analisar o cdigo. No bloco a seguir, estamos definindo um objeto do tipo TfmAltera, para que possamos manipular o objeto. var
302 Delphi 7 Internet e Banco de Dados fmAltera:TfmAltera; No bloco que segue, instanciamos o objeto FmAltera. begin fmAltera:=TFmAltera.Create(WebApplication); Em seguida atribumos o cdigo do cliente, extrado da varivel AValue (constante da procedure), ao objeto SQLDataSet1. with fmAltera do begin FmAltera.SQLDataSet1.Params[0].Value:=StrtoInt(AValue); fmAltera.SQLDataSet1.Open; O bloco a seguir atribui as informaes do SQLDataSet1 aos campos do objeto fmAltera, apresentando o formulrio de alterao de clientes. edRazao.Text:=SQLDataSet1RAZAO_SOCIAL.AsString; edEndereco.Text:=SQLDataSet1ENDERECO.AsString; edCidade.Text:=SQLDataSet1CIDADE.AsString; edCEP.Text:=SQLDataSet1CEP.AsString; edUF.ItemIndex:=edUF.Items.IndexOf( QLDataSet1ESTADO.AsString); edEmail.Text:=SQLDataSet1EMAIL.AsString; {Atribui os valores} fmAltera.lbCodigo.Caption:=Avalue; fmAltera.Show; Agora vamos codificar a operao de excluso do Grid. Atravs da propriedade Columns do IWDBGrid1, selecione a coluna 4 (Exclui) e insira o cdigo que segue no evento OnClick. try with DataModule1.SQLExclui do begin ParamByName('pcodigo').Value:=StrtoInt(AValue); ExecSQL; end; WebApplication.ShowMessage('Cliente Excluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve smSameWindow); end; um problema na exclusao do cliente',
Vamos analisar o cdigo. No cdigo que segue estamos criando um bloco protegido; atribuindo um parmetro para o objeto SQLExclui e finalmente apresentando uma mensagem ao usurio, em caso de sucesso da operao. try with DataModule1.SQLExclui do begin ParamByName('pcodigo').Value:=StrtoInt(AValue); ExecSQL; end; WebApplication.ShowMessage('Cliente Excluido com sucesso',smSameWindow); No bloco a seguir estamos tratando a exceo, apresentando para o usurio uma mensagem de alerta.
um
problema
na
exclusao
do
cliente',
Grave a unit un_manutencao e selecione o formulrio principal. A figura 12.47 ilustra o nosso formulrio de manuteno.
Figura 12.47 Formulrio de manuteno Vamos codificar o formulrio principal, para concluir a aplicao. Na clusula uses do formulrio principal (formMain), insira as units que seguem. uses ServerController, un_Inclusao, un_manutencao; Agora vamos codificar a opo Incluso de Clientes do Menu Principal. No evento OnClick da opo, insira o cdigo a seguir. var fmInclusao:TFmInclusao; begin fmInclusao:=TFMInclusao.Create(WebApplication); fmInclusao.Show; end; Neste cdigo estamos instanciando o objeto FmInclusao e apresentando ao usurio. E agora, vamos codificar a opo Manuteno/Consulta.Coloque o cdigo que segue no evento OnClick da opo. var fmManutencao:TFmManutencao; begin fmManutencao:=TFMManutencao.Create(WebApplication); fmManutencao.Show; end; Com isso conclumos o nosso projeto de Cadastro de Clientes. As figuras 12.48 a 12.53 ilustram nossa aplicao em tempo de execuo.
Intraweb 305
Figura 12.51 Manuteno Repare que na tela de manuteno existe um rollover passeando entre os registros. Para que voc possa fazer qualquer tipo de operao, clique no cdigo do cliente, correspondente operao (altera ou exclui). Voc poder digitar apenas uma parte da razo social do cliente. Por exemplo: digitando Facunte, so apresentados todos os registros que contm a palavra Facunte, independente da posio.
308 Delphi 7 Internet e Banco de Dados with DataModule1.SQLInclui do begin ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente incluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve um problema na incluso do cliente', smSameWindow); end; Hide; end; end.
Intraweb 309 SQLDataSet1ENDERECO: TStringField; SQLDataSet1CIDADE: TStringField; SQLDataSet1ESTADO: TStringField; SQLDataSet1CEP: TStringField; SQLDataSet1EMAIL: TStringField; procedure IWButton2Click(Sender: TObject); procedure IWButton1Click(Sender: TObject); public end; implementation {$R *.dfm} uses ServerController, DataModuleUnit; procedure TfmAltera.IWButton2Click(Sender: TObject); begin Hide; end; procedure TfmAltera.IWButton1Click(Sender: TObject); begin try {Altera Cliente} with DataModule1.SQLAltera do begin ParamByName('pcodigo').Value:=StrtoInt(lbCodigo.Text); ParamByName('prazao').Value:=edRazao.Text; ParamByName('pendereco').Value:=edEndereco.Text; ParamByName('pcidade').Value:=edCidade.Text; ParamByName('pestado').Value:=edUf.Items[edUf.ItemIndex]; ParamByName('pcep').Value:=edCep.Text; ParamByName('pemail').Value:=edEmail.Text; ExecSQL; end; WebApplication.ShowMessage('Cliente Alterado com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve um problema na alteracao do cliente', smSameWindow); end; Hide; end; end.
310 Delphi 7 Internet e Banco de Dados uses IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl, IWCompRectangle, Forms, IWContainer, IWRegion, FMTBcd, DB, SqlExpr, IWGrids, IWDBGrids, IWCompLabel, IWCompButton, IWCompEdit, SysUtils, IWHTMLControls; type TfmManutencao = class(TIWAppForm) IWRectangle1: TIWRectangle; IWRegion1: TIWRegion; IWDBGrid1: TIWDBGrid; SQLPesquisa: TSQLQuery; Ds1: TDataSource; edPesquisa: TIWEdit; btPesquisa: TIWButton; IWLabel1: TIWLabel; btVolta: TIWButton; procedure btPesquisaClick(Sender: TObject); procedure btVoltaClick(Sender: TObject); procedure IWDBGrid1Columns3Click(ASender: TObject; const AValue: String); procedure IWDBGrid1Columns4Click(ASender: TObject; const AValue: String); public procedure Localiza(Cliente: integer); end; implementation {$R *.dfm} uses ServerController, DataModuleUnit, un_alteracao; procedure Tfmmanutencao.Localiza(Cliente:integer); begin SQLPesquisa.Locate('cod_cliente', Cliente, []); end; procedure TfmManutencao.btPesquisaClick(Sender: TObject); begin SQLPesquisa.SQL.Clear; SQLPesquisa.SQL.Add('SELECT * FROM TBCLIENTE WHERE '+''''+'%'+edPesquisa.Text+'%'+''''); SQLPesquisa.Open; end; procedure TfmManutencao.btVoltaClick(Sender: TObject); begin Hide; end; procedure TfmManutencao.IWDBGrid1Columns3Click(ASender: TObject; const AValue: String); var fmAltera:TfmAltera; begin
RAZAO_SOCIAL
LIKE
Intraweb 311 fmAltera:=TFmAltera.Create(WebApplication); { Atribui o cdigo a Query } with fmAltera do begin fmAltera.SQLDataSet1.Params[0].Value:=StrtoInt(AValue); fmAltera.SQLDataSet1.Open; edRazao.Text:=SQLDataSet1RAZAO_SOCIAL.AsString; edEndereco.Text:=SQLDataSet1ENDERECO.AsString; edCidade.Text:=SQLDataSet1CIDADE.AsString; edCEP.Text:=SQLDataSet1CEP.AsString; edUF.ItemIndex:=edUF.Items.IndexOf(SQLDataSet1ESTADO.AsString); edEmail.Text:=SQLDataSet1EMAIL.AsString; { Atribui os valores } fmAltera.lbCodigo.Caption:=Avalue; fmAltera.Show; end; end; procedure TfmManutencao.IWDBGrid1Columns4Click(ASender: TObject; const AValue: String); begin try with DataModule1.SQLExclui do begin ParamByName('pcodigo').Value:=StrtoInt(AValue); ExecSQL; end; WebApplication.ShowMessage('Cliente Excluido com sucesso',smSameWindow); except WebApplication.ShowMessage('Houve smSameWindow); end; end; end. um problema na exclusao do cliente',
312 Delphi 7 Internet e Banco de Dados public end; // Procs function DataModule1: TDataModule1; implementation {$R *.dfm} uses IWInit, ServerController; // Since we are threaded we cannot use global variables to store form / datamodule references // so we store them in WebApplication.Data and we could reference that each time, but by creating // a function like this our other code looks "normal" almost as if its referencing a global. // This function is not necessary but it makes the code in the main form which references this // datamodule a lot neater. // Without this function ever time we would reference this datamodule we would use: // TDataModule1(WebApplication.Data).Datamodule.<method / component> // By creating this procedure it becomes: // TDataModule1.<method / component> // Which is just like normal Delphi code. function DataModule1: TDataModule1; begin Result := TUserSession(RWebApplication.Data).Datamodule1; end; end.
Intraweb 313
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais
Captulo 13
WebServices
O que so WebServices
Para explicar de maneira adequada o significado da tecnologia WebServices, interessante fazer uma breve introduo aos problemas atuais no mundo da tecnologia. Com o grande avano de sistemas operacionais, bancos de dados, hardware, software, enfim, todo o tipo de tecnologia que envolve o mundo dos negcios, vem surgindo a necessidade de compartilhamento de informaes entre parceiros comerciais, governo e sociedade e at mesmo entre departamentos de uma empresa. Acontece que interligar diferentes plataformas, bancos de dados, operaes, entre outros conceitos, uma tarefa muito complicada e trabalhosa. Imagine o seguinte cenrio (figura 13.1) :
Consulta CPF (Restrio)
Aquisio Produtos
314
WebServices 315 A figura 13.1 ilustra uma situao comum nos dias de hoje, onde temos diversas operaes com tecnologias e parceiros diferentes. Sem dvida que a maioria das operaes poder ser desenvolvida com um grande trabalho em equipe, exigindo um bom trabalho de pesquisa junto aos parceiros e inmeras horas de desenvolvimento. justamente neste cenrio que surgiu a tecnologia WebServices, para impulsionar os sistemas legados e facilitar a integrao de parceiros comerciais. Pegando carona na primeira fase do WebServices, foram implementadas e idealizadas novas funes, com o intuito de promover e consolidar operaes semelhantes. A figura 13.2 ilustra este cenrio.
Figura 13.2 Cenrio de WebServices semelhantes Analisando a figura 13.2, temos uma aplicao que utiliza WebServices de diferentes fornecedores para fazer cotaes de aes, assim como efetuar a aquisio. Um exemplo bastante utilizado, a cotao do cmbio atual. Veja o cenrio na figura 13.3. Imagine o cenrio ilustrado pela figura 13.3 onde sua aplicao necessita ter 24 horas/dia (lembre-se de que o mundo no pra) a cotao do cmbio de diferentes pases, onde seria uma catstrofe imaginar a quebra dos servidores. O cenrio da figura 13.3, ilustra uma operao de cotao de cmbio, utilizando WebServices semelhantes, onde no pode haver queda de servidores, pois a misso crtica. Bem, do seu lado tudo sem problemas, pois existe uma infra-estrutura ideal para este tipo de operao. Mas no lado do provedor de informaes? Imagine que voc esteja utilizando apenas um WebService e o mesmo quebra a conexo? O que fazer? Com a segunda fase da tecnologia, voc pode mapear ilimitados WebServices semelhantes para fazer o mesmo servio, ou seja, quando cair o primeiro, passa para o segundo; na queda do segundo, para o terceiro e assim por diante, podendo at retornar ao primeiro WebService.
Cotao Cmbio A
Cotao Cmbio B
Sua Aplicao
Cotao Cmbio E Cotao Cmbio C
Cotao Cmbio D
Figura 13.3 Cotao cmbio atual Para concluir o conceito de WebServices, vamos imaginar um cenrio mais simples, onde precisamos integrar informaes de diferentes departamentos e filiais, que foram desenvolvidos em plataformas diferentes. Um bom exemplo para isso so os bancos que esto adquirindo outros bancos em todo o mundo e que utilizam conceitos e plataformas diferentes de trabalho. A figura 13.4 ilustra o Banco Facunte, adquirindo outros dois bancos com diferentes tecnologias.
WebServices 317 Tecnologias do nosso cenrio exemplo Banco Facunte X Y S.O. Unix NT Solaris Banco Dados DB2 SQL Server Oracle Terminais Terminais Linux Windows Terminais Linux
Integrar informaes de diferentes plataformas no novidade e, como j foi mencionado, possvel, mas muito trabalhoso. A proposta da tecnologia WebServices, neste cenrio, o de facilitar a troca de informaes, fazendo o Banco Facunte entender e tratar as informaes dos Bancos X e Y, independente do banco de dados, sistema operacional ou outro fator no citado. Com algumas linhas de programao e um bom planejamento, as informaes essenciais sero interligadas facilmente. Meus amigos, isso WebServices! Em resumo, WebServices, um padro no-proprietrio, que possibilita o processamento distribudo em sistemas heterogneos. E acredito que muitos de vocs neste ponto estejam ansiosos para produzir o seu primeiro WebService. Antes, devemos conhecer os padres que fazem parte da tecnologia.
Padronizao
Imagine IBM, Microsoft, Borland, Oracle, Sun e outros gigantes da rea de tecnologia, planejando, desenvolvendo e decidindo juntos uma mesma tecnologia. isso que acontece com o WebServices. E para facilitar ainda mais o seu uso e aplicabilidade, foram adotados padres j consagrados, alm do desenvolvimento de outros padres bastante simples. Vejamos os padres:
XML
XML (Extensive Markup Language) ou Linguagem de Marcao Extensvel, que consiste em uma srie de regras, dividindo o documento em partes lgicas e hierrquicas. Atualmente utilizada para trabalhar em conjunto com diversas tecnologias, seja no padro de gravao de um arquivo, no transporte de informaes, at mesmo em definies de montagem de veculos. Trabalhando em conjunto com o WebServices, fornece estrutura para o documento de regras e servios (WSDL), pacote de dados e ocorrncias. Veja um exemplo de XML de dados: <?xml version=1.0?> <LISTA_CLIENTES> <Cliente> <RazaoSocial>Banco Facunte</RazaoSocial> <Cidade>So Paulo</Cidade> <Estado>SP</Estado> </Cliente> <Cliente> <RazaoSocial>Global Education</RazaoSocial> <Cidade>So Paulo</Cidade> <Estado>SP</Estado> </Cliente> <Cliente> <RazaoSocial>Clube Delphi</RazaoSocial> <Cidade>Rio de Janeiro</Cidade> <Estado>RJ</Estado> </Cliente> </LISTA_CLIENTES>
WSDL
WSDL Web Service Definition Language ou Linguagem de Definies de WebServices. O WSDL um documento criado no padro XML, com o objetivo de fornecer informaes sobre a definio de um WebService. Esta definio consiste em mtodos, parmetros e servios fornecidos pelo WebService. Veremos na prtica um documento WSDL, bem como a sua forma de utilizao.
SOAP
Soap Simple Object Access Protocol ou Protocolo Simples de Acesso a Objetos. Em poucas palavras, o SOAP o protocolo utilizado para troca de informaes atravs de objetos criados em diversas linguagens de programao, como Delphi, Java, C++, C#, VB.NET, entre outras. Trafega atravs da porta 80 de um servidor HTTP, facilitando assim o trabalho com servidores protegidos por Firewall, onde a porta 80, apesar de fortemente monitorada, permite o trfego de informaes.
UDDI
UDDI Universal Definition Discovery Inteface ou Interface para Descoberta de Definies Universais. Para facilitar a compreenso do UDDI, farei uma comparao com os servios de busca na Internet. Quando queremos procurar algum documento, artigo, software, na Internet, normalmente utilizamos servios de busca, como o Google (meu preferido), Yahoo!, Hotbot, Cad?, entre outros. Imagine que para localizar um WebServices bastante semelhante, com alguns parmetros diferenciados. O UDDI na realidade um grande catlogo de WebServices, oferecido por diversas empresas, seja ela envolvida na padronizao, como IBM e Borland, ou at mesmo empresas independentes, como o SALCentral.COM (www.salcentral.com). Com isso poderemos localizar e mapear servios semelhantes, como o exemplo que vimos neste captulo, sobre a cotao de cmbios.
E UDDI
Figura 13.5 Aplicao utilizando o servio UDDI A figura 13.5 ilustra uma aplicao utilizando os servios do UDDI. Neste cenrio foram localizados e mapeados WebServices semelhantes, de maneira que a aplicao tenha objetos redundantes, aumentando a eficcia e a segurana. Isso demonstra a flexibilidade da tecnologia, onde as empresas podero escolher os servios (WebServices) mais adequados sua aplicao.
WebServices 319
Sugestes de desenvolvimento
CPF Restries de Crdito
Empresas que oferecem servios e informaes sobre restries de crdito podero desenvolver WebServices para fornecer tais informaes diretamente nas aplicaes de seus clientes. O mais interessante que a cobrana ser automtica, pois cada cliente ter uma chave criptografada e a empresa poder cobrar por nmero de acessos.
Rastreamento de Cargas
Empresas como FedEx e DHL j fornecem seus prprios WebServices. Correios, empresas de logstica e transporte, podero desenvolver WebServices para rastrear as cargas e encomendas enviadas. Alm disso, podero fornecer informaes de estimativa de chegada dinmica, ou seja, imagine uma carga que teve um acrscimo na previso de chegada, devido a uma greve no porto, ou at mesmo um problema no trajeto; com isso a informao poder ser fornecida dinamicamente ao cliente, onde o mesmo tomar as devidas providncias, como um adiamento de reunio ou de produo.
Identificao de Veculos
Os DETRANs de todo o pas poderiam desenvolver WebServices, com inmeros objetivos. O mais importante seria a identificao prvia do veculo, onde despachantes, compradores e vendedores de veculos, guardas e operadores de trnsito, saberiam imediatamente informaes do veculo em questo. Atravs de Palmtops ou celulares, guardas de trnsito poderiam controlar com mais facilidade as multas em veculos infratores. Fabricantes de veculos poderiam checar com maior facilidade informaes sobre um grupo de chassis, para um possvel recall, preparando uma estratgia junto sua equipe de mecnicos para um melhor atendimento por regio.
Cotao de Aes
As operadoras de aes poderiam desenvolver WebServices, afim de fornecer informaes diretamente nas aplicaes de seus clientes, onde os mesmos poderiam concluir negcios mais facilmente, e armazenando a informao diretamente em seu prprio banco de dados.
Cotao de Moedas
J existem diversos WebServices catalogados oferecendo o servio de cotao de moedas. Os mais avanados oferecem funes para converso, onde a aplicao fornece as moedas e valores e o WebService retorna o resultado. Existem outros que fazem atualizao monetria baseada em mltiplas moedas. Isso muito interessante em pases como o nosso, que j trocou de moeda uma dezena de vezes.
Controle de Estoque
Tenho certeza que ser muito bem utilizado e aplicado este tipo de WebService. Poderemos desenvolver WebServices que sero utilizados por nossos clientes, vendedores e tambm fornecedores. Os clientes utilizaro para fazer cotaes e fechamento de pedidos atravs de suas prprias aplicaes. Os vendedores, tanto externos como internos, utilizaro para consultar o saldo no estoque e efetuar os seus pedidos. J os fornecedores podero enviar oramentos para produtos que esto chegando no nvel de estoque mnimo, assim como os prprios compradores da empresa.
CEPs
Os Correios, uma das empresas mais respeitadas do pas, poderiam desenvolver um WebService, oferecendo as informaes de sua base de dados on-line, diretamente na aplicao do cliente. O objetivo no apenas consultar e corrigir informaes sobre o CEP; pode-se ampliar o servio para o clculo de envio de encomendas, e os prazos estipulados.
RG
Um dos assuntos polmicos em nosso pas. Cada Estado tem sua forma de estabelecer regras para os nmeros de R.G.s. Ser que um dia iremos acordar e cada cidado brasileiro ter sua identificao prpria, sem duplicidades? Isso s ser possvel atravs de uma integrao entre os municpios de todo o pas. Quando isso for possvel, o Governo poder oferecer WebServices com os mais variados objetivos. Um bom exemplo para isso, seria o Censo. Sem dvida nenhuma teramos um Censo com um percentual prximo do mximo e com muita rapidez.
CNAB
Quem a j passou pelo suado processo de montagem de arquivos no padro (eu disse padro?) CNAB? Cada banco tem um formato de arquivo, um nmero diferente de propriedades a serem preenchidas, headers psicodlicos e linhas de registros com informaes absurdas e repetitivas. Criando um WebService, padro (aqui sim, seria um padro), os clientes poderiam transmitir e receber informaes de cobrana com uma facilidade enorme. O mais interessante disso tudo acontece quando o cliente opta por outra instituio para fazer a sua cobrana e no precisa alterar nenhuma linha de programao, apenas algumas propriedades, como por exemplo, o cdigo da instituio financeira.
http://uddi.ibm.com
UDDI da IBM, com opes de registros de WebServices corporativos e para testes. .
http://uddi.microsoft.com
UDDI da Microsoft, com diversas opes de busca, registro simples de novos WebServices, ferramentas para desenvolvedores, entre outros servios. Excelente.
WebServices 321
http://uddi.sap.com
UDDI da SAP. necessrio entrar na rea UDDI Discovery para registrar, procurar e publicar WebServices.
http://www.webservicelist.com/
Fantstico catlogo de Webservices independente, com diviso por categoria, busca de semelhantes, palavras chaves, entre outros servios.
http://www.xmethods.com
Excelente catlogo de Webservices, com os mais populares, at Webservices comerciais.
Nos servios aqui apresentados, existe uma imensido de WebServices, divididos nas mais variadas categorias. Desde simples consultas a cotao de moedas, at servios na rea de sade. Mais adiante iremos aprender a importar estes servios (WebServices) em nossa aplicao.
Delphi x WebServices
Neste tpico iremos aprender os conceitos de WebServices integrado com o Delphi. O Delphi possui um conjunto de componentes especfico para a tecnologia de WebServices. Na seo WebServices da paleta de componentes, encontramos os seguintes objetos: COMPONENTE (OBJETO) DESCRIO
HTTPRIO
Utiliza para obter uma referncia para uma interface registrada. Gera em memria uma tabela de mtodos, a fim de fornecer a implementao da interface.
HTTPReqResp
Executa mtodos de chamada na interface, de maneira a enviar e receber mensagens no padro SOAP. Normalmente utilizado em conjunto com o HTTPRio, implementando os mtodos Get e Post.
OpToSOAPDOMConvert
Normalmente instanciado em tempo de execuo pelo componente HTTPRio, tem como principal funo fazer um parser nos mtodos de chamada.
Utilizado para conectar a aplicao aos servidores implementados no padro WebService. SOAPConnection
COMPONENTE (OBJETO)
DESCRIO
WSDLHTMLPublish
Responsvel por publicar um documento WSDL com todo o descritivo do WebService. Utilizado para interpretar uma mensagem padro SOAP, e executar o mtodo correspondente.
HTTPSoapPascalInvoker
WebService Exemplo
Vamos criar nosso primeiro WebService para aprender melhor seu conceito. Atravs das opes File/New..., seo WebServices, selecione a opo SOAP Server Application (figura 13.6).
Figura 13.6 Nova aplicao WebService Em seguida, selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.7).
WebServices 323
Figura 13.7 Tipo da aplicao servidora Em seguida, o Delphi pergunta se deseja criar uma Interface SOAP padro (figura 13.8). Em nosso primeiro exemplo, vamos criar tal Interface, a fim de conhecer sua implementao.
figura 13.8 Criao da Interface Em seguida (figura 13.9). devemos informar os dados da nova Interface. Nos campos Service Name e Unit identifier coloque wsexemplo. Com isso estamos criando uma Interface com o nome wsexemplo, e gravando a unit com o mesmo nome. Em Code generation selecione as opes Generate Comments e Generate Sample Methods. Com isso estamos gerando exemplos de mtodos e comentrios.
Figura 13.9 Identificao do servio Clique em OK para finalizar. Vamos gravar nossa aplicao.
324 Delphi 7 Internet e Banco de Dados Unit WebModule Unit Implementao WsExemplo Unit Interface WsExemplo Projeto Vamos analisar o que o nosso amigo Delphi criou. un_ws1.pas wsexemploImpl.pas wsexemploIntf.pas ws1.dpr
Figura 13.10 WebModule1 A figura 13.10 ilustra nosso WebModule com trs componentes no padro WebService (HTTPSoapDispatcher, HTTPSoapPascalInvoker e WSDLHTMLPublish). Vejamos sua implementao. procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin WSDLHTMLPublish1.ServiceInfo(Sender, Request, Response, Handled); end; A nica funo do nosso WebModule1 a criao de um handler para o WebService e publicao do documento WSDL. Na unit wsexemploIntf estamos definindo a Interface de nossa aplicao. {Invokable interface Iwsexemplo } unit wsexemploIntf; interface uses InvokeRegistry, Types, XSBuiltIns; type TEnumTest = (etNone, etAFew, etSome, etAlot); TDoubleArray = array of Double; TMyEmployee = class(TRemotable) private FLastName: AnsiString; FFirstName: AnsiString; FSalary: Double; published property LastName: AnsiString read FLastName write FLastName; property FirstName: AnsiString read FFirstName write FFirstName; property Salary: Double read FSalary write FSalary;
WebServices 325 end; { Invokable interfaces must derive from IInvokable } Iwsexemplo = interface(IInvokable) ['{A391DC0F-CDA7-4929-97B8-DAECA7C2CF18}'] { Methods of Invokable interface must not use the default } { calling convention; stdcall is recommended } function echoEnum(const Value: TEnumTest): TEnumTest; stdcall; function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; function echoDouble(const Value: Double): Double; stdcall; end; implementation initialization { Invokable interfaces must be registered } InvRegistry.RegisterInterface(TypeInfo(Iwsexemplo)); end. Esta unit na realidade est seguindo as regras da O.O. (Orientao a Objeto), onde definimos uma Interface como base, para que possamos implementar nossas classes. Alm disso estamos registrando a Interface no modelo SOAP. Repare que os mtodos criados so apenas exemplos de implementao, que solicitamos previamente, justamente para estudar e analisar. Na unit wsexemploImpl, temos a implementao da Interface que vimos anteriormente. Veja o cdigo. { Invokable implementation File for Twsexemplo which implements Iwsexemplo } unit wsexemploImpl; interface uses InvokeRegistry, Types, XSBuiltIns, wsexemploIntf; type { Twsexemplo } Twsexemplo = class(TInvokableClass, Iwsexemplo) public function echoEnum(const Value: TEnumTest): TEnumTest; stdcall; function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; function echoDouble(const Value: Double): Double; stdcall; end; implementation function Twsexemplo.echoEnum(const Value: TEnumTest): TEnumTest; stdcall; begin { TODO : Implement method echoEnum } Result := Value; end; function stdcall; begin Twsexemplo.echoDoubleArray(const Value: TDoubleArray): TDoubleArray;
326 Delphi 7 Internet e Banco de Dados { TODO : Implement method echoDoubleArray } Result := Value; end; function Twsexemplo.echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; begin { TODO : Implement method echoMyEmployee } Result := TMyEmployee.Create; end; function Twsexemplo.echoDouble(const Value: Double): Double; stdcall; begin { TODO : Implement method echoDouble } Result := Value; end; initialization { Invokable classes must be registered } InvRegistry.RegisterInvokableClass(Twsexemplo); end. Acredito que deu para perceber, que os mtodos apenas retornam os mesmos valores informados. Para compreender melhor, vamos fazer uma pequena alterao no mtodo echoDouble. Substitua a linha de retorno, pelo cdigo que segue em negrito: function Twsexemplo.echoDouble(const Value: Double): Double; stdcall; begin { TODO : Implement method echoDouble } Result := Value * 3; end; Grave a aplicao. Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.11).
WebServices 327 Agora vamos compilar a aplicao. Vamos executar a aplicao no browser para analisar o seu contedo. Digite: http://localhost/cgi-bin/ws1.exe/. A figura 13.12 ilustra o resultado da primeira fase de nossa aplicao.
Figura 13.12 Aplicao ws1 Repare que temos todos os mtodos listados na Interface Iwsexemplo (echoEnum, echoDoubleArray, echoMyEmployee, echoDouble). O documento gerado est de acordo com o padro estabelecido pelo W3C-UDDI (rgo responsvel pelo padro WebService). Clicando no link WSDL da Interface Iwexemplo ser apresentado o seguinte documento WSDL. <?xml version="1.0" encoding="utf-8" ?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="Iwsexemploservice" targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns1="urn:wsexemploIntf"> - <types> - <xs:schema targetNamespace="urn:wsexemploIntf" xmlns="urn:wsexemploIntf"> - <xs:simpleType name="TEnumTest"> - <xs:restriction base="xs:string"> <xs:enumeration value="etNone" /> <xs:enumeration value="etAFew" /> <xs:enumeration value="etSome" /> <xs:enumeration value="etAlot" /> </xs:restriction> </xs:simpleType> - <xs:complexType name="TDoubleArray"> - <xs:complexContent> - <xs:restriction base="soapenc:Array"> <xs:sequence /> <xs:attribute ref="soapenc:arrayType" n1:arrayType="xs:double[]" xmlns:n1="http://schemas.xmlsoap.org/wsdl/" /> </xs:restriction> </xs:complexContent> </xs:complexType> - <xs:complexType name="TMyEmployee"> - <xs:sequence>
328 Delphi 7 Internet e Banco de Dados <xs:element name="LastName" type="xs:string" /> <xs:element name="FirstName" type="xs:string" /> <xs:element name="Salary" type="xs:double" /> </xs:sequence> </xs:complexType> </xs:schema> </types> - <message name="echoEnum0Request"> <part name="Value" type="ns1:TEnumTest" /> </message> - <message name="echoEnum0Response"> <part name="return" type="ns1:TEnumTest" /> </message> - <message name="echoDoubleArray1Request"> <part name="Value" type="ns1:TDoubleArray" /> </message> - <message name="echoDoubleArray1Response"> <part name="return" type="ns1:TDoubleArray" /> </message> - <message name="echoMyEmployee2Request"> <part name="Value" type="ns1:TMyEmployee" /> </message> - <message name="echoMyEmployee2Response"> <part name="return" type="ns1:TMyEmployee" /> </message> - <message name="echoDouble3Request"> <part name="Value" type="xs:double" /> </message> - <message name="echoDouble3Response"> <part name="return" type="xs:double" /> </message> - <portType name="Iwsexemplo"> - <operation name="echoEnum"> <input message="tns:echoEnum0Request" /> <output message="tns:echoEnum0Response" /> </operation> - <operation name="echoDoubleArray"> <input message="tns:echoDoubleArray1Request" /> <output message="tns:echoDoubleArray1Response" /> </operation> - <operation name="echoMyEmployee"> <input message="tns:echoMyEmployee2Request" /> <output message="tns:echoMyEmployee2Response" /> </operation> - <operation name="echoDouble"> <input message="tns:echoDouble3Request" /> <output message="tns:echoDouble3Response" /> </operation> </portType> - <binding name="Iwsexemplobinding" type="tns:Iwsexemplo"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="echoEnum"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoEnum" style="rpc" /> - <input message="tns:echoEnum0Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoEnum0Response">
WebServices 329 <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> - <operation name="echoDoubleArray"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoDoubleArray" style="rpc" /> - <input message="tns:echoDoubleArray1Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoDoubleArray1Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> - <operation name="echoMyEmployee"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoMyEmployee" style="rpc" /> - <input message="tns:echoMyEmployee2Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoMyEmployee2Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> - <operation name="echoDouble"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoDouble" style="rpc" /> - <input message="tns:echoDouble3Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoDouble3Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> </operation> </binding> - <service name="Iwsexemploservice"> - <port name="IwsexemploPort" binding="tns:Iwsexemplobinding"> <soap:address location="http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo" /> </port> </service> </definitions> Parece complicado, no ? Vamos analisar algumas partes do documento para compreender melhor seu funcionamento. <types> <xs:schema targetNamespace="urn:wsexemploIntf" xmlns="urn:wsexemploIntf"> <xs:simpleType name="TEnumTest"> <xs:restriction base="xs:string"> <xs:enumeration value="etNone" /> <xs:enumeration value="etAFew" /> <xs:enumeration value="etSome" />
330 Delphi 7 Internet e Banco de Dados <xs:enumeration value="etAlot" /> </xs:restriction> Passando pelo bloco das definies inicias (<?xml version="1.0"...), chegamos no bloco de definies de tipos e mtodos. Neste bloco so definidos todos os mtodos da nossa Interface, com o descritivo completo. Repare que a classe TEnumTest descrita com perfeio. No bloco que segue, so descritos os mtodos Request e Response da Interface em questo. - <message name="echoEnum0Request"> <part name="Value" type="ns1:TEnumTest" /> </message> - <message name="echoEnum0Response"> <part name="return" type="ns1:TEnumTest" /> </message> A seguir, temos o bloco que define o nome da porta (Port) e as operaes Request e Response, descritas no bloco anterior. - <portType name="Iwsexemplo"> - <operation name="echoEnum"> <input message="tns:echoEnum0Request" /> <output message="tns:echoEnum0Response" /> </operation> Em seguida temos o bloco que envelopa e define a camada de transporte dos mtodos. - <binding name="Iwsexemplobinding" type="tns:Iwsexemplo"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="echoEnum"> <soap:operation soapAction="urn:wsexemploIntf-Iwsexemplo#echoEnum" style="rpc" /> - <input message="tns:echoEnum0Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </input> - <output message="tns:echoEnum0Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsexemploIntf-Iwsexemplo" /> </output> O ltimo bloco finaliza o documento, declarando o nome do servio, bem como o nome da porta e a sua camada de transporte. - <service name="Iwsexemploservice"> - <port name="IwsexemploPort" binding="tns:Iwsexemplobinding"> <soap:address location="http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo" /> </port> </service> </definitions> Agora vamos criar uma aplicao cliente para testar nosso primeiro WebService. Atravs das opes File/New Application crie uma nova aplicao, e grave os arquivos como segue: Unit Projeto un_teste_ws1.PAS teste_ws1.DPR
Agora vamos importar a Interface em nossa aplicao. Atravs das opes File/New.../WebServices (figura 13.13), selecione a opo WSDL Importer.
WebServices 331
Figura 13.13 WSDL importer Em seguida, como ilustra a figura 13.14 , digite o endereo que segue. http://localhost/cgi-bin/ws1.exe/wsdl/Iwsexemplo Este endereo faz a chamada ao documento WSDL da Interface Iwsexemplo.
Fgura 13.14 Importao da Interface atravs do WSDL Este procedimento est importando toda a Interface para a nossa aplicao. Com isso teremos acesso aos mtodos definidos. interessante destacar que um WebService poder ter inmeras Interfaces, onde poderemos importar apenas as que condizem com a nossa necessidade. Aperte o boto Next para avanar prxima fase. A figura 13.15 ilustra a Interface gerada pelo assistente.
Fgura 13.15 Interface gerada pelo assistente Para concluir,aperte a tecla Finish. O assistente gerou uma Unit com toda a Interface implementada. Grave a Unit com o nome Iwsexemplo1.pas. O que acabamos de fazer, na realidade, foi a importao de uma Interface para facilitar o uso do WebService. Agora com o foco na unit un_teste_ws1, insira a unit Iwexemplo1.pas gerada pelo assistente. implementation uses Iwsexemplo1; Neste ponto iremos configurar o acesso para este formulrio. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.
OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws1.exe/wsdl/Iwsexemplo Iwsexemploservice IwsexemploPort
Service Port
Com isto configuramos o objeto de acesso Interface, informando a localizao do documento WSDL (WSDLLocation), o servio (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.
WebServices 333
OBJETO TEdit Objeto edValor Propriedade Name Left Text Top Width Valor edValor 32 deixe em branco 24 120
OBJETO TButton Objeto Button1 Propriedade Name Caption Left Top Width Valor Button1 Calcula 176 24 125
OBJETO Tlabel Objeto lbResultado Propriedade Name Caption Left Top Valor lbResultado 0 32 64
Figura 13.16 Formulrio da aplicao Agora vamos codificar a aplicao. Insira o cdigo que segue no evento OnClick do objeto Button1. var Iexemplo: Iwsexemplo; begin
334 Delphi 7 Internet e Banco de Dados Iexemplo:= HR1 as Iwsexemplo; lbResultado.Caption:=FloattoStr(Iexemplo.echoDouble( StrtoFloat(edValor.Text))); end; O cdigo bastante simples, onde estamos definindo um objeto do tipo Iwsexemplo. Em seguida estamos instanciando o objeto a partir do nosso HTTPRio (HR1), adotando o modelo Iwsexemplo. E por fim, apresentamos o resultado em nosso objeto lbResultado, atravs da funo IExemplo.echoDouble. O mais importante, at aqui, justamente a compreenso de como conseguimos implementar o WebService em nossa aplicao. Vamos testar nossa aplicao. Compile e execute a aplicao, informando um nmero no campo e pressionando o boto. A figura 13.17 ilustra nossa aplicao em tempo de execuo.
, Figura 13.17 Aplicao em tempo de execuo Perceba que, na primeira vez que pressionamos o boto, existe um delay, que justamente o tempo de conexo com o WebService. Repita a operao e perceba que j no existe mais o delay. Amigos, no prximo tpico iremos desenvolver nosso prprio WebService.
WebServices 335
implementation uses Iwsexemplo1; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Iexemplo: Iwsexemplo; begin Iexemplo:= HR1 as Iwsexemplo; lbresultado.Caption:=FloattoStr(Iexemplo.echoDouble(StrtoFloat(edValor.Text))); end; end.
unit Iwsexemplo1; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:double - "http://www.w3.org/2001/XMLSchema" // !:string - "http://www.w3.org/2001/XMLSchema" TMyEmployee = class; { "urn:wsexemploIntf" }
{ "urn:wsexemploIntf" } TEnumTest = (etNone, etAFew, etSome, etAlot); TDoubleArray = array of Double; { "urn:wsexemploIntf" }
336 Delphi 7 Internet e Banco de Dados private FLastName: WideString; FFirstName: WideString; FSalary: Double; published property LastName: WideString read FLastName write FLastName; property FirstName: WideString read FFirstName write FFirstName; property Salary: Double read FSalary write FSalary; end; // ************************************************************************ // // Namespace : urn:wsexemploIntf-Iwsexemplo // soapAction: urn:wsexemploIntf-Iwsexemplo#%operationName% // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : Iwsexemplobinding // service : Iwsexemploservice // port : IwsexemploPort // URL : http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo // ************************************************************************ // Iwsexemplo = interface(IInvokable) ['{A21A137B-E1B0-488A-810D-790FBDEA675A}'] function echoEnum(const Value: TEnumTest): TEnumTest; stdcall; function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall; function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall; function echoDouble(const Value: Double): Double; stdcall; end; function GetIwsexemplo(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): Iwsexemplo; implementation function GetIwsexemplo(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): Iwsexemplo; const defWSDL = 'http://localhost/delphi/cgi-bin/ws1.exe/wsdl/Iwsexemplo'; defURL = 'http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo'; defSvc = 'Iwsexemploservice'; defPrt = 'IwsexemploPort'; var RIO: THTTPRIO; begin Result := nil; if (Addr = '') then begin if UseWSDL then Addr := defWSDL else Addr := defURL; end; if HTTPRIO = nil then RIO := THTTPRIO.Create(nil) else RIO := HTTPRIO; try
WebServices 337 Result := (RIO as Iwsexemplo); if UseWSDL then begin RIO.WSDLLocation := Addr; RIO.Service := defSvc; RIO.Port := defPrt; end else RIO.URL := Addr; finally if (Result = nil) and (HTTPRIO = nil) then RIO.Free; end; end; initialization InvRegistry.RegisterInterface(TypeInfo(Iwsexemplo), 'urn:wsexemploIntf-Iwsexemplo', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(Iwsexemplo), 'urn:wsexemploIntfIwsexemplo#%operationName%'); RemClassRegistry.RegisterXSInfo(TypeInfo(TEnumTest), 'urn:wsexemploIntf', 'TEnumTest'); RemClassRegistry.RegisterXSInfo(TypeInfo(TDoubleArray), 'urn:wsexemploIntf', 'TDoubleArray'); RemClassRegistry.RegisterXSClass(TMyEmployee, 'urn:wsexemploIntf', 'TMyEmployee'); end.
Segundo WebService
Neste exemplo vamos criar nosso WebService sem utilizar os exemplos de mtodos gerados pelo assistente. Nosso WebService consiste em fazer um simples clculo, apresentando um nmero aproximado de dias j vividos, a partir de uma idade informada. Exemplo: 28 anos = 10.220 dias aproximadamente ( 28 x 365 ), onde 28 = idade informada, 365 = dias do ano. Atravs das opes File/New..., seo WebServices, selecione a opo SOAP Server Application (figura 13.18).
338 Delphi 7 Internet e Banco de Dados Em seguida, selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.19).
Figura 13.19 Tipo da aplicao servidora Em seguida, o Delphi pergunta se deseja criar uma Interface SOAP padro (figura 13.20). Neste caso, seleciona No, pois iremos criar manualmente.
Figura 13.20 Criao da Interface Vamos gravar nossa aplicao. Unit WebModule Projeto un_ws2.PAS ws2.DPR
Agora vamos criar a Interface de nossa aplicao. A partir da verso 7, existe o assistente para a criao da Interface. Na realidade faz a mesma operao que dispensamos no dilogo anterior (figura 13.20). Atravs das opes File/New..WebServices, selecione o assistente SOAP Server Interface (figura 13.21), e em seguida pressione OK.
WebServices 339
Figura 13.21 Criando a Interface do WebService Em seguida (figura 13.22) devemos informar os dados da nova Interface. Nos campos Service Name e Unit identifier coloque wsidade. Com isso estamos criando uma Interface com o nome wsidade, e gravando a unit com o mesmo nome. Em Code generation desmarque as duas opes (Generate Comments e Generate Sample Methods).
Figura 13.22 Dados complementares da Interface O assistente criou duas novas units: wsIdadeIntf.pas e wsIdadeImpl.pas. Vamos gravar nossa aplicao. Unit wsIdadeIntf Unit wsIdadeImpl Vamos analisar as units criadas. wsIdadeIntf.pas unit wsIdadeIntf; interface uses InvokeRegistry, Types, XSBuiltIns; type IwsIdade = interface(IInvokable) wsIdadeIntf.pas wsIdadeImpl.pas
340 Delphi 7 Internet e Banco de Dados ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] end; implementation initialization InvRegistry.RegisterInterface(TypeInfo(IwsIdade)); end. Esta a unit para definio da Interface do nosso WebService. No bloco que segue, definimos os mtodos. Repare que foi criado um identificador nico (GUID). Poderamos fazer esta Interface sem o uso do assistente, e para a criao do GUID, basta pressionar as teclas CTRL-G no editor. type IwsIdade = interface(IInvokable) ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] end; A seguir temos o registro da Interface do nosso WebService.. implementation initialization InvRegistry.RegisterInterface(TypeInfo(IwsIdade)); Agora veremos a unit wsIdadeImpl. wsIdadeImpl.pas unit wsIdadeImpl; interface uses InvokeRegistry, Types, XSBuiltIns, wsIdadeIntf; type TwsIdade = class(TInvokableClass, IwsIdade) public end; implementation initialization InvRegistry.RegisterInvokableClass(TwsIdade); end. Esta a unit para implementao dos mtodos definidos na Interface (unit wsIdadeIntf). Repare no bloco a seguir, que esta unit faz uso da anterior. uses InvokeRegistry, Types, XSBuiltIns, wsIdadeIntf; No bloco que segue, os mtodos so definidos como public. type
WebServices 341 TwsIdade = class(TInvokableClass, IwsIdade) public end; Bem, agora vamos definir o mtodo de nosso WebService. Selecione a unit wsIdadeIntf, e insira o mtodo QuantosDias, como segue. IwsIdade = interface(IInvokable) ['{A808C7C4-86BC-446C-B329-60F22BD82A87}'] function QuantosDias(idade: Integer):integer; stdcall; end; Repare que estamos fazendo uma chamada explcita stdcall, padro em WebServices. Grave a unit. Agora, selecione a unit wsIdadeImpl e insira o mtodo QuantosDias, como segue; public function QuantosDias(idade: Integer):integer; stdcall; end; Na seo implementation, digite o cdigo a seguir. function TwsIdade.QuantosDias(idade: integer):integer; begin Result:=idade * 365; end; Est pronto nosso WebService. Agora vamos desenvolver dois clientes com tecnologias diferentes. O primeiro ser no padro desktop, e o outro uma aplicao CGI. Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.23).
Figura 13.23 Configurao do diretrio Compile a nossa aplicao para que possamos analisar o documento WSDL. No browser digite http://localhost/cgibin/ws2.exe. A figura 13.24 ilustra o assistente WSDL de nossa aplicao.
Figura 13.24 Pgina de informao (assistente WSDL). Repare que o nosso mtodo QuantosDias est publicado. Clique no WSDL do mtodo para visualizar a implementao. O seguinte documento WSDL foi gerado. <?xml version="1.0" encoding="utf-8" ?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="IwsIdadeservice" targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"> - <message name="QuantosDias0Request"> <part name="idade" type="xs:int" /> </message> - <message name="QuantosDias0Response"> <part name="return" type="xs:int" /> </message> - <portType name="IwsIdade"> - <operation name="QuantosDias"> <input message="tns:QuantosDias0Request" /> <output message="tns:QuantosDias0Response" /> </operation> </portType> - <binding name="IwsIdadebinding" type="tns:IwsIdade"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> - <operation name="QuantosDias"> <soap:operation soapAction="urn:wsIdadeIntf-IwsIdade#QuantosDias" style="rpc" /> - <input message="tns:QuantosDias0Request"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsIdadeIntf-IwsIdade" /> </input> - <output message="tns:QuantosDias0Response"> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:wsIdadeIntf-IwsIdade" /> </output> </operation>
WebServices 343 </binding> - <service name="IwsIdadeservice"> - <port name="IwsIdadePort" binding="tns:IwsIdadebinding"> <soap:address location="http://localhost/delphi/cgi-bin/ws2.exe/soap/IwsIdade" /> </port> </service> </definitions> Agora vamos criar a primeira aplicao cliente para o nosso WebService. Atravs das opes File/New Application cria uma nova aplicao e grave os arquivos como segue: Unit Projeto un_teste_ws2.PAS teste_ws2.DPR
Agora vamos importar a Interface em nossa aplicao. Atravs das opes File/New.../WebServices (figura 13.25), selecione a opo WSDL Importer.
Figura 13.25 WSDL importer Em seguida, como ilustra a figura 13.26 , digite o endereo que segue. http://localhost/cgi-bin/ws2.exe/wsdl/IwsIdade Este endereo faz a chamada ao documento WSDL da Interface IwsIdade.
344 Delphi 7 Internet e Banco de Dados O assistente gerou uma Unit com toda a Interface implementada. Grave a Unit com o nome IwsIdade1.pas. Agora com o foco na unit un_teste_ws2, insira a unit IwsIdade1.pas gerada pelo assistente. implementation uses IwsIdade1;
Neste ponto iremos configurar o acesso para este formulrio. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.
OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws2.exe/wsdl/IwsIdade IwsIdadeservice IwsIdadePort
Service Port
Com isto configuramos o objeto de acesso Interface, informando a localizao do documento WSDL (WSDLLocation), o servio (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.
OBJETO TEdit Objeto edValor Propriedade Name Left Text Top Width Valor edIdade 32 deixe em branco 24 120
OBJETO TButton Objeto Button1 Propriedade Name Caption Left Top Width Valor Button1 Calcula 176 24 125
WebServices 345
OBJETO Tlabel Objeto lbResultado Propriedade Name Caption Left Top Valor lbDias Dias 32 64
Figura 13.27 Formulrio da aplicao Agora vamos codificar a aplicao. Insira o cdigo que segue no evento OnClick do objeto Button1. var IIdade: IwsIdade; begin IIdade:=HR1 as IwsIdade; lbDias.Caption:='Voc j viveu aproximadamente '+InttoStr(IIdade.QuantosDias(StrtoInt(edIdade.Text)))+' dias'; end; Muito parecido com o nosso primeiro teste, estamos definindo um objeto do tipo IwsIdade, em seguida estamos instanciando o objeto a partir do nosso HTTPRio (HR1), adotando o modelo IwsIdade. E por fim, apresentamos o resultado em nosso objeto lbDias, atravs da funo IIDade.QuantosDias. Fcil? Acredito que neste ponto j deu para compreender o mtodo de implementao de um WebService. Agora vamos utilizar o mesmo WebService numa aplicao do tipo CGI. A partir do Delphi, selecione as opes File/New/Other... e em seguida a opo Web Server Application, como ilustra a figura 13.28.
346 Delphi 7 Internet e Banco de Dados Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 13.29).
Figura 13.29 Seleo do tipo da aplicao Em seguida teremos o nosso WebModule (figura 13.30).
Figura 13.30 WebModule Neste ponto ao invs de importar o WSDL, vamos apenas adicionar a unit que j importamos em nossa primeira aplicao: IwsIdade; implementation uses IwsIdade1; Neste ponto iremos configurar o acesso para o nosso CGI. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.
OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws2.exe/wsdl/IwsIdade IwsIdadeservice IwsIdadePort
Service Port
WebServices 347 Agora vamos criar nossa Action. Atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 13.31).
Figura 13.31 Editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 13.32).
OBJETO TWebActionItem Objeto padrao Propriedade Default Name PathInfo Valor True dias /dias
Esta ser nossa Action padro, ou seja, caso o usurio no digite nada, alm do nome da nossa aplicao, esta Action ser executada. No evento OnAction coloque o seguinte cdigo: var IIdade: IwsIdade; begin IIdade:=HR1 as IwsIdade; Response.Content:='Voc j viveu aproximadamente '+InttoStr(IIdade.QuantosDias(StrtoInt(Request.QueryFields.Values['idade'])))+' dias'; end; Aqui estamos utilizando o mtodo Response.Content para apresentar ao usurio a mensagem criada atravs do parmetro Idade, utilizando o mtodo QuantosDias do nosso WebService.
348 Delphi 7 Internet e Banco de Dados Antes de compilar vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.33).
Figura 13.33 Configurao do diretrio Grave os arquivos como segue. Unit Projeto un_cgi_ws2.PAS teste_cgi_ws2.DPR
http://localhost/delphi/cgi-bin/teste_cgi_ws2.exe/dias?idade=55
A figura 13.34 ilustra nosso CGI em tempo de execuo.
Figura 13.34 CGI em execuo Para testar o CGI, estamos passando atravs do parmetro Idade (?idade=), a idade desejada para o clculo. Nosso CGI extrai atravs do mtodo Request.QueryFields o valor do parmetro Idade, e faz o clculo utilizando o mtodo QuantosDias do nosso Webservice. Com isso conclumos o nosso projeto.
WebServices 349
350 Delphi 7 Internet e Banco de Dados type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:int - "http://www.w3.org/2001/XMLSchema" // ************************************************************************ // // Namespace : urn:wsIdadeIntf-IwsIdade // soapAction: urn:wsIdadeIntf-IwsIdade#QuantosDias // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : IwsIdadebinding // service : IwsIdadeservice // port : IwsIdadePort // URL : http://localhost/delphi/cgi-bin/ws2.exe/soap/IwsIdade // ************************************************************************ // IwsIdade = interface(IInvokable) ['{28CE8152-2421-53DD-F897-0FAAB7C4FB3B}'] function QuantosDias(const idade: Integer): Integer; stdcall; end; function GetIwsIdade(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IwsIdade; implementation function GetIwsIdade(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IwsIdade; const defWSDL = 'http://localhost/delphi/cgi-bin/ws2.exe/wsdl/IwsIdade'; defURL = 'http://localhost/delphi/cgi-bin/ws2.exe/soap/IwsIdade'; defSvc = 'IwsIdadeservice'; defPrt = 'IwsIdadePort'; var RIO: THTTPRIO; begin Result := nil; if (Addr = '') then begin if UseWSDL then Addr := defWSDL else Addr := defURL; end; if HTTPRIO = nil then RIO := THTTPRIO.Create(nil) else RIO := HTTPRIO; try Result := (RIO as IwsIdade);
WebServices 351 if UseWSDL then begin RIO.WSDLLocation := Addr; RIO.Service := defSvc; RIO.Port := defPrt; end else RIO.URL := Addr; finally if (Result = nil) and (HTTPRIO = nil) then RIO.Free; end; end; initialization InvRegistry.RegisterInterface(TypeInfo(IwsIdade), 'urn:wsIdadeIntf-IwsIdade', 'utf8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IwsIdade), 'urn:wsIdadeIntfIwsIdade#QuantosDias'); end.
Figura 13.35 Nova aplicao WebService Em seguida selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.36).
Figura 13.36 Tipo da aplicao servidora Na janela de dilogo que segue (figura 13.37), no confirme a criao da Interface.
WebServices 353
Figura 13.37 Criao da Interface Vamos gravar nossa aplicao. Unit WebModule Projeto un_ws3.PAS ws3.DPR
Agora vamos inserir um SOAP Data Module em nossa aplicao. Atravs das opes File/New..WebServices, selecione a opo SOAP Server Data Module (figura 13.38), e em seguida pressione OK.
Figura 13.38 Soap Server Data Module Em seguida (figura 13.39) informe o nome do nosso Soap Server Data Module, como ws3dm.
Figura 13.39 Module Name Grave a unit como un_ws3_dm.pas. Insira um objeto do tipo TSQLConnection. Atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo.
PROPRIEDADE
VALOR
CommitRetain Database Password UserName Name Altere tambm a propriedade LoginPrompt para false.
Figura 13.40 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades: PROPRIEDADE VALOR
Agora vamos codificar a Interface do nosso WebService. Na unit un_ws3_dm, insira o cdigo que segue, adequando ao cdigo j existente.
WebServices 355 type Iws3dm = interface(IAppServerSOAP) ['{7D59A6B9-A6C8-4FC4-B105-C92A0CDA478B}'] function MostraRazao(codigo:integer):String; stdcall; end; Tws3dm = class(TSoapDataModule, Iws3dm, IAppServerSOAP, IAppServer) ConexaoBD: TSQLConnection; SQLClientes: TSQLDataSet; private public function MostraRazao(codigo:integer):String; stdcall; end; Repare que criamos o mtodo MostraRazao, que implementaremos agora na seo implementation. Agora, na seo implementation, insira completamente o cdigo a seguir: function Tws3dm.MostraRazao(codigo:integer):String; begin { configura o parmetro } SQLClientes.ParamByName('pcodigo').Value:=codigo; SQLClientes.Open; if not(SQLClientes.Eof) then Result:=SQLClientes.FieldValues['RAZAO_SOCIAL'] else Result:='Cliente inexistente'; SQLClientes.Close; end; Vamos analisar o cdigo. No bloco a seguir, estamos atribuindo o cdigo transmitido atravs do Client em nosso parmetro e abrindo o DataSet. SQLClientes.ParamByName('pcodigo').Value:=codigo; SQLClientes.Open; Em seguida, verificamos a existncia do cliente, e em caso afirmativo retornamos o valor do campo Razao_Social, caso contrrio, retornamos a mensagem Cliente inexistente !. E para finalizar, fechamos o nosso DataSet. if not(SQLClientes.Eof) then Result:=SQLClientes.FieldValues['RAZAO_SOCIAL'] else Result:='Cliente inexistente'; SQLClientes.Close; O nosso WebService est prontinho pra ser utilizado. Agora vamos criar nossas aplicaes Client. Atravs das opes File/New Application crie uma nova aplicao e grave os arquivos como segue: Unit Projeto un_teste_ws3.PAS teste_ws3.DPR
Agora vamos importar a Interface em nossa aplicao. Atravs das opes File/New.../WebServices (figura 13.41), selecione a opo WSDL Importer.
Figura 13.41 WSDL importer Em seguida, como ilustra a figura 13.42 , digite o endereo que segue. http://localhost/cgi-bin/ws3.exe/wsdl/Iws3DM Este endereo faz a chamada ao documento WSDL da Interface Iws3DM.
Figura 13.42 Importando a Interface O assistente gerou uma Unit com toda a Interface implementada. Grave a Unit com o nome Iws3Dm1.pas. Agora com o foco na unit un_teste_ws3, insira a unit Iws3DM1.pas gerada pelo assistente. implementation uses Iws3DM1; Neste ponto iremos configurar o acesso para este formulrio. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.
WebServices 357
OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws3.exe/wsdl/Iws3dm Iws3dmservice Iws3DmPort
Service Port
Com isto configuramos o objeto de acesso Interface, informando a localizao do documento WSDL (WSDLLocation), o servio (Service), e a porta (Port). Agora insira os objetos que seguem, configurando suas respectivas propriedades.
OBJETO TEdit Objeto edCodigo Propriedade Name Left Text Top Width Valor edCodigo 32 deixe em branco 24 120
OBJETO TButton Objeto Button1 Propriedade Name Caption Left Top Width Valor Button1 Pesquisa 176 24 125
OBJETO Tlabel Objeto lbRazao Propriedade Name Caption Left Top Valor lbRazao Cliente 32 64
358 Delphi 7 Internet e Banco de Dados A figura 13.43 ilustra o formulrio da nossa aplicao.
Figura 13.43 Formulrio aplicao teste3 Agora vamos implementar o cdigo do formulrio. No evento OnClick do boto, insira o cdigo que segue: var IRazao:IWS3DM; begin IRazao:=HR1 as IwS3DM; lbRazao.Caption:=Irazao.MostraRazao( StrtoInt( edCodigo.Text )); end; Estamos fazendo uma operao bastante simples, passando o parmetro cdigo para o nosso WebService e apresentando o resultado no objeto lbRazao. As figuras 13.44 e 13.45 ilustram nossa aplicao em tempo de execuo.
Figura 13.45 Cliente inexistente Amigos, isto fantstico, no ? Agora vamos desenvolver uma aplicao no padro CGI para consultar a razo social de um cliente. A partir do Delphi, selecione as opes File/New/Other... e em seguida a opo Web Server Application, como ilustra a figura 13.46.
WebServices 359
Figura 13.46 Opo Web Server Application Na janela seguinte selecione a opo CGI Stand-Alone executable (figura 13.47).
Figura 13.47 Seleo do tipo da aplicao Em seguida teremos o nosso WebModule (figura 13.48).
360 Delphi 7 Internet e Banco de Dados Neste ponto ao invs de importar o WSDL, vamos apenas adicionar a unit que j importamos em nossa primeira aplicao: Iws3DM; implementation uses Iws3DM; Neste ponto iremos configurar o acesso para o nosso CGI. Insira um objeto do tipo THTTPRIO e configure as propriedades que seguem, respeitando a seqncia apresentada, caso contrrio, uma exceo ocorrer.
OBJETO THTTPRio Objeto HTTPRio1 Propriedade Name WSDLLocation Valor HR1 http://localhost/cgi-bin/ ws3.exe/wsdl/Iws3dm Iws3dmservice Iws3DmPort
Service Port
Agora vamos criar nossa Action. Atravs do duplo-clique no WebModule, acesse o editor de ActionItems (figura 13.49).
Figura 13.49 editor ActionItems Clique no primeiro boto do editor para inserir uma nova Action (figura 13.50).
WebServices 361
OBJETO TWebActionItem Objeto Padrao Propriedade Default Name PathInfo Valor True consulta /consulta
Esta ser nossa Action padro, ou seja, caso o usurio no digite nada, alm do nome da nossa aplicao, esta Action ser executada. No evento OnAction coloque o seguinte cdigo: var IRazao: Iws3DM1; begin IRazao:=HR1 as Iws3DM; Response.Content:='Cliente = '+ IRazao.MostraRazao(StrtoInt(Request.QueryFields. Values['codigo'])); end; Aqui estamos utilizando o mtodo Response.Content para apresentar ao usurio a mensagem criada atravs do parmetro codigo, utilizando o mtodo MostraRazao do nosso WebService. Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.51).
Figura 13.51 Configurao do diretrio Grave os arquivos como segue. Unit Projeto un_cgi_ws3.PAS teste_cgi_ws3.DPR
362 Delphi 7 Internet e Banco de Dados Agora vamos testar a nossa aplicao. No browser digite o seguinte endereo:
http://localhost/delphi/cgi-bin/teste_cgi_ws3.exe/consulta? codigo=14
A figura 13.52 ilustra nosso CGI em tempo de execuo.
figura 13.52 Resultado da aplicao Agora deu para perceber o poder do WebService, no? No prximo tpico, iremos desenvolver uma aplicao utilizando o protocolo SOAP em conjunto com a tecnologia DataSNAP.
unit Iws3Dm1; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns, SOAPMidas; type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:string - "http://www.w3.org/2001/XMLSchema" // !:int - "http://www.w3.org/2001/XMLSchema" // ************************************************************************ // // Namespace : urn:un_ws3_dm-Iws3dm // soapAction: urn:un_ws3_dm-Iws3dm#MostraRazao // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : Iws3dmbinding // service : Iws3dmservice // port : Iws3DmPort // URL : http://localhost/delphi/cgi-bin/ws3.exe/soap/Iws3Dm // ************************************************************************ // Iws3dm = interface(IAppServerSOAP) ['{B8148078-61EE-65BD-6196-A55E0A9CA57C}'] function MostraRazao(const codigo: Integer): WideString; stdcall; end;
implementation initialization
364 Delphi 7 Internet e Banco de Dados InvRegistry.RegisterInterface(TypeInfo(Iws3dm), 'urn:un_ws3_dm-Iws3dm', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(Iws3dm), 'urn:un_ws3_dmIws3dm#MostraRazao'); end.
WebServices 365
Figura 13.53 Nova aplicao WebService Em seguida, selecione a opo CGI para o tipo da aplicao servidora SOAP (figura 13.54).
Figura 13.54 Tipo da aplicao servidora Na janela de dilogo que segue (figura 13.55), no confirme a criao da Interface.
366 Delphi 7 Internet e Banco de Dados Unit WebModule Projeto un_ws4.PAS ws4.DPR
Agora vamos inserir um SOAP Data Module em nossa aplicao. Atravs das opes File/New..WebServices, selecione a opo SOAP Server Data Module (figura 13.56), e em seguida pressione OK.
Figura 13.56 Soap Server Data Module Em seguida (figura 13.57) informe o nome do nosso Soap Server Data Module, como ws4dm.
Figura 13.57 Module Name Grave a unit como un_ws4_dm.pas. Insira um objeto do tipo TSQLConnection. Atravs do duplo-clique, j na tela de configurao, aponte para a nossa conexo Clientes, criada anteriormente. Vamos relembrar os atributos da conexo. PROPRIEDADE VALOR
Figura 13.58 Configurao da Conexo Agora vamos inserir o objeto para manipular nossa tabela de clientes. Insira um objeto do tipo TSQLDataSet, e altere as seguintes propriedades: PROPRIEDADE VALOR
Insira um objeto do tipo TDataSetProvider para fornecer os dados de nosso DataSet a qualquer cliente conectado em nossa aplicao. PROPRIEDADE VALOR
DataSet Name
SQLClientes DataSetProvider1
Antes de compilar, vamos definir o diretrio para gerao do nosso WebService. Atravs das opes Project/Options.../Directories_Conditionals, configure a opo Output Directory, apontando para o seu diretrio cgi-bin (figura 13.59).
Figura 13.59 Configurao do diretrio Grave e compile a aplicao. Agora vamos construir nossa aplicao Client. Atravs das opes File/New Application crie uma nova aplicao e grave os arquivos como segue: Unit Projeto un_teste_ws4.PAS teste_ws4.DPR
Agora insira um objeto do tipo TSOAPConnection e altere as propriedades que seguem: PROPRIEDADE VALOR
Perceba que estamos utilizando o mtodo SOAP do nosso WebService. Agora, insira um objeto do tipo TClientDataSet e altere as seguintes propriedades. PROPRIEDADE VALOR
Atravs do duplo-clique no objeto ClientDataSet1, insira os campos, como ilustra a figura 13.60.
WebServices 369
Figura 13.60 Campos do ClientDataSet1 Agora, selecione todos os campos e arraste para o formulrio, dimensionando como sugere a figura 13.61.
Figura 13.61 Formulrio exemplo Com a propriedade Active do ClientDataSet1 configurada como True, execute a aplicao e veja o resultado (figura 13.62).
Figura 13.62 Aplicao em execuo Amigos, com isso conclumos nosso captulo de WebServices.
WebServices 371 ClientDataSet1EMAIL: TStringField; Label1: TLabel; DBEdit1: TDBEdit; DataSource1: TDataSource; Label2: TLabel; DBEdit2: TDBEdit; Label3: TLabel; DBEdit3: TDBEdit; Label4: TLabel; DBEdit4: TDBEdit; Label5: TLabel; DBEdit5: TDBEdit; Label6: TLabel; DBEdit6: TDBEdit; Label7: TLabel; DBEdit7: TDBEdit; DBNavigator1: TDBNavigator; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} end.
Anotaes de Dvidas
?
Preciso Revisar
Anotaes Gerais