DELPHI 6 선점-BizSnap/SOAP/WebService 2
9927 단어 webservice
-- SOAP를 통해 사용자 정의 유형 데이터 전달
앞의 예《DELPHI 6 선도적 연구--BizSnap/SOAP/Web 서비스 중 하나--Hello World!의 예》에서 보듯이 SOAP를 통해 원격 대상 호출을 편리하게 할 수 있다. 비록 그 예에 사용된 대상은 Delphi류이지만 실제로는 대상에 대한 SOAP 포장만 하면 COM/CORBA/EJB 등 각 대상을 호출할 수 있다(EJB가 자바로 해야 하는 것을 제외하고 COM/CORBA는 모두 Delphi로 실현할 수 있다).그 예에서 인터페이스 방법이 사용하는 데이터 유형은 모두 표준 유형이지만 실제 응용에서 사용자 정의 유형을 전달해야 하는 상황에 자주 부딪히기 때문에 이 때의 조작은 약간 번거롭다. 자세한 내용은 리비"재미, 가능한 새로운 기술 - 웹 서비스"의 예와 같다.마찬가지로 여기서도 하나의 예로 SOAP를 통해 사용자 정의 데이터 형식을 전달하는 방법을 설명해야 한다. 이 예는 비교적 번거로운 예가 될 것이다. 서버: 1.New | Web Services | Soap Server Application, 다음 그림: 이 예는 웹 앱 Debugger(상세 참조DELPHI 6 선점 연구 - 웹 응용 개발 및 디버깅를 사용하여 CoClass Name을wadSoapDemo2로 설정합니다. 다음 그림: 2.SaveAll, Unit2 이름: SvrWMmain, Unit1 이름 바꾸지 않음, Project1 이름: Server,3. New | Data Module, 이 단원을 SvrData Mod로 저장합니다.4. 두 개의dbExpress 컨트롤을 넣는다. SQLconnection1과 SQLDAtaSet1이다. 다음 그림은 속성 설정이 다음과 같다.
SQLConnection1
ConnectionName := IBLocal;LoginPrompt := false;Params.Values['Database'] := '[...]/Examples/Database/Employee.gdb';//위의 [...]InterBase 설치 경로
SQLDataSet1
SQLConnection := SQLConnection1;CommandText := 'select FULL_NAME, PHONE_EXT from EMPLOYEE WHERE EMP_NO = :EMP_NO';
5. New | Unit, 이 단원을 SvrDataType으로 저장합니다. 그 내용은 다음과 같습니다.
unit SvrDataType;
interface
Uses
InvokeRegistry;
Type
TEmpInfo = Class( TRemotable )
Private
FName : String;
FPhone : String;
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.
이 단원에 정의된 클래스는 다음과 같습니다: TEmpInfo. 직원 정보를 기록하는 데 사용됩니다. Name과 Phone 두 영역을 포함하여 모두 문자열 형식입니다.클라이언트에게 전달해야 하는 데이터 형식은 Tremotable 클래스에서 파생되어야 하며, 유형 정보의 전달을 자동으로 처리할 수 있습니다.사용자 정의 데이터 형식의 전달을 수동으로 처리하려면 Tremotable XS 클래스에서 파생해야 합니다. 그 사용법은 Tremotable와 유사하지만, 이렇게 하려면 두 가지 변환 방법을 실현해야 합니다. 그것이 바로 NativeToXS와 XSTONative입니다. Delphi6/Source/Soap/XSBuiltIns입니다.pas 중의 몇 가지 유형의 실현.주의해야 할 것은 이러한 두 개의 속성을 Published에 두면 반드시 이렇게 해야 한다는 것이다. 나는 이를 Public에 두었기 때문에 클라이언트가 서버의 데이터 형식 정보를 얻을 수 없었고 나중에 Published에 두어야 한다는 것을 발견했다. 비록 이것은 컨트롤러가 아니지만 Object Inspector에 표시하기 위해서도 아니지만 Published에 두어야 한다는 것이다.이는 Published가 Public보다 RTTI(Run Time Type Info, 런타임 유형 정보)의 동쪽이 많고 원격 데이터 형식은 RTTI에 의존하기 때문일 수 있다.마지막으로 원격 클래스 등록 정보 라이브러리에서 이런 것을 등록하고 반등록한다.6. New | Unit, 이 단원을 SvrSoapIntf로 저장합니다. 그 내용은 다음과 같습니다: unit SvrSoapIntf;
interface
Uses
InvokeRegistry, SvrDataType;
Type
ISoapEmployee = Interface( IInvokable )
['{31903B5A-96B3-43C2-A7B5-F67F6DB829E5}']
Function GetEmployee( aEmpNo : Integer ) : TEmpInfo; StdCall;
End;
implementation
Initialization
InvRegistry.RegisterInterface( TypeInfo( ISoapEmployee ) );
end.
이 단원에서 SOAP 인터페이스를 정의했습니다. 이것은 앞의 예와 크게 다르지 않습니다. 단지 이번에 명확하게 보기 위해 이 인터페이스를 하나의 단독 단원에 두어 실현합니다.유일한 차이점은 이 인터페이스의 방법인 GetEmployee가 사용자 정의 데이터 형식인 TEmpInfo를 되돌려주는 것입니다.7. SvrWMmain 단원에 SOAP 실현 클래스를 추가하면 완전한 단원의 내용은 다음과 같다. unit SvrWMMain;
interface
uses
SysUtils, Classes, HTTPApp, WSDLPub, SOAPPasInv, SOAPHTTPPasInv,
SoapHTTPDisp, WebBrokerSOAP;
type
TWebModule2 = class(TWebModule)
HTTPSoapDispatcher1: THTTPSoapDispatcher;
HTTPSoapPascalInvoker1: THTTPSoapPascalInvoker;
WSDLHTMLPublish1: TWSDLHTMLPublish;
private
{ Private declarations }
public
{ Public declarations }
end;
var
WebModule2: TWebModule2;
implementation
uses WebReq, InvokeRegistry, SvrDataType, SvrSoapIntf, SvrDataMod;
{$R *.DFM}
Type
TSoapEmployee = class( TInvokableClass, ISoapEmployee )
Protected
Function GetEmployee( aEmpNo : Integer ) : TEmpInfo; StdCall;
End;
{ TSoapEmployee }
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' ).AsString;
Result.Phone := FieldByName( 'PHONE_EXT' ).AsString;
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.
이 인터페이스의 실현 클래스인 Tsoap Employee의 정의는 실현과 이전 예와 유사하다.GetEmployee의 실현도 복잡하지 않다. 우선, DataModule2의 실례를 만들지 않으면(Project|Options에서 DataModule2를 자동 생성 목록에서 옮겨야 함) DataModule2의 실례를 만든다.그리고 데이터베이스에 연결하여 지정된 직원 번호의 직원 정보를 조회한다.마지막으로 이 메시지를 되돌려줍니다.주의:dbExpress를 사용했습니다. BDE/ADO와 다른 부분도 있습니다. RecordCount를 사용할 수 없으면 Eof로만 조회 결과가 있는지 판단할 수 있습니다.8. 이로써 서버의 모든 프로그램을 완성하고 컴파일하고 실행한 다음에 웹 앱 디버그 프로그램의 등록을 종료합니다.웹 App Debugger를 시작하고 브라우저를 시작하여 주소 표시줄에 다음을 입력합니다.http://localhost:1024/Server.wadSoapDemo2/wsdl/ISoapEmployee사용자 정의 유형에 필요한 정보를 포함하는 WSDL 내용을 볼 수 있지만, 앞의 SvrDataType 단원의 TEmpInfo 클래스 속성이 Published 부분에 놓여 있지 않으면 유형 정보를 볼 수 없습니다.다음은 이 WSDL의 types 표기 부분의 내용입니다. <types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:SvrDataType">
<xs:complexType name="TEmpInfo">
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Phone" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:WSDLSoap">
<xs:complexType name="TWSDLSOAPPort">
<xs:sequence>
<xs:element name="PortName" type="xs:string"/>
<xs:element name="Addresses" type="ns3:TWideStringDynArray"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Types">
<xs:complexType name="TWideStringDynArray">
<xs:complexContent>
<xs:restriction base="soapenc:Array">
<xs:sequence/>
<xs:attribute ref="soapenc:arrayType" n1:arrayType="xs:string[]"
xmlns:n1="http://schemas.xmlsoap.org/wsdl/"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>
</types>
위의 WSDL에서 서비스 측에서 세 가지'복잡한 유형'을 내보냈습니다. 그것이 바로 complexType: TEmpInfo, TWSDLSOAPPort, TWideStringDynarray입니다. 그 중에서 TEmpInfo는 우리가 정의한 데이터 유형을 제외하고 다른 두 가지는 Delphi 내부에서 정의한 유형입니다. 클라이언트가 WSDL을 가져올 때 우리는 그것들을 다시 볼 수 있습니다.클라이언트의 실현을 살펴보자: 1.New | Application에서 일반 VCL 프로그램을 새로 만듭니다.2. SaveAll, Unit1은 ClnMain, Project1은 Client로 명명한다.3. Form1에 HTTPRIO1,Edit1,Button1,Label1,Label2 등 컨트롤을 넣는다. 그림에서 Edit1의 Text는 1,Button1의 Caption은 GetEmployee,HTTPRIO1의 URL 속성은 다음과 같다.http://localhost:1024/Server.wadSoapDemo2/soap ; 4. New | Web Services | Web Services Importerhttp://localhost:1024/Server.wadSoapDemo2/wsdl/ISoapEmployee ; 5. 만약에 서비스 측의 WSDL이 앞에서 말한 바와 같이 세 개의 단원을 가져올 것이다. 각각 TWSDLSOAPPort, TEmpInfo, ISoapEmployee를 포함한다. 그 중에서 ISoapEmployee는 우리가 아는 SOAP 인터페이스 단원이고 TEmpInfo는 우리가 서비스 측에서 정의한 데이터 유형이다. TWSDLSOAPPort는 DLphi 내부에서 정의한 데이터 유형이다. 우리는 서비스 측의 WSDL에서 이 유형을 본 적이 있다.Save All, TWSDLSOAPPort의 단원을 ClnSoapPort, TEmpInfo를 ClnDataType, ISoapEmployee를 ClnSoapIntf로 저장합니다.ClnSoapIntf 단원의 Uses에서 UnitN이라는 두 단원을 ClnSoapPort와 ClnDataType으로 바꾸어야 한다는 것을 주의하십시오.이 세 단원의 내용은 모두 바꿀 필요가 없기 때문에 서버가 정확하기만 하면 이 세 단원의 내용을 이해할 필요가 없다(특히 ClnSoapIntf와 ClnDataType은 서버의 상응하는 단원과 기본적으로 같다). 그래서 여기에도 그들의 내용을 열거하지 않는다.6. Button1을 두 번 클릭하여 다음 코드를 입력합니다. procedure TForm2.Button1Click(Sender: TObject);
Var
ei : TEmpInfo;
begin
ei := ( HTTPRIO1 As ISoapEmployee ).GetEmployee( StrToInt( Edit1.Text ) );
If ( Assigned( ei ) ) Then
Begin
Label1.Caption := ei.Name;
Label2.Caption := ei.Phone;
End;
end;
7.편집 실행, 편집 1에'1'또는 다른 데이터베이스에 해당하는 기록이 없는 직원 번호를 입력하고 Button1을 누르면 Label1과 Label2가 모두 비어 있음;"2"또는 다른 데이터베이스에 기록된 직원 번호를 입력하면 Label1에 직원 전체 이름을 표시하고, Label2에 이 직원의 전화번호를 표시합니다. 다음 그림은 다음과 같습니다. 한 번 해 보고 다시 봐도 그리 복잡하지 않습니다.맹금 Jun.20-01, Oct.20, Oct.24
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
java가 클라이언트를 통해 서버 웹 서비스에 접근하는 방법본고는 자바가 클라이언트를 통해 서버 웹 서비스에 접근하는 방법을 실례로 설명한다.다음과 같이 여러분에게 참고할 수 있도록 공유합니다. 자바 관련 내용에 관심이 있는 더 많은 독자들은 본 사이트의 주제를 볼 수 있습...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.