异构:Delphi7 WebBrowser 调用 Struts2 Action

标题:Delphi7 WebBrowser + Struts2 Action

作者:JRQ

正文:

使用Delphi7 WebBrowser客户端调用服务器Struts2 Action,并向服务端传递相关参数。

算是针对异构系统做简单集成的一个测试。

简要记之。

一、客户端WebBrowser以HTTP POST方式调用Action并传递参数

客户端Post方法一:

procedure WebNavigate1(sURL, sPostData: String; var wbWebBrowser: TWebBrowser);

var

vWebAddr, vPostData, vFlags, vFrame, vHeaders: OleVariant;

i: Integer;

begin

if Length(sPostData)> 0 then

begin

//头信息

vHeaders:= 'Content-Type:application/x-www-form-urlencoded'+ #10#13#0;

//创建二进制参数

vPostData:= VarArrayCreate([0, Length(sPostData)], varByte);

for i := 0 to Length(sPostData)-1 do

begin

vPostData[i]:= Ord(sPostData[i+1]);

end;

//结束字符

vPostData[Length(sPostData)]:= 0;

//Set the type of Variant

//TVarData(vPostData).vType:= varArray; //注释此句。否则类型错误。

end;

vWebAddr:= sURL;

wbWebBrowser.Navigate2(vWebAddr,vFlags,vFrame, vPostData, vHeaders);

//wbWebBrowser.Navigate(vWebAddr, EmptyParam, EmptyParam, vPostData, vHeaders);

end;

客户端Post方法二:

procedure WebNavigate2(sURL, sPostData: String; var wbWebBrowser: TWebBrowser);

var PostData,Headers: OleVariant;

i: Integer;

begin

//创建字节方式的可变变量数组,并将字符串转换之。

PostData := VarArrayCreate([0, Length(sPostData) - 1], varByte);

for i := 1 to Length(sPostData) do

begin

PostData[i-1] := Ord(sPostData[i]);

end;

//头类型

Headers := 'Content-Type: application/x-www-form-urlencoded' + #10#13;

//提交

wbWebBrowser.Navigate(sURL, EmptyParam, EmptyParam, PostData, Headers);

end;

客户端WebBrowser调用方法:

uses HttpApp;

var aURL, aPostData: String;

begin

//Post方法一

aURL:='http://127.0.0.1:8088/test/loginAction.action' ;

aPostData:='UserCode=abc&PassWord=abc';

//aPostData:='UserCode='+HTTPEncode('用户名')+'&PassWord=abc';

WebNavigate1(aURL,aPostData,WebBrowser1);

//Post方法二

aURL:= 'http://127.0.0.1:8088/test/testAction.action';

aPostData := 'ParaCode='+HTTPEncode('测试')+'&ParaNumb=123';

WebNavigate2(aURL,aPostData,WebBrowser1);

end;

服务器Action得到参数:

String pUserCode = request.getParameter("UserCode").toString();

String pPassWord = request.getParameter("PassWord").toString();

String pParaCode = request.getParameter("ParaCode").toString();

String pParaNumb = request.getParameter("ParaNumb").toString();

说明:

TWebBrowser有多个重载方法Navigate(),在此使用的Navigate()方法原型如下:

procedure TWebBrowser.Navigate(const URL: WideString; var Flags: OleVariant;

var TargetFrameName: OleVariant; var PostData: OleVariant;

var Headers: OleVariant);

begin

DefaultInterface.Navigate(URL, Flags, TargetFrameName, PostData, Headers);

end;

关于Navigate(),帮助中有如下说明:

-----------------------

Use Navigate to locate and download a specific resource.

Navigate can send an HTTP message to a specified URL and display the results or simply display the results of a specified file.

PostData contains the data sent to the server when using Navigate to generate an HTTP POST message.

If PostData is NULL, Navigate generates an HTTP GET message.

PostData is ignored if URL does not specify an HTTP URL.

-----------------------

如果Navigate()方法使用了PostData参数,则是HTTP POST方式的。如果没有PostData参数,则是HTTP GET方式。

Post方式传递的参数在客户端需要做二进制编码。并设置了Http的头信息。

另外,如果PostData中传递的是中文参数,客户端则需要用uses HttpApp单元,使用HTTPEncode()对中文参数编码,然后再做二进制编码。

客户端可以在WebBrowser的BeforeNavigate2()事件中捕获Post的参数,如下所示:

procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;

const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,

Headers: OleVariant; var Cancel: WordBool);

var

i, nLen: Integer;

vPostData: OleVariant;

szData: string;

begin

//解开PostData参数

vPostData := PostData;

if VarIsArray(vPostData, True) then

begin

nLen := VarArrayHighBound(vPostData, 1) - VarArrayLowBound(vPostData, 1) + 1;

SetLength(szData, nLen);

for i := 0 to nLen - 1 do

begin

szData[i + 1] := Chr(Byte(vPostData[VarArrayLowBound(vPostData, 1) + i]));

end;

Application.MessageBox(PChar('PostData is : '+ szData),'测试');

end;

end;

二、客户端WebBrowser以HTTP Get方式调用Action并传递参数

客户端WebBrowser以GET方式发送请求:

uses HttpApp;

var aURL:String;

begin

aURL:= 'http://127.0.0.1:8088/test/loginAction.action?UserCode=abc&PassWord=abc';

WebBrowser1.Navigate(aURL);

aURL:= 'http://127.0.0.1:8088/test/testAction.action?ParaCode='+HTTPEncode('测试')+'&ParaNumb=123';

WebBrowser1.Navigate(aURL);

end;

服务器Action得到参数:

String pUserCode = request.getParameter("UserCode").toString();

String pPassWord = request.getParameter("PassWord").toString();

String pParaCode = new String(request.getParameter("ParaCode").getBytes("ISO8859_1")); //中文参数编码转换

String pParaNumb = request.getParameter("ParaNumb").toString();

说明:

客户端的WebBrowser的方法Navigate()只使用了一个参数:URL。该URL中包含了向服务器Action提交的参数。

Navigate()方法中没有使用PostData参数,使用的是HTTP GET方式请求。

此处客户端WebBrowser使用的Navigate()方法原型如下:

procedure TWebBrowser.Navigate(const URL: WideString);

begin

DefaultInterface.Navigate(URL, EmptyParam, EmptyParam, EmptyParam, EmptyParam);

end;

如果URL中包含中文参数,则需要用HTTPEncode()函数对中文参数编码。

同时,服务器Action中需要对该参数做编码转换。

三、一点想法

1.关于安全性:

针对此案例,使用POST比GET方式更为安全。因为POST方式不会在URL中暴露所传递的参数内容。

2.关于系统集成:

针对此案例,可以应用到多个异构系统的集成中,包括单点登录的实现、远程桌面集成访问等等。 ^_^

[--完--]

by JRQ

2009/05/23 于 京