現在地: Visual LANSA を使用したWeb アプリケーション > 20. ヒントとテクニック > 20.12 クライアントとサーバー間でのデータのやり取り

20.12 クライアントとサーバー間でのデータのやり取り

ほとんどの場合、情報は JSON 形式によりサーバーとクライアントの間で双方向にやり取りされます。  SRVROUTINE は JSON データを以下の形式で送受信します。

JSON フォーマットの例外としては、サーバー・ルーチンが応答オブジェクトを返す時です。これは、1 つのファイルの詳細を戻すために使用されます。

例:

フィールドまたはフィールドのグループを引き渡す

データ・リストの引き渡し

応答オブジェクトを戻す

フィールドまたはフィールドのグループを引き渡す

クライアントとサーバー間でデータのやり取りをする最も簡単な方法は、どちらの方向であったとしても、個別のフィールドまたはフィールドのグループを SRVROUTINE にマップすることです。  値は、その位置または任意の PARAMETER_NAME の値をもとに、SRVROUTINE とやり取りされます。

GROUP_MAP を使用する際は、クライアントとサーバー間で関連するグループ定義が検証されないことに注意することが大切です。グループ内のフィールドは名前をもとにマップされています。  必要に応じて想定のデータが確実に送受信されるよう、含まれるフィールドに関しては、グループ定義と一致するか検証することを忘れないようにしてください。

例えば、次のコードは xEmployee ファイルのレコードを更新しようとすると、エラーになります。これは、何故でしょうか。クライアントの GROUP_BY では、ID、名字と名前のみがサーバーに渡されます。ですから、これに対応するサーバー・モジュールの GROUP_BY に指定されているその他のフィールドには値がないことになります。UPDATE で更新しようとすると、妥当性検査ルールでエラーとなります。

クライアントとサーバーの処理で使用される GROUP_BY 定義に同じフィールドが含まれることを確実にするだけで、この問題は解決できます。これは処理するトランザクションによりますが、ファイルのフィールドすべての場合もあるでしょうし、フファイルのフィールドのサブセットの場合もあるでしょう。

クライアントの Web ページまたは再利用可能パーツのコードは次のようになります。

Group_By Name(#MyEmployee) Fields(#xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames)

 

Mthroutine Name(UpdateEmployee)

 

* サーバーのデータ更新に使用するサーバー・モジュールの定義

Define_Com Class(#MyServerModule.UpdateEmployee) Name(#UpdateEmp)

 

* データを非同期に更新

#UpdateEmp.ExecuteAsync Status(#io$sts) Employeedetails(#MyEmployee)

 

Evtroutine Handling(#UpdateEmp.Completed)

 

* 完了後の処理があれば追加

 

Endroutine

 

Evtroutine Handling(#UpdateEmp.Failed) Handled(#handled)

 

* エラー処理

 

Endroutine

 

Endroutine

 

サーバー・モジュールのこれに対応するコードは以下のようになります。

Group_By Name(#Employee) Fields(#xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames #xEmployeeStreet #xEmployeeCity #xEmployeeState #xEmployeePostalCode #xEmployeeCountry #xEmployeeHomeTelephone #xEmployeeBusinessTelephone #xEmployeeMobilePhone #xEmployeeSalary #xEmployeeStartDate #xEmployeeTerminationDate #xEmployeeDepartmentCode) 

 

* このグループ定義を使って Web ページより送信された詳細と一致させる

 

* Group_By Name(#Employee) Fields(#xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames)

 

SrvRoutine Name(UpdateEmployee)

Group_Map For(*input) Group(#Employee) Parameter_Name(EmployeeDetails)

Field_Map For(*output) Field(#io$sts) Parameter_Name(Status)

 

Update Fields(#Employee) In_File(xEmployee) With_Key (#xEmployeeIdentification)

 

Endroutine

 

データ・リストの引き渡し

GROUP_MAP には、各フィールドの 1 つのインスタンスのみが含まれており、LIST_MAP を使用できる、複数のデータのインスタンスを引き渡します。 

GROUP_MAP と同様、クライアントとサーバー側の DEF_LIST 定義が、リスト・サイズと同様にフィールドも一致していることを確認することが重要です。

以下の SRVROUTINE ルーチンは、ファイル内のすべてのレコードを含むリストを戻します。

Def_List Name(#Employees) Fields(#xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames #xEmployeeStreet #xEmployeeCity #xEmployeeState #xEmployeePostalCode #xEmployeeCountry #xEmployeeHomeTelephone #xEmployeeBusinessTelephone #xEmployeeMobilePhone #xEmployeeSalary #xEmployeeStartDate #xEmployeeTerminationDate #xEmployeeDepartmentCode) Type(*working) Entrys(*MAX) 
SrvRoutine Name(GetEmployees)
List_Map For(*Output) List(#Employees)
Select Fields(#Employees) From_File(xEmployee)
Add_Entry To_List(#Employees)
Endselect
Endroutine

 

クライアント側でリストを受信する方法には 2 通りあり、1 つはローカルで定義されたリストに直接送信する方法で、次のようになります。

* ローカル定義リスト

Def_List Name(#EmployeeList) Fields(#xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames #xEmployeeStreet #xEmployeeCity #xEmployeeState #xEmployeePostalCode #xEmployeeCountry #xEmployeeHomeTelephone #xEmployeeBusinessTelephone #xEmployeeMobilePhone #xEmployeeSalary #xEmployeeStartDate #xEmployeeTerminationDate #xEmployeeDepartmentCode) Type(*working) Entrys(*MAX) 

Mthroutine Name(GetEmployees)

* サーバー・モジュールのメソッド・ルーチンの定義

Define_Com Class(#MyServerModule.GetEmployees) Name(#GetEmps)

 

* ローカル定義のリストにデータを返す

#GetEmps.ExecuteAsync( #EmployeeList )

 

Endroutine

 

もう 1 つの方法は、DEF_LIST を以下のように変えて、データをデータ・オブジェクトのコレクションに直接マップする方法です。

* リストとして使用される社員アイテムのコレクション

Define_Com Class(#Prim_acol<#MyEmployeeData>) Name(#EmployeeList)

 

すべてのリスト・データがクライアントで使用できるようにするためには、この関連付けられた再利用可能パーツ MyEmployeeData に、対応するフィールドが含まれている必要があります。

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_OBJT *listFields #MyEmployee)

 

Group_By Name(#MyEmployee) Fields(#xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames #xEmployeeStreet #xEmployeeCity #xEmployeeState #xEmployeePostalCode #xEmployeeCountry #xEmployeeHomeTelephone #xEmployeeBusinessTelephone #xEmployeeMobilePhone #xEmployeeSalary #xEmployeeStartDate #xEmployeeTerminationDate #xEmployeeDepartmentCode)

 

End_Com

応答オブジェクトを戻す

応答オブジェクトは、通常はアプリケーション・サーバーからのイメージまたはファイルのダウンロードに使用されます。

以下の例では、データベース・テーブルからあるイメージが読み込まれます。そして、応答オブジェクトにイメージ・データが入れられ、ファイル名が設定されます。

SrvRoutine Name(DownloadImage) Response(#Response)
Field_Map For(*Input) Field(#xEmployeeIdentification)
Field_Map For(*output) Field(#io$sts) Parameter_Name(Status)
 
Fetch Fields(#xEmployeeSurname #xEmployeeGivenNames) From_File(xEmployee) With_Key(#xEmployeeIdentification)
 
If_Status Is(*okay)
 
Fetch Fields(#empimg) From_File(xEmployeeImages) With_Key(#xEmployeeIdentification)
 
If_Status Is(*okay)
 
#Response.ContentFile := #Empimg.Filename
#Response.AttachmentFileName := #xEmployeeSurname #xEmployeeGivenNames + (#xEmployeeIdentification
 
Endif
 
Endif
Endroutine