xml地图|网站地图|网站标签 [设为首页] [加入收藏]
session以及认证系统,多层返回数据集分析FireDA
分类:编程

采用服务器返回数据,一种是返回字符串数据例如JSON,跨平台跨语言,任何语言调用都支持兼容,类似WEBService。

一,C#是什么?

COOKIE&SESSION

第二种是紧密结合c++builder语言,传输DataSet,可以是ClientDataSet,也可以是FDMemTable,或TDataSet,这类好处是DataSet本身包含了很多属性,记录集的状态Insert/Modify/Delete,在服务端可以调用

人与人之间可以用语言进行交流,我们和计算机交流也是通过语言。我们可以通过语言让一个人做一件我们想让他做事情(他愿意的话~),我们能不能让计算机按照我们的意愿来做事情呢?比如我们让计算机进行数学运算,播放歌曲,显示特定的画面等等。人类设计计

知识储备

  由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。

  cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

  cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。

  问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。

  我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。

  总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本

不同的方法进行数据处理,客户端也只需要把dataset对象赋值就展示到dbgrid里了。

C#就是种类繁多的计算机语言的一种,只要我们按照计算机能够理解的规则来设计我们的指令,计算机就可以做它能做到的任何事情。

Django实现COOKIE

序列化。

学习一门计算机语言就是学习它的规则。

设置cookie

obj = HttpResponse(...) 或 obj= render(request, ...) 或 obj= redirect()
obj.set_cookie(key,value,...)
obj.set_signed_cookie(key,value,salt='加密盐',...)

 

FDMemTable1有saveToFile(sfJson),虽然是json格式,但不能跨语言交流,只能fdMem.LoadFromFile才可解析。所以用这个json字符串是不通用的,只能RAD delphi/c++使用。

二、二进制

获取cookie

request.COOKIES.get('key')
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

计算机作为一种机器其实很单纯,它只能识别0和1两种状态,这是一种机器语言。计算语言的发展经过了机器语言,汇编语言,高级语言的过程。我们学习的各种高级语言都需要经过编译,转换成机器语言计算机才能一步步执行,这就涉及到二进制的概念。十进制逢十进一:0,1,2,3,4,5,6,7,8,9,10,11,12,...;二进制逢二进一:0,1,10,11,100,101,110,111,...;二进制和十进制可以相互转换。

删除cookie

response.delete_cookie("cookie_key",path="/",domain=name)

 

十进制转二进制:

参数

key,                 键
value='',            值
max_age=None,        超长时间
expires=None,        超长时间
path='/',           Cookie生效的路径,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
domain=None,         Cookie生效的域名你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读www.example.com 、 www2.example.com 
和an.other.sub.domain.example.com 。
如果该参数设置为 None ,cookie只能由设置它的站点读取。

secure=False,        如果设置为 True ,浏览器将通过HTTPS来回传cookie。
httponly=False       只能http协议传输,无法被JavaScript获取
                                         (不是绝对,底层抓包可以获取到也可以被覆盖

图片 1图片 2

$.cookie("key", value,{ path: '/' })

jquery操作cookie

一、跨平台纯字符串

 

Tokyo 10.2.2有了TFDBatchMoveJSONWriter

 

对返回的数据增删改查。对应的方法就是Add/Delete/Update/Query,客户端调用此方法就OK了。

数据集转换依赖于TDBXReader、TDBXCommand、SQLConnection1。不能随意转换dataset为json。有个第三方的库可以转。

Serever

String GetPersonAll()

{

return "";字符串形式的JSON或XML格式

aReader:=aCommand``.``ExecuteQuery;

`Result:=TDBXJSONTools.TableToJSON(aReader,10,True`).ToString;

}

Client

String DataSTR=srv->GetPersonAll();

对字符串解析JSON或XML,以DataSet展示就可以。

function TServerMethods1.GetData(SQL: String): String;
var
  aCommand: TDBXCommand;
  aReader: TDBXReader;
begin
  Result := '';
  aCommand := SQLConnection1.DBXConnection.CreateCommand; // 指定 SQLConnection1 连接数据库
  try
    aCommand.Text := SQL; // 指定SQL语句
    aReader := aCommand.ExecuteQuery;
    Result := TDBXJSONTools.TableToJSON(aReader, 10, True).ToString;
  finally
    aCommand.Free;
  end;
end;

 

 用第三方库SuperJson也可以。

方法:十进制数除以16,商继续除以16直到商为0,每次余数由8,4,2,1中的几个求和可得,则8这几个数对应的位置记为1,其余位置记0。从下往上排列即得这个十进制数对应的二进制数。
举例:
十进制数265         8  4  2  1
除16  商16 余9      1  0  0  1
除16  商1   余0      0  0  0  0
除16  商0   余1      0  0  0  1

Django实现SESSION

 二、DataSet

利用TDBXDataSetReader实例化,传输的是TDBXReader

讲的是返回dataset ClientDataSet1.Delta,TDataSetProvider,TSqlServerMethod,还用到了OleVariant

#include <Data.DBXCDSReaders.hpp>

 static void __fastcall CopyReaderToClientDataSet(Data::Dbxcommon::TDBXReader* Reader, Datasnap::Dbclient::TClientDataSet* Dataset);
 static Datasnap::Dbclient::TClientDataSet* __fastcall ToClientDataSet(TComponent* AOwner, Data::Dbxcommon::TDBXReader* Reader, bool AOwnsInstance);

C++中这些返回指针,怎么释放一直没想清楚。

则其对应的二进制数为 0001 0000 1001

设置Session

request.session['key']='value'
'''
实际进行的操作:
    1.  检查请求是否有sessionid,且是否存在与数据库,存在则对session_data进行更新
    2. 若不等,则创建随机字符串
    3. set_cookie('sessionid','随机字符串')
    4. 在session表中添加记录
                  session-key          session-data
                    随机字符串          {"key":"value"}-------------进行处理后的
'''

 三、返回ClientDataSet1的OleVariant

int TServerMethods1::GetTableDataSet(String atableName, OleVariant adata)
{
   ClientDataSet1->Open();
   adata = this->ClientDataSet1->Data;
   return this->ClientDataSet1->RecordCount;

}

DataSetProvider1也有Data属性。

OleVariant Data

DataSetProvider1->Data;

只能用ClientDataSet1,其他的数据集都没有data属性,有data属性的FDQuery类型也不是OleVariant 。

ClientDataSet:OleVariant Data

FDQuery:_di_IFDDataSetReference Data 

 

二进制转十进制:

获取Session

session_name=request.session['key']
'''
实际进行了哪些操作:
    1. 取随机字符串request.COOKIE.get('sessionid')
    2. 在session表中进行过滤:
        obj=django-session.objects.filter(session-key=random_str).first()
        obj.session-data.get("user")

'''

四、返回TDBXReader 

TDBXReader  可以自己释放内存,所以不必担心内心释放泄露的问题了。

 #include "Data.DBXCDSReaders.hpp"

TDBXReader* TServerMethods1::GetDSReader(String asql)
{
    TDBXCommand *cmd;
    TDBXReader *reader;
    TClientDataSet *cds;
    cmd = SQLConnection1.DBXConnection.CreateCommand;
    cmd->Text = asql;
    reader = cmd->ExecuteQuery();
    return reader;

   //or
    cds = TDBXClientDataSetReader::ToClientDataSet(NULL, reader, true);
    return new TDBXClientDataSetReader(cds, true);

}

 Client

 reader= CallProxy.GetDSReader();

TDBXClientDataSetReader::CopyReaderToClientDataSet(reader,cds);
cds->Open();

 

二进制数从右到左,每4位为一组(最后不足四位补0,编号N从第0组开始,以此类推)和8,4,2,1对应。其中1对应的数字求和再乘以16的N次方,所得的每组数再求和。
举例:
二进制数1000 1101
8  4  2  1    8  4  2  1
1  0  0  0    1  1  0  1
8*16¹+(8+4+1)*16º=141
即其对应的十进制数为 141。

其他

#删除Sessions值
del request.session["session_name"]
#检测是否操作session值
if "session_name" is request.session:

五、用ClientDataSet 

服务端:

fdquery

DataSetProvider1.DataSet=fdquery;

DataSetProvider1.Option.poAllowCommandText=true;

客户端

SQLConnection1

TDSProviderConnection.sqlconnection=SQLConnection1

TDSProviderConnection.serverclassname =tServerMethods1

ClientDataSet.RemoteServer=DSProviderConnection1

ClientDataSet.providername =DataSetProvider1

ClientDataSet.open();

ok!

三,开发中常见的术语

配置

图片 3图片 4

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认

数据库配置(配置)

图片 5图片 6

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置


    SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
    SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路径
    SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
    SESSION_COOKIE_SECURE = False                             # 是否Https传输cookie
    SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http传输
    SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否关闭浏览器使得Session过期
    SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次请求都保存Session,默认修改之后才保存

缓存配置

图片 7图片 8

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()         
    SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
    SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路径
    SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
    SESSION_COOKIE_SECURE = False                               # 是否Https传输cookie
    SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http传输
    SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否关闭浏览器使得Session过期
    SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次请求都保存Session,默认修改之后才保存

文件配置

图片 9图片 10

def login_session(request):
    if request.method=='POST':
        user=request.POST.get('user')
        pwd=request.POST.get('pwd')
        ret=UserInfo.objects.filter(name=user,pwd=pwd)
        if ret:
            request.session['user']=user
            return redirect('/index_session/')
    return render(request,'login.html')

def index_session(request):
    user=request.session.get('user')
    if not user:
        return redirect('/login_session/')
    return render(request,'index.html',locals())

View Code

六、返回TFDJSONDataSets 

TFDJSONDataSets可以返回多个数据集。这个是以后的趋势!REST Client,但是这个不能跨语言,客户端只能用RAD的TFDJSONDataSetsReader解析。但依然不能跨语言,C#,java无法解析。
服务的没有释放TFDJSONDataSets总感觉有内存泄漏,调用1000次测试一下。
返回字符串没有内存泄漏。

server

function TServerMethods1.GetJSONData: TFDJSONDataSets;
begin
  Result := TFDJSONDataSets.Create;
  if not FDMemTable1.Active then
    FDMemTable1.LoadFromFile('../../customer.fds')
  else
    FDMemTable1.Active := False;
  TFDJSONDataSetsWriter.ListAdd(Result, FDMemTable1);
end;

 

Client

var
  DSList: TFDJSONDataSets;
begin
  FDMemTable1.Close;
  DSList := ClientModule1.ServerMethods1Client.GetJSONData;
  FDMemTable1.AppendData(
      TFDJSONDataSetsReader.GetListValue(DSList, 0));
  FDMemTable1.Open;
end;

 or serverProxy eg

 FUnMarshal := TDSRestCommand(FGetDepartmentNamesCommand.Parameters[0].ConnectionHandler).GetJSONUnMarshaler;
 Result := TFDJSONDataSets(FUnMarshal.UnMarshal(FGetDepartmentNamesCommand.Parameters[0].Value.GetJSONValue(True)));

客户端 也可以  FDMemTableDepartments.Data := TFDJSONDataSetsReader.GetListValue(LDataSetList, 0);

图片 11

Django的用户认证

#先settings配置用户表
AUTH_USER_MODEL="blog.UserInfo"

 

七、返回TJSONArray

未实行

四、变量和数据类型

auth

利用auth模块中的一些方法来进行认证
from django.contrib import auth

八、返回FireDAC TJSONObject

此方法虽然返回了TJSONObject,但依然不能跨语言,C#,java无法解析。

DataSet2JsonObject 

DataSetsToJSONObject
从DataSet到TJsonObject
http://community.embarcadero.com/blogs/entry/cbuilder-xe6-multitier-database-app-with-firedac-json-reflection-40330

TJSONObject * TServerMethods1::GetDepartmentEmployeesJSON     ( System::UnicodeString AID )
{

    FDQueryDepartmentEmployees->Active = false;
    FDQueryDepartment->Active = false;
    FDQueryDepartment->Params->operator[ ]( 0 )->Value = AID;
    FDQueryDepartmentEmployees->Params->operator[ ]( 0 )->Value = AID;
    // Create dataset list
    TFDJSONDataSets * ds = new TFDJSONDataSets( );
    // Add departments dataset
    TFDJSONDataSetsWriter::ListAdd( ds, sDepartment, FDQueryDepartment );
    // Add employees dataset
    TFDJSONDataSetsWriter::ListAdd( ds, sEmployees,
        FDQueryDepartmentEmployees );
    TJSONObject * obj = new TJSONObject( );
    TFDJSONInterceptor::DataSetsToJSONObject( ds, obj );
    return obj;
}

 服务的没有释放TFDJSONDataSets总感觉有内存泄漏,调用1000次测试一下。
返回字符串没有内存泄漏。

TFDJSONDataSets

C++Builder
http://blogs.embarcadero.com/pawelglowacki/2014/06/04/40330/

Delphi
http://blogs.embarcadero.com/fernandorizzato/index.php/2014/07/21/multi-tier-com-delphi-xe6-e-firedac-json-reflection/

http://www.cnblogs.com/hnxxcxg/p/4007876.html
http://www.cnblogs.com/hnxxcxg/p/4008789.html
http://www.kzx123.com/?p=105
http://blog.marcocantu.com/blog/delphi_xe5_update2_datasnap_firedac.html
D:UsersPublicDocumentsEmbarcaderoStudio15.0SamplesObject PascalDataSnapFireDACJSONReflect

 TFDJSONDataSets *dset;
 TFDJSONDataSetsReader * dsread;
 TFDJSONDataSetsWriter::ListAdd(dset, FDMemTable1);//FDQuery1

TFDJSONDataSets 是DataSet的集合,数据集的集合,可以持有多个DataSet。
FDQuery1,FDMemTable1其实也可以有多个数据集,也算是数据集的集合,取下一个数据集FDQuery1.NextRecordSet

下面sql返回2个数据集。
FDQuery1.SQL.Text := 'select * from orders; select * from customers';

Data.FireDACJSONReflect.hpp
返回值可以是 TFDJSONDataSets,TJSONObject*,TFDJSONDeltas
通过 TFDJSONInterceptor::DataSetsToJSONObject()把TFDJSONDataSets转为TFDJSONDataSets。

图片 12图片 13

 static bool __fastcall DataSetsToJSONObject(TFDJSONDataSetsBase* const ADataSets, System::Json::TJSONObject* const AJSONObject);
 static bool __fastcall JSONObjectToDataSets(System::Json::TJSONObject* const AJSONObject, TFDJSONDataSetsBase* const ADataSets);
 static int __fastcall ListApplyUpdates(TFDJSONDeltas* const ADeltaList, const System::UnicodeString AKey, Firedac::Comp::Client::TFDCustomCommand* const ASelectCommand, TFDJSONErrors* const AErrors = (TFDJSONErrors*)(0x0))/* overload */;
 static Firedac::Comp::Client::TFDAdaptedDataSet* __fastcall GetListValueByName(TFDJSONDataSets* const ADataList, const System::UnicodeString AName);

View Code

 

图片 14图片 15

void __fastcall TForm2::FormCreate(TObject *Sender)
{

    //Server dataSet > JSONObj
    TFDJSONDataSets *dss;
    TFDJSONDataSetsWriter::ListAdd(dss, FDMemTable1);
    TFDJSONDataSetsWriter::ListAdd(dss, "employ", FDMemTable1);

    TJSONObject *jsobj = new TJSONObject();
    TFDJSONInterceptor::DataSetsToJSONObject(dss, jsobj);

    //Client JSONObject > dataSet
    std::auto_ptr<TFDJSONDataSets>LDataSets(new TFDJSONDataSets());
    TFDJSONInterceptor::JSONObjectToDataSets(jsobj, LDataSets.get());
    FDMemTable1->Active = false;
    TFDAdaptedDataSet * LDataSet = TFDJSONDataSetsReader::GetListValue(LDataSets.get(), 0);
    FDMemTable1->AppendData(*LDataSet);

    // client updateData
    TFDJSONDeltas *LDeltas;
    TFDJSONDeltasWriter::ListAdd(LDeltas, "a", FDMemTable1);
    TFDJSONInterceptor::DataSetsToJSONObject(LDeltas, jsobj);
    // dm->ServerMethods1Client->ApplyChangesDepartmentEmployeesJSON(LJSONObject);

    //Server  updata DataBase Server
    TFDJSONInterceptor::JSONObjectToDataSets(jsobj, LDeltas);
    TFDJSONErrors *errs;
    TFDJSONDeltasApplyUpdates::ListApplyUpdates(LDeltas, "a", FDQuery1->Command, errs)

}

View Code

 

更新还没实验好
  TFDAdaptedDataSet * LDataSet =  TFDJSONDataSetsReader::GetListValueByName(LDataSets.get(), sDepartment);
  // Update UI
  FDMemTableDepartment->Active = False;
  FDMemTableDepartment->AppendData(*LDataSet);

fdstoreproc 执行返回数据
  FDStoredProc1.Close;
  FDStoredProc1.Unprepare;
  FDStoredProc1.StoredProcName := 'TServerMethods1.QueryData';
  FDStoredProc1.Prepare;
  FDStoredProc1.ParamByName('sql').Value := 'select * from MyTable';
  FDStoredProc1.open;
  FDMemTable1.Close;
  FDMemTable1.Data := FDStoredProc1.Data


#include "Data.DBXCommon.hpp"
 TDBXCommand *FFindDataSetCommand;

内存释放FreeOnExecute有此函数貌似安全了。

FreeOnExecute registers the object indicated by Value, and frees it the next time the command is executed, closed, or freed. 

 返回TDataSet*

TDataSet* __fastcall TServerMethods1Client::FindDataSet(System::UnicodeString sql)
{
    if (FFindDataSetCommand == NULL)
    {
        FFindDataSetCommand = FDBXConnection->CreateCommand();
        FFindDataSetCommand->CommandType = TDBXCommandTypes_DSServerMethod;
        FFindDataSetCommand->Text = "TServerMethods1.FindDataSet";
        FFindDataSetCommand->Prepare();
    }
    FFindDataSetCommand->Parameters->Parameter[0]->Value->SetWideString(sql);
    FFindDataSetCommand->ExecuteUpdate();
    TDataSet* result = new TCustomSQLDataSet(NULL, FFindDataSetCommand->Parameters->Parameter[1]->Value->GetDBXReader(False), True);
    result->Open();
    if (FInstanceOwner)
        FFindDataSetCommand->FreeOnExecute(result);
    return result;
}

 

1、数据

authenticate()

提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数

如果认证信息有效,会返回一个  User  对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的

user = authenticate(username='someone',password='somepassword')

 九、返回TJSONObject

server code

// Get a Department and all Employees in the department.  Return TJSONObject.
function TServerMethods1.GetDepartmentEmployeesJSON(const AID: string)
  : TJSONObject;
var
  LDataSets: TFDJSONDataSets;
begin
  LDataSets := GetDepartmentEmployees(AID);
  try
    Result := TJSONObject.Create;
    TFDJSONInterceptor.DataSetsToJSONObject(LDataSets, Result)
  finally
    LDataSets.Free;
  end;
end;

client code

TJSONObject* __fastcall TServerMethods1Client::FindDataSetJSObj(System::UnicodeString sql)
{
    if (FFindDataSetJSObjCommand == NULL)
    {
        FFindDataSetJSObjCommand = FDBXConnection->CreateCommand();
        FFindDataSetJSObjCommand->CommandType = TDBXCommandTypes_DSServerMethod;
        FFindDataSetJSObjCommand->Text = "TServerMethods1.FindDataSetJSObj";
        FFindDataSetJSObjCommand->Prepare();
    }
    FFindDataSetJSObjCommand->Parameters->Parameter[0]->Value->SetWideString(sql);
    FFindDataSetJSObjCommand->ExecuteUpdate();
    TJSONObject* result = (TJSONObject*)FFindDataSetJSObjCommand->Parameters->Parameter[1]->Value->GetJSONValue(FInstanceOwner);
    return result;
}

 

返回Stream

Result := FFileDownloadCommand.Parameters[1].Value.GetStream(FInstanceOwner);

 

update json

// Update department and employees using deltas.  TJSONObject parameter.
procedure TServerMethods1.ApplyChangesDepartmentEmployeesJSON(const AJSONObject
  : TJSONObject);
var
  LDeltas: TFDJSONDeltas;
begin
  LDeltas := TFDJSONDeltas.Create;
  TFDJSONInterceptor.JSONObjectToDataSets(AJSONObject, LDeltas);
  ApplyChangesDepartmentEmployees(LDeltas);
end;

图片 16图片 17

Skip to content
This repository

    Explore
    Features
    Enterprise
    Pricing

1
0

    0

flrizzato/FireDACJSONReflectionXE7

FireDACJSONReflectionXE7/ServerMethodsUnit1.pas
Git User on 15 Oct 2014 first version

0 contributors
219 lines (188 sloc) 6.751 kB
//
// FireDACJSONReflect demo
// Copyright (c) 1995-2013 Embarcadero Technologies, Inc.

// You may only use this software if you are an authorized licensee
// of Delphi, C++Builder or RAD Studio (Embarcadero Products).
// This software is considered a Redistributable as defined under
// the software license agreement that comes with the Embarcadero Products
// and is subject to that software license agreement.
//
unit ServerMethodsUnit1;

interface

uses System.SysUtils, System.Classes, Datasnap.DSServer, Datasnap.DSAuth,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  FireDAC.Stan.Async, FireDAC.DApt, FireDAC.UI.Intf, FireDAC.VCLUI.Wait,
  FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys, Data.DB,
  FireDAC.Comp.Client, FireDAC.Phys.IBBase, FireDAC.Phys.IB, FireDAC.Comp.UI,
  FireDAC.Comp.DataSet, Data.FireDACJSONReflect, System.JSON,
  FireDAC.Stan.StorageBin, FireDAC.Stan.StorageJSON, FireDAC.Phys.IBDef;

type
{$METHODINFO ON}
  TServerMethods1 = class(TDataModule)
    FDQueryDepartmentEmployees: TFDQuery;
    FDQueryDepartment: TFDQuery;
    FDQueryDepartmentNames: TFDQuery;
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    FDPhysIBDriverLink1: TFDPhysIBDriverLink;
    FDConnectionEMPLOYEE: TFDConnection;
    FDStanStorageJSONLink1: TFDStanStorageJSONLink;
    FDQueryDepartmentDEPT_NO: TStringField;
    FDQueryDepartmentDEPARTMENT: TStringField;
    FDQueryDepartmentHEAD_DEPT: TStringField;
    FDQueryDepartmentMNGR_NO: TSmallintField;
    FDQueryDepartmentBUDGET: TBCDField;
    FDQueryDepartmentLOCATION: TStringField;
    FDQueryDepartmentPHONE_NO: TStringField;
    procedure DataModuleCreate(Sender: TObject);
  public
    { Public declarations }
    function EchoString(Value: string): string;
    function ReverseString(Value: string): string;

    // Strongly typed methods
    function GetDepartmentNames: TFDJSONDataSets;
    function GetDepartmentEmployees(const AID: string): TFDJSONDataSets;
    procedure ApplyChangesDepartmentEmployees(const ADeltaList: TFDJSONDeltas);

    // Equivalent TJSONObject methods (C++ compatible)
    function GetDepartmentNamesJSON: TJSONObject;
    function GetDepartmentEmployeesJSON(const AID: string): TJSONObject;
    procedure ApplyChangesDepartmentEmployeesJSON(const AJSONObject
      : TJSONObject);

    function FileDownload(sFileName: string): TStream;
    procedure FileUpload(fStream: TStream);
  end;
{$METHODINFO OFF}

implementation

{$R *.dfm}

uses System.StrUtils, System.Generics.Collections;

const
  sDepartment = 'Department';
  sEmployees = 'Employees';
  sDataDir = 'c:temp';

  // Get a Department and all Employees in the department.  Result TFDJSONDataSets.
function TServerMethods1.GetDepartmentEmployees(const AID: string)
  : TFDJSONDataSets;
begin
  // Clear active so that query will reexecute
  FDQueryDepartmentEmployees.Active := False;
  FDQueryDepartment.Active := False;
  FDQueryDepartment.Params[0].Value := AID;
  FDQueryDepartmentEmployees.Params[0].Value := AID;

  // Create dataset list
  Result := TFDJSONDataSets.Create;
  // Add departments dataset
  TFDJSONDataSetsWriter.ListAdd(Result, sDepartment, FDQueryDepartment);
  // Add employees dataset
  TFDJSONDataSetsWriter.ListAdd(Result, sEmployees, FDQueryDepartmentEmployees);
end;

// Get a Department and all Employees in the department.  Return TJSONObject.
function TServerMethods1.GetDepartmentEmployeesJSON(const AID: string)
  : TJSONObject;
var
  LDataSets: TFDJSONDataSets;
begin
  LDataSets := GetDepartmentEmployees(AID);
  try
    Result := TJSONObject.Create;
    TFDJSONInterceptor.DataSetsToJSONObject(LDataSets, Result)
  finally
    LDataSets.Free;
  end;
end;

// Update department and employees using deltas.  TFDJSONDeltas parameter.
procedure TServerMethods1.ApplyChangesDepartmentEmployees(const ADeltaList
  : TFDJSONDeltas);
var
  LApply: IFDJSONDeltasApplyUpdates;
begin
  // Create the apply object
  LApply := TFDJSONDeltasApplyUpdates.Create(ADeltaList);
  // Apply the department delta
  LApply.ApplyUpdates(sDepartment, FDQueryDepartment.Command);

  if LApply.Errors.Count = 0 then
    // If no errors, apply the employee delta
    LApply.ApplyUpdates(sEmployees, FDQueryDepartmentEmployees.Command);
  if LApply.Errors.Count > 0 then
    // Raise an exception if any errors.
    raise Exception.Create(LApply.Errors.Strings.Text);
end;

// Update department and employees using deltas.  TJSONObject parameter.
procedure TServerMethods1.ApplyChangesDepartmentEmployeesJSON(const AJSONObject
  : TJSONObject);
var
  LDeltas: TFDJSONDeltas;
begin
  LDeltas := TFDJSONDeltas.Create;
  TFDJSONInterceptor.JSONObjectToDataSets(AJSONObject, LDeltas);
  ApplyChangesDepartmentEmployees(LDeltas);
end;

procedure TServerMethods1.DataModuleCreate(Sender: TObject);
begin

end;

// Get all Departments.  Result TFDJSONDataSets.
function TServerMethods1.GetDepartmentNames: TFDJSONDataSets;
begin
  // Clear active so that query will reexecute
  FDQueryDepartmentNames.Active := False;

  Result := TFDJSONDataSets.Create;
  TFDJSONDataSetsWriter.ListAdd(Result, FDQueryDepartmentNames);
end;

// Get all Departments.  Result TFDJSONDataSets;
function TServerMethods1.GetDepartmentNamesJSON: TJSONObject;
var
  LDataSets: TFDJSONDataSets;
begin
  LDataSets := GetDepartmentNames;
  try
    Result := TJSONObject.Create;
    TFDJSONInterceptor.DataSetsToJSONObject(LDataSets, Result);
  finally
    LDataSets.Free;
  end;
end;

function TServerMethods1.EchoString(Value: string): string;
begin
  Result := Value;
end;

function TServerMethods1.FileDownload(sFileName: string): TStream;
var
  fFileStream: TFileStream;
begin
  fFileStream := TFileStream.Create(sDataDir + sFileName, fmOpenRead);
  Result := fFileStream;
end;

procedure TServerMethods1.FileUpload(fStream: TStream);
var
  fMemStream: TMemoryStream;
  BytesRead: integer;
  sFileName: string;
  Buffer: PByte;
const
  MaxBufSize = 1024 * 1024;
begin
  sFileName := sDatadir + 'file-to-upload-copy.jpg';
  DeleteFile(sFileName);

  if not FileExists(sFileName) then
  begin
    fMemStream := TMemoryStream.Create;
    try
      fStream.Seek(0, TSeekOrigin.soBeginning);
      fStream.Position := 0;

      GetMem(Buffer, MaxBufSize);
      repeat
        BytesRead := fStream.Read(Buffer^, MaxBufSize);
        if BytesRead > 0 then
          fMemStream.WriteBuffer(Buffer^, BytesRead);
      until BytesRead < MaxBufSize;
      fMemStream.Seek(0, TSeekOrigin.soBeginning);

      fMemStream.SaveToFile(sFileName);
    finally
      fMemStream.Free;
    end;
  end;
end;

function TServerMethods1.ReverseString(Value: string): string;
begin
  Result := System.StrUtils.ReverseString(Value);
end;

end.

    Status API Training Shop Blog About Pricing 

    © 2015 GitHub, Inc. Terms Privacy Security Contact Help 

View Code

 

Delphi DataSet与JSON互转

DataSetConverter4Delphi

 

用webmodule返回

void __fastcall TWebModule_main::WebModule_mainWebActionItem1Action(TObject *Sender,
          TWebRequest *Request, TWebResponse *Response, bool &Handled)

function TServerConnMonitorMethodsClient.ReverseString(Value: string): string;
begin
  if FReverseStringCommand = nil then
  begin
    FReverseStringCommand := FDBXConnection.CreateCommand;
    FReverseStringCommand.CommandType := TDBXCommandTypes.DSServerMethod;
    FReverseStringCommand.Text := 'TServerConnMonitorMethods.ReverseString';
    FReverseStringCommand.Prepare;
  end;
  FReverseStringCommand.Parameters[0].Value.SetWideString(Value);
  FReverseStringCommand.ExecuteUpdate;
  Result := FReverseStringCommand.Parameters[1].Value.GetWideString;
end;

 

 

计算机存储的数据会分为各种类型,基本类型有4种:int(整数类型)、double(浮点数类型)、string(字符串类型)、char(字符类型)。每种类型有对应的书写规则。

login(HttpRequest, user)

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。

login(request, user)

char:字符类型 ‘’

logout(request) 

 该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

logout(request)

string:字符串类型 “”

User对象

User 对象属性:

username, password(必填项)password用哈希算法保存到数据库

is_staff : 用户是否拥有网站的管理权限.

is_active : 是否允许用户登录, 设置为``False``,可以不用删除用户来禁止 用户登录

int:整数类型 直接书写

is_authenticated()

如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

if not request.user.is_authenticated():
    return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

django自带用于此种情况的装饰器:login_requierd()

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递  当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

double:浮点数类型 直接书写

创建用户

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email='')

类型转换

修改密码set_password()

user = User.objects.get(username='')
user.set_password(password='')
user.save

任何类型转string: 数据.Tostring()

check_password(passwd)

用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

 基于auth认证实现登录:

def login(request):
    '''
    登录验证
    :param request:
    :return:
    '''
    if request.method=='POST':
        username=request.POST.get('username')
        pwd=request.POST.get('pwd')
        input_valid_code=request.POST.get('valid_code')
        valid_code=request.session.get('valid_code')
        login_response={'user':None,'error_msg':''}
        #进行验证码的比较
        if valid_code.upper()==input_valid_code.upper():
            user=auth.authenticate(username=username,password=pwd)
            if user:
                auth.login(request,user)
                login_response['user']=user.username
            else:
                login_response['error_msg']='用户名或密码错误!'
        else:
            login_response['error_msg']='验证码错误!'
        import json
        return HttpResponse(json.dumps(login_response))
    return render(request,'login.html',locals())

 

 

 

 

string转int:int.Parse(数据)

string转double:double.Parse(数据)

double转int:显式转换 int(数据)

int转double:隐式转换 不采取操作

2、变量

变量代表一块储存数据的内存空间,存储的数据可变。需要先声明,再赋值。

本文由澳门新葡亰手机版发布于编程,转载请注明出处:session以及认证系统,多层返回数据集分析FireDA

上一篇:递归例程,python学习笔记 下一篇:没有了
猜你喜欢
热门排行
精彩图文