首先利用vs来开发服务端:
第一步,打开Visual Studio新建一个win32控制台应用程序项目,名为login。
第二步,建立一个名为ifun的头文件,在这个文件里设计出服务端可供客服端调用的函数的函数头,其内容如下:
/**********************************************************************************************
编写头文件的几种特殊情况的处理已经注意点
1.所有的接口函数的名字必须以ns__开头
2.最后一个参数必须以指针或者引用的方式传递,作为客户端的返回值
3.需要传递的参数类型是一个结构体的时候,必须先要定义一个结构体 ,而且结构体的名字必须以ns__开头
4.当没有传入参数的时候参数类型定义为 void* 即可
***********************************************************************************************/
//登录接口
int ns__Login(char* strUserID, char* strPwd, wchar_t*& iLoginInfo);
//增加账户
int ns__Addid(char* strUserID, char* strPwd,wchar_t*& iLoginInfo);
//删除账户
int ns__Deleteid(char* strUserID, char* strPwd,wchar_t*& iLoginInfo);
//修改账户
int ns__Modifyid(char* strUserID, char* strPwd, wchar_t*& iLoginInfo);
第三步,通过gsoap工具把ifun.h头文件自动生成一些与soap服务有关的文件。其具体步骤如下:
1,在D盘下新建一个名为gsoap的文件,将ifun.h头文件复制进来
2,打开gsoap工具的目录,例如:D:\我的文档\Visual Studio 2005\gsoap-2.8\gsoap\bin\win32
3,打开doc命令,将工作目录改为D:/gsoap>再键入如下命令:
"D:\我的文档\Visual Studio 2005\gsoap-2.8\gsoap\bin\win32\soapcpp2.exe" -i -S ifun.h再敲击回车
其生成视图为:
第四步,将这些自动生成的文件以及gsoap工具目录下的stdsoap2.h,stdsoap2.cpp文件添加进login项目,其中ns.wsdl放到debug文件夹下
第五步,继续编辑gsoap.cpp文件,在此文件的末尾编辑ifun.h文件中声明的函数的实现,实现的代码如下:
int Service::Login(char *strUserID, char *strPwd,wchar_t*& StrLoginInfo)
{
_RecordsetPtr login_RecordSetPtr;
CString userID;
CString userPWD;
CString userName;
CString LoginInfo;
CString strSQL;
char* strReturnBuffer;
static wchar_t WcharBuffer[WCHAR_MAX];
memset(WcharBuffer,0,WCHAR_MAX);
wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
strSQL.Format("select * from login where myname = '%s'",strUserID);
g_DataBase.IfOpenRecordset(login_RecordSetPtr);
login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
if(login_RecordSetPtr->adoEOF)
{
LoginInfo = Login_uderID_err;
strReturnBuffer = LoginInfo.GetBuffer(LoginInfo.GetLength());
LoginInfo.ReleaseBuffer();
MBToWCHAR(wchar_tArray,strReturnBuffer,strlen(strReturnBuffer));
StrLoginInfo = (wchar_t*)wchar_tArray;
LoginInfo = Login_userPwd_err;
return SOAP_OK;
}
else
{
strSQL.Format("select * from login where myname = '%s'and myage='%s'",strUserID,strPwd);
g_DataBase.IfOpenRecordset(login_RecordSetPtr);
login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
if (login_RecordSetPtr->adoEOF)
{
LoginInfo = Login_userPwd_err;
}
else
{
LoginInfo.Format("%s",strUserID);
}
}
strReturnBuffer = LoginInfo.GetBuffer(LoginInfo.GetLength());
MBToWCHAR(wchar_tArray,strReturnBuffer,strlen(strReturnBuffer));
LoginInfo.ReleaseBuffer();
StrLoginInfo = (wchar_t*)wchar_tArray;
g_DataBase.CloseRecordset(login_RecordSetPtr);
return SOAP_OK;
}
int Service::Addid(char *strUserID, char *strPwd, wchar_t *&iLoginInfo)
{
_RecordsetPtr login_RecordSetPtr;
CString userID;
CString userPWD;
CString userName;
CString LoginInfo;
CString strSQL;
static wchar_t WcharBuffer[WCHAR_MAX];
memset(WcharBuffer,0,WCHAR_MAX);
wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
strSQL.Format("insert into login (myname,myage) values ('%s','%s')",strUserID,strPwd);
g_DataBase.IfOpenRecordset(login_RecordSetPtr);
login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
MBToWCHAR(wchar_tArray, "添加成功", strlen("添加成功"));
iLoginInfo = (wchar_t*)wchar_tArray;
g_DataBase.CloseRecordset(login_RecordSetPtr);
return SOAP_OK;
}
int Service::Deleteid(char *strUserID, char *strPwd,wchar_t *&iLoginInfo)
{
_RecordsetPtr login_RecordSetPtr;
CString userID;
CString userPWD;
CString userName;
CString LoginInfo;
CString strSQL;
char* strReturnBuffer;
static wchar_t WcharBuffer[WCHAR_MAX];
memset(WcharBuffer,0,WCHAR_MAX);
wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
strSQL.Format("select * from login where myname = '%s'",strUserID);
g_DataBase.IfOpenRecordset(login_RecordSetPtr);
login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
if (login_RecordSetPtr->adoEOF)
{
LoginInfo = Login_uderID_err;
strReturnBuffer = LoginInfo.GetBuffer(LoginInfo.GetLength());
LoginInfo.ReleaseBuffer();
MBToWCHAR(wchar_tArray,strReturnBuffer,strlen(strReturnBuffer));
iLoginInfo = (wchar_t*)wchar_tArray;
}
else
{
strSQL.Format("delete from login where myname = '%s'",strUserID);
g_DataBase.IfOpenRecordset(login_RecordSetPtr);
login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
MBToWCHAR(wchar_tArray, "删除成功", strlen("删除成功"));
iLoginInfo = (wchar_t*)wchar_tArray;
}
g_DataBase.CloseRecordset(login_RecordSetPtr);
return SOAP_OK;
}
int Service::Modifyid(char *strUserID, char *strPwd, wchar_t *&iLoginInfo)
{
_RecordsetPtr login_RecordSetPtr;
CString userID;
CString userPWD;
CString userName;
CString LoginInfo;
CString strSQL;
static wchar_t WcharBuffer[WCHAR_MAX];
memset(WcharBuffer,0,WCHAR_MAX);
wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
strSQL.Format("update login set myage='%s' where myname = '%s'",strPwd, strUserID);
g_DataBase.IfOpenRecordset(login_RecordSetPtr);
login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
MBToWCHAR(wchar_tArray, "修改成功", strlen("修改成功"));
iLoginInfo = (wchar_t*)wchar_tArray;
g_DataBase.CloseRecordset(login_RecordSetPtr);
return SOAP_OK;
}
第六步,在login项目里加入头文件:CharConVert.h,Database.h,MailSender.h,Markup.h,PublicFunction.h以及源文件Markup.cpp,PublicFunction.cpp
第七步,编写stdafx.h文件以及主文件login.cpp其中主文件的内容如下:
// login.cpp : 定义控制台应用程序的入口点。
//
#include <vector>
#include "stdafx.h"
#include "Database.h"
#include "soapService.h"
#include "ns.nsmap"
#include "Markup.h"
#include "PublicFunction.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include "MailSender.h"
#define PER_MINUTE (60000)
using namespace std;
int http_get(struct soap * soap);
CDataBase g_DataBase;
int _tmain(int argc, _TCHAR* argv[])
{
//连接数据库
if(!g_DataBase.OpenDatabase())
{
return 1;
}
Service calc;
calc.imode |= SOAP_C_UTFSTRING;
calc.omode |= SOAP_C_MBSTRING;
calc.fget = http_get;
if (!(argc < 2))
{
// serve as CGI application
calc.serve();
calc.destroy();
}
if (calc.run(9999))
{
calc.soap_stream_fault(std::cerr);
exit(-1);
}
return 0;
}
//能够远程读取wsdl文件
int http_get(struct soap * soap)
{
if (0 != strcmp(soap->path, "/ns.wsdl"))
{
return SOAP_GET_METHOD;
}
//读取硬盘wsdl文件
CString cstrWsdlName = CPublicFunction::GetWsdlName();
CString cstrWsdlPath = CPublicFunction::GetWsdlPath();
CString cstrWsdl = cstrWsdlPath + cstrWsdlName;
CMarkup xmlWsdl;
string strWsdl;
if(xmlWsdl.Load(cstrWsdl))
{
strWsdl = xmlWsdl.GetDoc();
cout << strWsdl.c_str() <<endl;
}
soap->http_content = "xml";
soap_response(soap, SOAP_FILE);
soap_send_raw(soap, strWsdl.c_str(), strWsdl.length());
soap_end_send(soap);
return SOAP_OK;
}
第八步,编译纠错,在login的属性页里加入预处理器定义:_AFXDLL,更改字符集为未设置,直到编译成功,服务端便完成了
最后通过flash builder开发客户端,其步骤如下:
第一步,打开flash builder,新建一个桌面应用程序项目,名也为login
第二步,在主文件里的设计视图中建立如下界面
第三步,进入源代码视图进行设计,代码为
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:zp="zp.*"
xmlns:ns1="*"
width="800" height="385" accentColor="#0DA5BB"
applicationComplete="windowedapplication1_applicationCompleteHandler(event)"
backgroundColor="#D2F4F4" chromeColor="#4CEA1C">
<fx:Style source="login.css"/>
<fx:Script>
<![CDATA[
import ServiceManage.WebService.GService;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.soap.LoadEvent;
import mx.rpc.soap.WebService;
private var m_gSer:GService;
private var m_webser:WebService;
private var dkck:spark.components.WindowedApplication;
public function OnRes(res:ResultEvent):void
{
Alert.show("OnRes");
}
protected function dl_clickHandler(event:MouseEvent):void
{
m_webser.Login.addEventListener(ResultEvent.RESULT, OnLoginSuccess);
m_webser.Login.addEventListener(FaultEvent.FAULT, OnLoginFault);
m_webser.Login(sr1.text, sr2.text);
}
protected function jz_clickHandler(event:MouseEvent):void
{
m_webser.wsdl = "http://192.168.1.101:9999/ns.wsdl";
m_webser.addEventListener(ResultEvent.RESULT, OnRes);
m_webser.addEventListener(FaultEvent.FAULT, OnFault);
m_webser.addEventListener(LoadEvent.LOAD, OnLoadWsdlSuccess);
m_webser.loadWSDL();
}
protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void
{
m_webser = new WebService;
jz_clickHandler(null);
}
public function OnLoadWsdlSuccess(e:LoadEvent):void
{
trace("-------OnLoadWsdlSuccess--------");
Alert.show("OnLoadWsdlSuccess");
}
public function OnFault(evt:FaultEvent):void
{
trace("-------OnLoadWsdlFault--------");
Alert.show("OnLoadWsdlFault");
}
public function OnLoginSuccess(eve:ResultEvent):void
{
Alert.show(eve.result.toString());
ck.enabled=true
}
public function OnLoginFault(eve:FaultEvent):void
{
Alert.show(eve.toString());
}
protected function qx_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
close();
}
protected function zj_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
m_webser.Addid.addEventListener(ResultEvent.RESULT, OnAddidSuccess);
m_webser.Addid.addEventListener(FaultEvent.FAULT, OnAddidFault);
m_webser.Addid(sr3.text, sr4.text);
}
public function OnAddidSuccess(eve:ResultEvent):void
{
Alert.show(eve.result.toString());
}
public function OnAddidFault(eve:FaultEvent):void
{
Alert.show(eve.toString());
}
protected function sc_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
m_webser.Deleteid.addEventListener(ResultEvent.RESULT, OnDeleteidSuccess);
m_webser.Deleteid.addEventListener(FaultEvent.FAULT, OnDeleteidFault);
m_webser.Deleteid(sr3.text, sr4.text);
}
public function OnDeleteidSuccess(eve:ResultEvent):void
{
Alert.show(eve.result.toString());
}
public function OnDeleteidFault(eve:FaultEvent):void
{
Alert.show(eve.toString());
}
protected function xg_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
m_webser.Modifyid.addEventListener(ResultEvent.RESULT, OnModifyidSuccess);
m_webser.Modifyid.addEventListener(FaultEvent.FAULT, OnModifyidFault);
m_webser.Modifyid(sr3.text, sr4.text);
}
public function OnModifyidSuccess(eve:ResultEvent):void
{
Alert.show(eve.result.toString());
}
public function OnModifyidFault(eve:FaultEvent):void
{
Alert.show(eve.toString());
}
]]>
</fx:Script>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<s:HGroup x="10" y="85" width="288" height="46" gap="20" horizontalAlign="center">
<s:Button id="dl" label="登陆" click="dl_clickHandler(event)"/>
<s:Button id="qx" label="取消" click="qx_clickHandler(event)"/>
<s:Button id="jz" height="21" label="加载" click="jz_clickHandler(event)"/>
</s:HGroup>
<s:VGroup x="6" y="28" width="80" height="45">
<s:Label width="77" height="23" text="用户名:"/>
<s:Label width="77" height="21" text="密码:"/>
</s:VGroup>
<s:VGroup x="60" y="28" width="130" height="53">
<s:TextInput id="sr1"/>
<s:TextInput id="sr2"/>
</s:VGroup>
<s:TitleWindow id="ck" x="352" y="101" width="375" height="256" enabled="false" title="账户管理">
<s:HGroup x="6" y="3" width="200" height="27">
<s:Label width="72" height="26" text="当前账户:"/>
</s:HGroup>
<s:VGroup x="6" y="38" width="68" height="77">
<s:Button id="zj" label="增加账户" click="zj_clickHandler(event)"/>
<s:Button id="xg" label="修改账户" click="xg_clickHandler(event)"/>
<s:Button id="sc" label="删除账户" click="sc_clickHandler(event)"/>
</s:VGroup>
<s:Label x="10" y="135" width="76" height="19" text="账户名:"/>
<s:Label x="10" y="158" width="82" height="19" text="密码:"/>
<s:Image x="82" y="0" width="291" height="213" source="assets/00.jpg"/>
<s:Label id="bj" x="88" y="3" width="77" height="26" text="{sr1.text}"/>
<s:TextInput id="sr3" x="65" y="128"/>
<s:TextInput id="sr4" x="65" y="158"/>
</s:TitleWindow>
</s:WindowedApplication>
第四步,先运行先前编写好的服务端程序,再运行客户端进行测试,其结果如下:
到此时简单的登录系统便做成了,需要说明的是本系统的开发需要SQL2008数据库管理系统的支持。