nor*_*aul 5 delphi uri remobjects delphi-xe2
我们有一个RemObjects SDK HTTP服务器,它公开了许多服务和方法.是否可以通过URI调用方法,而不是将参数作为SOAP/JSON传递,例如
http://www.mywebservice.com/servicename/methodname?param1=xxx¶m2=yyy
Run Code Online (Sandbox Code Playgroud)
更新
\n\n我编写了服务器后代的改进版本。该函数将格式化的 URI 转换为 JSON 对象,随后由 RO JSON 消息处理程序处理。
\n\n默认处理方法是忽略 URI。
\n\n更改URIHandlingMethod为urhJSON接受如下 URI:
http://www.mywebservice.com/json?{JSON OBJECT}\nRun Code Online (Sandbox Code Playgroud)\n\n设置URIHandlingMethod为urhParametersto接受这样的 URI:
http://www.mywebservice.com/json/service/method?param1=xxx¶m2=yyy\nRun Code Online (Sandbox Code Playgroud)\n\n这是代码:
\n\nunit ROJSONURIIndyHTTPServer ;\n\ninterface\n\nuses\n SysUtils, Classes,\n\n uROIndyHTTPServer,\n\n IdURI, IdCustomHTTPServer;\n\ntype\n TURIHandlingMethod = (\n urhNone,\n urhJSON,\n urhParameters\n );\n\n TROJSONURIIndyHTTPServer = class(TROIndyHTTPServer)\n private\n FURIHandlingMethod: TURIHandlingMethod;\n FJSONVersion: String;\n\n function ConvertURIToJSON(const Document, Params: String): String;\n function NextBlock(var Value: String; Delimiter: Char = \'/\'): String;\n protected\n procedure InternalServerCommandGet(AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo); override;\n public\n constructor Create(AOwner: TComponent); override;\n published\n property URIHandlingMethod: TURIHandlingMethod read FURIHandlingMethod write FURIHandlingMethod;\n property JSONVersion: String read FJSONVersion write FJSONVersion;\n end;\n\nimplementation\n\n{ TROJSONURIIndyHTTPServer }\n\nconstructor TROJSONURIIndyHTTPServer.Create(AOwner: TComponent);\nbegin\n inherited;\n\n FJSONVersion := \'1.1\';\nend;\n\nfunction TROJSONURIIndyHTTPServer.NextBlock(var Value: String; Delimiter: Char): String;\nvar\n p: Integer;\nbegin\n p := 1;\n\n while (p <= length(Value)) and (Value[p] <> Delimiter) do\n Inc(p);\n\n if p = length(Value) then\n Result := Value\n else\n Result := copy(Value, 1, p - 1);\n\n Value := copy(Value, p + 1, MaxInt);\nend;\n\nfunction TROJSONURIIndyHTTPServer.ConvertURIToJSON(const Document, Params: String): String;\nconst\n JSONObjectTemplate = \'{"method":"%s.%s"%s,"version": "%s"}\';\n JSONParamTemplate = \'"%s":"%s"\';\n JSONParamsTemplate = \',"params":{%s}\';\nvar\n CallService, CallMessage,\n ParsedDocument, ParsedParams, JSONParams,\n Param, ParamName, ParamValue: String;\n i: Integer;\nbegin\n Result := \'\';\n\n ParsedDocument := Trim(Document);\n\n // Remove the leading /\n if (length(Document) > 0) and\n (Document[1] = \'/\') then\n NextBlock(ParsedDocument);\n\n // Remove the message type\n NextBlock(ParsedDocument);\n\n // Extract the service\n CallService := NextBlock(ParsedDocument);\n\n // Exctract the service message (method)\n CallMessage := NextBlock(ParsedDocument);\n\n JSONParams := \'\';\n ParsedParams := Params;\n\n while ParsedParams <> \'\' do\n begin\n // Extract the parameter and value\n Param := NextBlock(ParsedParams, \'&\');\n\n // See RFC 1866 section 8.2.1. TP\n Param := StringReplace(Param, \'+\', \' \', [rfReplaceAll]); {do not localize}\n\n // Extract the parameter name\n ParamName := NextBlock(Param, \'=\');\n\n // Extract the parameter value\n ParamValue := Param;\n\n // Add a delimiter if required\n if JSONParams <> \'\' then\n JSONParams := JSONParams + \',\';\n\n // Build the JSON style parameter\n JSONParams := JSONParams + format(JSONParamTemplate, [ParamName, ParamValue]);\n end;\n\n if JSONParams <> \'\' then\n JSONParams := format(JSONParamsTemplate, [JSONParams]);\n\n // Make sure we have values for all the object variables, then build the JSON object\n if (CallService <> \'\') and\n (CallMessage <> \'\') and\n (FJSONVersion <> \'\') then\n Result := format(JSONObjectTemplate, [CallService, CallMessage, JSONParams, JSONVersion]);\nend;\n\nprocedure TROJSONURIIndyHTTPServer.InternalServerCommandGet(\n AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo;\n ResponseInfo: TIdHTTPResponseInfo);\nbegin\n if FURIHandlingMethod in [urhJSON, urhParameters] then\n begin\n // Parse parameters into JSON if required\n if FURIHandlingMethod = urhParameters then\n RequestInfo.UnparsedParams := ConvertURIToJSON(RequestInfo.Document, RequestInfo.UnparsedParams);\n\n // Decode the URI e.g. converts %20 to whitespace\n RequestInfo.UnparsedParams := TIdURI.URLDecode(RequestInfo.UnparsedParams);\n\n // This works around a bug in TROIndyHTTPServer. By adding a whitespace to the\n // end of the QueryParams it forces the http server to process the parameters\n RequestInfo.QueryParams := TIdURI.URLDecode(RequestInfo.QueryParams) + \' \';\n end;\n\n inherited;\nend;\n\nend.\nRun Code Online (Sandbox Code Playgroud)\n\n原答案
\n\n这是 Andr\xc3\xa9\ 答案的后续内容。
\n\n对于当前版本的 RemObjects SDK,以下 URI 应该可以工作,但不能:
\n\nhttp://www.mywebservice.com/JSON?{"id":"{392543cf-f110-4ba3-95471b02ce5bd693}","method":"servicename.methodname","params":{"param1":"xxx","param2":"yyy"}}:\nRun Code Online (Sandbox Code Playgroud)\n\n原因有两个:
\n\n我创建了一个 ROIndyHTTPServer 后代来解决这两个问题。这是代码:
\n\nunit FixedROIndyHTTPServer;\n\ninterface\n\nuses\n SysUtils, Classes,\n\n uROIndyHTTPServer,\n\n IdURI, IdCustomHTTPServer;\n\ntype\n TFixedROIndyHTTPServer = class(TROIndyHTTPServer)\n protected\n procedure InternalServerCommandGet(AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo); override;\n public\n constructor Create(AOwner: TComponent); override;\n end;\n\nimplementation\n\n{ TFixedROIndyHTTPServer }\n\nconstructor TFixedROIndyHTTPServer.Create(AOwner: TComponent);\nbegin\n inherited;\nend;\n\nprocedure TFixedROIndyHTTPServer.InternalServerCommandGet(\n AThread: TIdThreadClass; RequestInfo: TIdHTTPRequestInfo;\n ResponseInfo: TIdHTTPResponseInfo);\nbegin\n // This fixes 2 issues with TROIndyHTTPServer\n // 1) It decodes the parameters e.g. converts %20 to whitespace\n // 2) It adds a whitespace to the end of the QueryParams. This\n // forces the http server to process the parameters.\n\n RequestInfo.QueryParams := TIdURI.URLDecode(RequestInfo.QueryParams) + \' \';\n RequestInfo.UnparsedParams := TIdURI.URLDecode(RequestInfo.UnparsedParams);\n\n inherited;\nend;\n\nend.\nRun Code Online (Sandbox Code Playgroud)\n\n这并没有回答我的问题,但对于任何有类似问题的人来说,这是一种解决方法。
\n\n我仍然很想知道 RO SDK 是否支持使用自定义 URI。
\n