Delphi 6 preemptive research - BizSnapSOAPWebService

zhaozj2021-02-08  209

Delphi 6 preemptive research - BizSnap / SOAP / WebService

- Pass custom type data via SOAP

In the previous example (see "Delphi 6 preemptive research - BizSnap / SOAP / WebService - one Hello World!") We see that remote object calls can be easily performed through SOAP, although that example The object is a Delphi class, but in fact, you only need to make a SOAP package for the object, you can call all kinds of objects including COM / CORBA / EJB (except for EJBs must be implemented in Java, COM / CORBA can be implemented with Delphi ). In that example, the data type used by the interface method is a standard type, but the actual application often encounters the case where the custom type is passed. At this time, the operation is slightly troublesome, and the details such as Li Wei are fun, possibly Infinite New Technology -Web Service "is shown in the example. Similarly, here is also an example to illustrate the method of passing the custom data type through the SOAP, this example is a more trouble-to-server example: server: 1.New | WebServices | SOAP Server Application, as shown below: This example is used Web App Debugger (see "Delphi 6 Preferred Research - Web App Development and Debug"), set its coclass name to WadsoapDemo2, as shown below: 2.SAVEAll, Unit2 named: svrwmmain, Unit1 does not change the name, Project1 named: Server 3.New | Data Module, save this unit as SVRDATAMOD; 4. Put two DBEXPRESS controls: SqlConnection1 and SqlDataSet1, as shown below: It is set to:

SqlConnection1ConnectionName: = iblocal; loginprompt: = false; params.values ​​['Database']: = '[...] / example / database / employee.gdb'; // above [...] is installed for your interbase path SQLDataSet1SQLConnection: = SQLConnection1; CommandText: = 'select FULL_NAME, PHONE_EXT from EMPLOYEE WHERE EMP_NO =: EMP_NO'; 5.New | unit, this unit is saved as SvrDataType, which reads as follows: unit SvrDataType;

Interface

Uses

InvoKeregistry;

Type

Tempinfo = Class (Tremotable)

Private

FNAME: STRING;

FPHONE: STRINE;

Published

Property Name: String Read FName Write FName

Property Phone: String Read fPhone Write fPhone;

END;

IMPLEMENTATION

INITIALIZATION

RemclassRegistry.registerXSClass (Tempinfo); Finalization

RemclassRegistry.unregisterXSClass (Tempinfo);

End.

Class: Tempinfo is defined in this unit, used to record employee information, including two domains of Name and Phone, all of which are string types. For data types that need to be passed to the client, must be derived from the Tremotable class, which can automatically handle the passage of type information. If you want to manually process custom data types, you must derive from the TremotableXS class, which is similar to Tremotable, but in this way, two conversion methods must be implemented: NativeToxs and Xstonative, see Delphi6 / Source / SOAP / XSbuiltins.Pas Realization of several classes in. It should be noted that two attributes are placed in published in Published. He must do this here, I have used them in public, causing the client unable to get the data type information of the server, and then found them must Playing in public in public, so although it is not a control here, these properties are not displayed in the Object Inspector, but still need to be placed in public. This may be because Publisd is more Publico more RTTI (Run Time Type Info, runtime information), and the remote data type is dependent on RTTI. Finally, register and reverse this class in the remote class registration information library. 6.New | Unit, save this unit as SVRSOAPINTF, as follows: Unit Svrsoapintf;

Interface

Uses

InvokeRegistry, SVRDATYPE;

Type

IsoApeMPloyee = Interface (Iinvokable)

['{31903B5A-96B3-43C2-A7B5-F67F6DB829E5}']

Function GetEmployee (AEMPNO: Integer): Tempinfo; StdCall;

END;

IMPLEMENTATION

INITIALIZATION

INVREGISTRY.REGISTERFACE (IsoApemployee);

End.

The SOAP interface is defined in this unit, which is not a big difference with the previous example, but this interface is implemented in a separate unit in this time. The only difference is that the method in this interface gets geteMployee returns a custom data type: Tempinfo. 7. Join the SOAP implementation class in the SVRWMMAIN unit, the complete unit content is as follows: Unit svrwmmain

Interface

Uses

Sysutils, classes, httpapp, wsdlpub, soappasinv, soaphttpasinv,

SOAPHTTPDISP, WebBrokersoAP;

Type

Twebmodule2 = Class (Twebmodule)

HTTPSOAPDISPATCHER1: THTTPSOAPDISPATCHER;

HTTPSOAPSCALINVOKER1: THTTPSOAPSCALINVOKER;

Wsdlhtmlpublish1: TWSDLHTMLP Bublish;

Private

{Private Declarations}

PUBLIC {public declarations}

END;

VAR

WebModule2: twebmodule2;

IMPLEMENTATION

Uses WebReq, ​​InvokeRegistry, Svrdattype, Svrsoapintf, SvrdataMod;

{$ R * .dfm}

Type

TSoAPemPloyee = Class (TinvokableClass, IsoApeMployee)

Protected

Function GetEmployee (AEMPNO: Integer): Tempinfo; StdCall;

END;

{TSoAPEMPLOYEEE}

Function TSoApemployee.geTemPloyee (AEMPNO: Integer): Tempinfo; stdcall;

Begin

RESULT: = Tempinfo.create;

IF (Not Assigned (Datamodule2)) THEN

DataModule2: = TDATAModule2.create (nil);

Try

DataModule2.SqlConnection1.Open;

With datamodule2.sqldataset1 do

Begin

PARAMBYNAME ('EMP_NO') .asinteger: = AEMPNO;

Open;

IF (not eof) THEN

Begin

Result.name: = FieldByname ('full_name') .sstring;

Result.Phone: = FieldByName ('phone_ext') .sstring;

End

Else

Begin

Result.name: = '';

Result.Phone: = '';

END;

CLOSE;

END;

DataModule2.sqlConnection1.close;

Finally

DataModule2.free;

DataModule2: = NIL;

END;

END;

INITIALIZATION

WebRequestHandler.WebmoduleClass: = TWEBModule2;

Invregistry.registerInvokableClass (TSoApemployee);

End.

The implementation and implementation of the TSOAPEMPLOYEE of the interface here is similar to the previous example. GetEmployee is not complex: First, if you do not create an instance of DataModule2 (you need to remove DataModule2 from automatic creation in Project | Options); then connect to the database, query the employee of the designated employee number Information; finally returns this information. Note: This uses DBEXPRESS, some places are not only like BDE / ADO, if you can't use RecordCount, you can only use EOF to determine if there is a query result. 8. This completes all the programs, compiles and runs, then exits the registration of the Web App DEBUGER application. Start the web app debugger, then start the browser, enter: http: // localhost: 1024 / server.wadsoapdemo2 / wsdl / isoaPloyee to browse its WSDL content, including the necessary information of the custom type, but if The properties of the Tempinfo class in the front SVRDATYPE unit are not placed in the Published section, which will not see type information. Here is the Types tag part of this WSDL:

XMLns: n1 = "http://schemas.xmlsoap.org/wsdl/" />

From the above WSDL, you can see that the server exports three "complex types" - ComplexType: Tempinfo, TWSDLSOAPPORT, TWIDESTRINGDYNARRAY, where the Tempinfo is the type of data we define, the other is Delphi internal definition Type, we will see them again when the client is imported in WSDL. Look at the implementation of the client: 1.New | Application Create a normal VCL application; 2.saveall, unit1 named clnmain, project1 named client; 3. Put HttPrio1, Edit1, Button1, Label1, Label2, etc. on Form1 Controls, as shown below: EDIT1's text set to 1, button1's CAPTION set to getEmployee, HTTPRIO1 URL property set to: http: // localhost: 1024 / server.wadsoapdemo2 / soap; 4.new | Web Services | Web Services Importer, similar to the former example, only imported URLs to: http: // localhost: 1024 / server.wadsoapdemo2 / wsdl / isoaPloyee; 5. If the server's WSDL is as described above, three units will be imported into three units. The TWSDLSOAPPORT, TEMPINFO, ISOAPEMPLOYEE, where IsoApeMPloyee is the SOAP interface unit we know. Tempinfo is the data type we defined at the server. TWSDLSOAPPORT is a data type inside the Delphi, we have seen in the server's WSDL It has been reached. Save all, saved TWSDLSOAPPORT as ClNSoApport, saved Tempinfo as CLNDATYPE, saved IsoApeMPloyee as ClNSoAPintf. Note that the two units in the CLNSOAPINTF unit must be changed to ClNSoApport and ClndataType accordingly. Since the contents of these three units do not need to be changed, as long as the server is correct, it is not necessary to understand the contents of the three units (especially the other CLNSOAPINTF and CLNDATYPE and the corresponding unit of the server), so it is not listed here. Their content. 6. Double click on button1 Enter the following code: Procedure TFORM2.BUTTON1CLICK (Sender: TOBJECT);

VAR

EI: Tempinfo;

Begin

EI: = (httprio1 as isoailemployee) .geTETEMPLOYEE (Strtell (Edit1.Text));

IF (Assigned (EI)) THEN

Begin

Label1.caption: = ei.name;

Label2.caption: = ei.phone;

END;

END;

7. Compilation operation, enter "1" or other database in Edit1, no corresponding record, press Button1, Label1 and Label2 to display empty; enter "2" or other databases have recorded employees, Display the full name of the employee in Label1, showing the telephone number of this employee in Label2, as shown below: It is not so complicated to see this example. Raptor Jun.20-01, OCT.20, OCT.24

转载请注明原文地址:https://www.9cbs.com/read-2665.html

New Post(0)