अद्यतन
मैंने सर्वर वंश का एक बेहतर संस्करण लिखा है। यह एक स्वरूपित यूआरआई को एक JSON ऑब्जेक्ट में परिवर्तित करता है जो उपसेक्यू आरओ JSON संदेश हैंडलर द्वारा ntly संभाला जा सकता है।
डिफ़ॉल्ट हैंडिंग विधि यूआरआई को अनदेखा करना है।
बदलें urhJSON
को URIHandlingMethod
इस तरह एक URI स्वीकार करने के लिए:
http://www.mywebservice.com/json?{JSON OBJECT}
सेट URIHandlingMethod
urhParametersto
को इस तरह एक URI स्वीकार करने के लिए:
unit ROJSONURIIndyHTTPServer ;
interface
uses
SysUtils, Classes,
uROIndyHTTPServer,
IdURI, IdCustomHTTPServer;
type
TURIHandlingMethod = (
urhNone,
urhJSON,
urhParameters
);
TROJSONURIIndyHTTPServer = class(TROIndyHTTPServer)
private
FURIHandlingMethod: TURIHandlingMethod;
FJSONVersion: String;
function ConvertURIToJSON(const Document, Params: String): String;
function NextBlock(var Value: String; Delimiter: Char = '/'): String;
protected
procedure InternalServerCommandGet(AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo); override;
public
constructor Create(AOwner: TComponent); override;
published
property URIHandlingMethod: TURIHandlingMethod read FURIHandlingMethod write FURIHandlingMethod;
property JSONVersion: String read FJSONVersion write FJSONVersion;
end;
implementation
{ TROJSONURIIndyHTTPServer }
constructor TROJSONURIIndyHTTPServer.Create(AOwner: TComponent);
begin
inherited;
FJSONVersion := '1.1';
end;
function TROJSONURIIndyHTTPServer.NextBlock(var Value: String; Delimiter: Char): String;
var
p: Integer;
begin
p := 1;
while (p <= length(Value)) and (Value[p] <> Delimiter) do
Inc(p);
if p = length(Value) then
Result := Value
else
Result := copy(Value, 1, p - 1);
Value := copy(Value, p + 1, MaxInt);
end;
function TROJSONURIIndyHTTPServer.ConvertURIToJSON(const Document, Params: String): String;
const
JSONObjectTemplate = '{"method":"%s.%s"%s,"version": "%s"}';
JSONParamTemplate = '"%s":"%s"';
JSONParamsTemplate = ',"params":{%s}';
var
CallService, CallMessage,
ParsedDocument, ParsedParams, JSONParams,
Param, ParamName, ParamValue: String;
i: Integer;
begin
Result := '';
ParsedDocument := Trim(Document);
// Remove the leading/
if (length(Document) > 0) and
(Document[1] = '/') then
NextBlock(ParsedDocument);
// Remove the message type
NextBlock(ParsedDocument);
// Extract the service
CallService := NextBlock(ParsedDocument);
// Exctract the service message (method)
CallMessage := NextBlock(ParsedDocument);
JSONParams := '';
ParsedParams := Params;
while ParsedParams <> '' do
begin
// Extract the parameter and value
Param := NextBlock(ParsedParams, '&');
// See RFC 1866 section 8.2.1. TP
Param := StringReplace(Param, '+', ' ', [rfReplaceAll]); {do not localize}
// Extract the parameter name
ParamName := NextBlock(Param, '=');
// Extract the parameter value
ParamValue := Param;
// Add a delimiter if required
if JSONParams <> '' then
JSONParams := JSONParams + ',';
// Build the JSON style parameter
JSONParams := JSONParams + format(JSONParamTemplate, [ParamName, ParamValue]);
end;
if JSONParams <> '' then
JSONParams := format(JSONParamsTemplate, [JSONParams]);
// Make sure we have values for all the object variables, then build the JSON object
if (CallService <> '') and
(CallMessage <> '') and
(FJSONVersion <> '') then
Result := format(JSONObjectTemplate, [CallService, CallMessage, JSONParams, JSONVersion]);
end;
procedure TROJSONURIIndyHTTPServer.InternalServerCommandGet(
AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo;
ResponseInfo: TIdHTTPResponseInfo);
begin
if FURIHandlingMethod in [urhJSON, urhParameters] then
begin
// Parse parameters into JSON if required
if FURIHandlingMethod = urhParameters then
RequestInfo.UnparsedParams := ConvertURIToJSON(RequestInfo.Document, RequestInfo.UnparsedParams);
// Decode the URI e.g. converts %20 to whitespace
RequestInfo.UnparsedParams := TIdURI.URLDecode(RequestInfo.UnparsedParams);
// This works around a bug in TROIndyHTTPServer. By adding a whitespace to the
// end of the QueryParams it forces the http server to process the parameters
RequestInfo.QueryParams := TIdURI.URLDecode(RequestInfo.QueryParams) + ' ';
end;
inherited;
end;
end.
:
http://www.mywebservice.com/json/service/method?param1=xxx¶m2=yyy
कोड यह
मूल उत्तर
यह एक आन्द्रे का जवाब देने के लिए अनुवर्ती है।
निम्नलिखित यूआरआई काम करना चाहिए RemObjects एसडीके के वर्तमान संस्करण के साथ
, लेकिन नहीं करता है: इससे पहले कि यह पारित हो जाता है
- यूआरआई डीकोड नहीं है:
http://www.mywebservice.com/JSON?{"id":"{392543cf-f110-4ba3-95471b02ce5bd693}","method":"servicename.methodname","params":{"param1":"xxx","param2":"yyy"}}:
वहाँ 2 कारणों क्यों कर रहे हैं संदेश हैंडलर को। यदि किसी भी वर्ण को एन्कोड किया गया है तो इसका परिणाम JSON त्रुटि में होता है। % 20 आदि
- ROIndyHTTPServer कोड में एक बग प्रतीत होता है जो यूआरआई पैरामीटर को मिशनल करता है।
मैंने एक ROINDYHTTPServer वंशज बनाया है जो दोनों समस्याओं को हल करता है। यहां कोड है:
unit FixedROIndyHTTPServer;
interface
uses
SysUtils, Classes,
uROIndyHTTPServer,
IdURI, IdCustomHTTPServer;
type
TFixedROIndyHTTPServer = class(TROIndyHTTPServer)
protected
procedure InternalServerCommandGet(AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo); override;
public
constructor Create(AOwner: TComponent); override;
end;
implementation
{ TFixedROIndyHTTPServer }
constructor TFixedROIndyHTTPServer.Create(AOwner: TComponent);
begin
inherited;
end;
procedure TFixedROIndyHTTPServer.InternalServerCommandGet(
AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo;
ResponseInfo: TIdHTTPResponseInfo);
begin
// This fixes 2 issues with TROIndyHTTPServer
// 1) It decodes the parameters e.g. converts %20 to whitespace
// 2) It adds a whitespace to the end of the QueryParams. This
// forces the http server to process the parameters.
RequestInfo.QueryParams := TIdURI.URLDecode(RequestInfo.QueryParams) + ' ';
RequestInfo.UnparsedParams := TIdURI.URLDecode(RequestInfo.UnparsedParams);
inherited;
end;
end.
यह मेरे प्रश्न का उत्तर नहीं देता है, लेकिन यह किसी भी समस्या के लिए कामकाज है।
मैं अभी भी सुनना चाहता हूं कि आरओ एसडीके कस्टम यूआरआई के उपयोग का समर्थन करता है या नहीं।
आपको विक्रेता से अधिक प्रत्यक्ष उत्तर मिल जाएगा, connect.remobjects.com पर, यह नहीं कि यह इस प्रश्न के लिए ठीक नहीं है। –
@ वॉरेनपी-आम तौर पर, मैं सहमत हूं - RemObjects के पास बहुत अच्छे उत्पाद हैं, लेकिन उनके समर्थन का जवाब देने में लंबा समय लग सकता है। हालांकि यह यहां तेजी से पोस्ट हो सकता है :) – norgepaul
@ नोर्गपॉल - अगर वे कभी जवाब देते हैं ... – RBA