segunda-feira, 24 de agosto de 2009

Delphi - Intraweb: Passar e recuperar parâmetros entre requisições HTTP

Inicie uma aplicação Intraweb no Delphi. O Assunto é sobre passar, e recuperar, parâmetros entre requisições HTTP. Especificamente, pretendo exemplificar como chamar uma outra aplicação web, sendo que nesta chamada passaremos parâmetros, os quais, obviamente, serão recuperados e processados pela aplicação que foi requisitada.


Neste artigo criaremos duas aplicações Intraweb ISAPI. Um delas (“AppEstacaoZNSubmit”) servirá para passar parâmetros para outra (“AppRequestQueryFieldsEstacaoZN”). Esta segunda por sua vez, recupera os valores destes parâmetros processa e os exibe.
Ok, definido o que pretendemos fazer passamos agora a parte prática.

A seguir o código fonte da aplicação ISAPI que chama e passa os parâmetros. Salvei essa app de com o nome “AppEstacaoZNSubmit”.

O Form principal e único desta aplicação “IWUnit1.pas”:

unit IWUnit1;
{PUBDIST}

interface

uses
IWAppForm, IWApplication, IWTypes, IWCompButton, Classes, Controls,
IWControl, IWCompEdit, IWCompLabel;

type
TformMain = class(TIWAppForm)
IWEdit1: TIWEdit;
IWButton1: TIWButton;
IWLabel1: TIWLabel;
EdtURLZN: TIWEdit;
IWLabel2: TIWLabel;
procedure IWAppFormCreate(Sender: TObject);
procedure IWButton1Click(Sender: TObject);
public
end;

implementation
{$R *.dfm}

uses
ServerController, SysUtils, IWForm;

procedure TformMain.IWAppFormCreate(Sender: TObject);
begin
IWEdit1.Text := '';
IWButton1.Caption := 'Enviar - ZN';
IWLabel1.Caption := 'Digite o valor que será enviado';
IWLabel2.Caption := 'Digite a URL da aplicação ISAPI que será chamada' +
'e exibirá o valor digitado acima.';
EdtURLZN.Text := '';
end;

procedure TformMain.IWButton1Click(Sender: TObject);
const
AJSComando = 'window.open("%s?estacaoZnValor=%s")';
begin
AddToInitProc(Format(AJSComando, [EdtURLZN.Text, IWEdit1.Text]));
end;

end.


Em seguida o “.dpr”:

library AppEstacaoZNSubmit;

uses
IWInitISAPI,
ServerController in 'ServerController.pas' {IWServerController: TIWServerControllerBase},
IWUnit1 in 'IWUnit1.pas' {formMain: TIWForm1};

{$R *.RES}

begin
IWRun(TFormMain, TIWServerController);
end.


Não editei nada no “IWServerController”, portanto após compilar e efetuar o deploy da “AppEstacaoZNSubmit.dll” no IIS damos por encerrada esta etapa do nosso exemplo.


O próximo passo é codificar a segunda aplicação. Logo, novamente inicie um novo projeto Intraweb ISAPI, salve com o nome de “AppRequestQueryFieldsEstacaoZN”. No evento “OnRender” do IWForm1 implementaremos o que especificamos anteriormente. Abaixo, o fonte da IWUnit1.pas:

unit IWUnit1;
{PUBDIST}

interface

uses
IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl,
IWCompLabel, IWCompListbox, IWCompMemo;

type
TformMain = class(TIWAppForm)
IWLabel1: TIWLabel;
procedure IWAppFormRender(Sender: TObject);
public
end;

implementation
{$R *.dfm}

uses
ServerController, IWForm, SysUtils;

procedure TformMain.IWAppFormRender(Sender: TObject);
const
ZnMsg = 'www.estacaozn.blogspot.com O Valor recebido de "%s" é: %s';
begin
IWLabel1.Caption := Format(ZnMsg,
[WebApplication.Request.RemoteAddr,
WebApplication.Request.QueryFields.Values['estacaoZnValor']]);
IWLabel1.Font.Size := 20;
end;


Vejamos o “.dpr” da “AppRequestQueryFieldsEstacaoZN.dpr”.


library AppRequestQueryFieldsEstacaoZN;

uses
IWInitISAPI,
ServerController in 'ServerController.pas' {IWServerController: TIWServerControllerBase},
IWUnit1 in 'IWUnit1.pas' {formMain: TIWForm1};

{$R *.RES}

begin
IWRun(TFormMain, TIWServerController);
end.


Após proceder a implementação deste módulo conforme ilustrado acima, semelhante ao exemplo anterior compile e efetue o deploy da “AppRequestQueryFieldsEstacaoZN.dll” no ISS.
Feito isso já é possível testar. No browser, chame o diretório virtual definido no deploy da primeira aplicação (AppEstacaoZNSubmit.dll).




Digite no “IWEdit1” o valor para parâmetro “estacaoZnValor”, o qual será exibido. Digite também a URL da segunda aplicação no “EdtURLZN”, para somente então clicar no IWButton1.






Na primeira aplicação, no evento OnClick do IWButton1, chamamos o método “AddToInitProc” de “TformMain”. Este método nos permite “colocar” scripts (Javascript) que serão executados quando a função “Initialize()" padronizada pelo framework Intraweb, quando o browser estiver interpretando a tag “body”, da página construída pelo Intraweb. No body onload é definida a chamada a função “Initialize()".





function Initialize() {
InitSubmitter();
StaticInit();
if (document.body.leftMargin < 0 && document.body.topMargin < 0) {
document.body.leftMargin = 0;
document.body.topMargin = 0;
}
InitRects(614, 451);
InitIWCLObjects();

window.open("http://localhost/requesestacaozn/?estacaoZnValor=Landjah Estação ZN")
}



Então, podemos concluir que, no Intraweb quando você precisar executar uma função qualquer no evento “onload” no body basta para isso passá-la como parâmetro no método “AddToInitProc” do TIWForm em questão.

Na segunda aplicação, “AppEstacaoZNSubmit”, o comando
"WebApplication.Request.QueryFields.Values" pode ser entendido da mesma forma que o Webbrocker trabalha com o protocolo http.
Podemos também recuperas outras variáveis através do objeto “WebApplication”, sua propriedade “Request”, tais como o “RemoteHost”, “UserAgent” e etc..

Por hora é só .... Até a próx!!!


Artigo completo (View Full Post)

JSP e Oracle - Para apresentar uma Treeview

Olá pessoal!

Dando manutenção em um sistema java web com interface jsp precisei usar uma treeview para apresentar as categorias de produtos para o usuário. Vou relatar aqui a experiência.


As categorias estão modeladas no banco em uma tabela com autorelacionamento.



No oracle para consultar uma table com autorelacionamento podemos utilizar a seguinte query:


select id, LEVEL, SYS_CONNECT_BY_PATH(nome, '@') as caminho
from categoria CONNECT BY parent_id = PRIOR id START WITH id = categoria_inicial


A categoria_inicial é a primeira categoria de uma árvore, nesse sistemas existem várias árvores de categorias.

O resultado fica assim para a categoria_inicial igual a 30:

id level caminho
30 1 @Material de escritório
31 2 @Material de escritório@Informática
34 3 @Material de escritório@Informática@Tinta
55 4 @Material de escritório@Informática@Tinta@Tinta Impressoras
60 3 @Material de escritório@Informática@Armazenamento
63 4 @Material de escritório@Informática@Armazenamento@DAT/DLT/DVD/DDS
64 4 @Material de escritório@Informática@Armazenamento@Disquetes
92 3 @Material de escritório@Informática@Teste
93 4 @Material de escritório@Informática@Teste@Teste1
113 4 @Material de escritório@Informática@Teste@Teste2
120 4 @Material de escritório@Informática@Teste@Test3

Ai no java criei uma classe para representar a estrutura da categoria, ficou assim:

public class CategoriaTreeView {
public String id;
public int level;
public String path;

public CategoriaTreeView(String id, int level, String path){
this.id = id;
this.level = level;
this.path = path;
}
}


Como essa classe vai ser utilizada somente como uma estrutura de dados para representar o dado que será exibido na tela ela não tem gets e sets. Nem toda classe java precisa ter gets e sets. Gets e sets aqui são desnecessários e não acresentam nada. Acredite. Mas isso é assunto para outro post.

Também tenho um DAO que acessa o banco e entrega um List com os objetos CategoriaTreeView.

Antes disso fiz uma pesquisa na internet sobre como criar uma treeview no jsp (ou html) e encontrei o jQuery plugin: Treeview que transforma uma lista não ordenada do html <ul> em uma árvore.

Agora o problema é transformar a minha coleção de CategoriaTreeView em uma lista não ordenada com <ul> e <li>. Para isso eu criei a seguinte função recursiva que retorna uma String que será utilizada dentro do html:


private String processa(int atual, List<CategoriaTreeView> lista){
if(lista == null) return "";
String out = "";
if(lista.size() == 0) {
if(atual > 0){
out += "</li>\n";
out += "</ul>\n";
out += processa(atual - 1, lista);
}
}else if(lista.size()>0){
CategoriaTreeView item = lista.remove(0);
if(item.level == atual){
out += "</li>\n";
out += "<li><span>" + subString(item.level, item.path) + "</span>\n";
out += processa(item.level, lista);
}else if(item.level > atual){
out += "<ul>\n";
out += "<li><span>" + subString(item.level, item.path) + "</span>\n";
out += processa(item.level, lista);
}else if(item.level < atual){
out += "</li>\n";
out += "</ul>\n";
// adiciono o cara de volta na lista pois ainda não foi processado. estou voltando um nivel na árvore.
lista.add(0, item);
out += processa(atual - 1, lista);
}
}
return out;
}

Também temos a função para retornar a categoria de dentro do caminho:


private String subString(int i, String s){
String[] ss = s.split("@");
return ss[i];
}


Dentro do meu servlet eu tenho o seguinte código:

ArrayList categorias = dao.categorias(categoria_inicial);
String treeView = processa(0, categorias);
treeView = treeView.replaceFirst("<ul>", "<ul id=\"browser\">");
request.setAttribute("treeView", treeView);

Para exibir a treeview no jsp eu utilizei o exemplo simple.html que vem no download do jQuery plugin: Treeview. A única mudança foi que eu fiz o download do jquery ao invés de usar o link direto do ajax.googleapis.com.

Adicionei o seguinte ao jsp:


<link rel="stylesheet" href="../jquery.treeview.css" />
<link rel="stylesheet" href="../red-treeview.css" />
<link rel="stylesheet" href="screen.css" />

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script src="../lib/jquery.cookie.js" type="text/javascript"></script>
<script src="../jquery.treeview.js" type="text/javascript"></script>

<script type="text/javascript">
$(document).ready(function(){
$("#browser").treeview({control: "#treecontrol", animated:"normal", persist: "cookie"});
});
</script>

<%
String s = (String)request.getAttribute("treeView");
if(s != null && !s.trim().equals("")){
%>
<tr>
<td>
<br>
<div id="treecontrol">
<a title="Collapse the entire tree below" href="#">Fechar Tudo</a>
<a title="Expand the entire tree below" href="#">Abrir Tudo</a>
</div>

</td>
</tr>
<tr>
<td>
<br>
<div><%= s %></div>
</td>
</tr>
<%
}
%>


O resultado fica parecido com esse demo que está no site.



Abraços, Rodrigo Alencar.

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br