www.gusucode.com > external 工具箱matlab源码程序 > external/interfaces/webservices/http/+matlab/+net/+http/ResponseMessage.m
classdef (Sealed) ResponseMessage < matlab.net.http.Message & matlab.mixin.CustomDisplay %ResponseMessage A response message received from an HTTP server % This object is created by the send() method of matlab.net.http.RequestMessage % containing the response from the server. % % ResponseMessage methods: % ResponseMessage - constructor % complete - complete a message by reconverting % string, char - return contents as a string or character vector % show - return/display contents with optional maximum length % % ResponseMessage properties: % StatusLine - status line from server % StatusCode - status code in StatusLine % Header - header of the message % Body - body of the message % Completed - true if Body is completed % % See also RequestMessage, RequestMessage.send % Copyright 2015-2016 The MathWorks, Inc. properties (Dependent) % StatusLine - status line from server, a matlab.net.http.StatusLine StatusLine end properties (Dependent, SetAccess=immutable) % StatusCode - status code in response, same as StatusLine.StatusCode StatusCode end methods function obj = ResponseMessage(statusLineOrCode, header, body) % ResponseMessage creates an HTTP response message % RESPONSE = ResponseMessage(STATUS,HEADER,BODY) creates a ResponseMessage % with the specified properties. All parameters are optional and may be [] % for placeholders. % STATUS The StatusCode as a string or matlab.net.http.StatusCode % object, or a matlab.net.http.StatusLine % HEADER The header fields: vector of matlab.net.http.HeaderField. % BODY The message body: matlab.net.http.MessageBody or data % acceptable to the MessageBody constructor. % % You do not normally create ResponseMessages because the ResponseMessage % represents data received from the web, returned by the % RequestMessage.send method. This constructor is provided for testing % purposes or to create an expected ResponseMessage for comparison with % a expected server response. % % See also StatusCode, StatusLine, HeaderField, Body, % matlab.net.http.RequestMessage.send if nargin > 0 if ischar(statusLineOrCode) || isstring(statusLineOrCode) || ... isa(statusLineOrCode, 'matlab.net.http.StatusCode') import matlab.net.http.*; obj.StatusLine = StatusLine([],statusLineOrCode); else if isempty(statusLineOrCode) obj.StatusLine = []; else validateattributes(statusLineOrCode, ... {'matlab.net.http.StatusLine','matlab.net.http.StatusCode','string'}, {'scalar'}, ... mfilename, 'STATUS'); if isa(statusLineOrCode, 'matlab.net.http.StatusCode') obj.StatusLine = StatusLine(statusLineOrCode); else obj.StatusLine = statusLineOrCode; end end end if nargin > 1 obj.Header = header; if nargin > 2 obj.Body = body; end end end obj.Completed = false; end function code = get.StatusCode(obj) if isempty(obj.StatusLine) code = []; else code = obj.StatusLine.StatusCode; end end function value = get.StatusLine(obj) value = obj.StartLine; end function obj = set.StatusLine(obj, value) obj.StartLine = value; end function obj = complete(obj) % complete Process or reprocess the response payload Content-Type % MSG = complete(MSG) returns a copy of the message, converting % MSG.Body.Payload to MSG.Body.Data using the current value of the % Content-Type header field in MSG. % % You do not normally need to use this method, since received data is % converted automatically. Use this method when Body.Data was not set % properly, or we left unset, because the server inserted the wrong % Content-Type in the message or the Content-Type was missing, or if you % set HTTPOptions.ConvertResponse to false to prevent conversion of the % data when it was originally received. If there was an exception % processing the received message, or if you set HTTPOptions.SavePayload % when you sent the request, the Body.Payload in this ResponseMessage will % contain the original payload (if any). Then you can modify the header of % this message to add or correct the Content-Type field and then call % complete() to process the response as if the server had inserted that % Content-Type field originally, and the result will be new contents in % Body.Data. % % If Body.Payload is set, this method ignores the current value of % Body.Data and processes that payload based on Content-Type. This would % be the case on any conversion error or if you specified SavePayload. But % if conversion of the incoming data succeeded originally, but was % incorrect, Body.Data will be set and Body.Payload may be empty. In this % case you can change the ContentTypeField in the received message to the % desired type and call this method. This method will try to convert the % data back to a original payload based on the original content type (saved % in Body.ContentType), and then reconvert it using the new Content-Type % header in the ResponseMessage. The returned Body.Payload will always be % set if Data is nonempty. % % As an example, assume the server returned a response containing JSON % string but specified a Content-Type field of 'text/plain' instead of % 'application/json', and you did not specify HTTPOptions.SavePayload. In % this case, conversion of payload to data would have succeeded, so % Body.Payload will be empty and Body.Data will contain an ASCII string % (since the default charset for 'text/plain' is us-ascii). To reprocess % this data and obtain a JSON structure instead: % % % The following also sets response.Completed to false % response = response.changeFields('Content-Type','application/json'); % response = response.complete(); % jsonData = response.Body.Data; % % The above call to complete() will convert Body.Data to Body.Payload using % us-ascii encoding, and then reconvert Body.Payload to utf-8 (the default % charset for application/json) before processing it as a JSON string and % storing the result in Body.Data. This conversion will fail to resurrect % any non-ASCII characters that were garbled when converting the original % payload using 'text/plain', but will preserve the original data if it was % all ASCII. % % In cases where the payload had to be resurrected from the data for % reconversion, the original length of the payload will be remembered, when % displayed by functions such as show. % % If you had set HTTPOptions.SavePayload when sending the message, the % original payload that was preserved in Body.Payload would have been used % instead, with no loss of information. % % This method returns the original message unaltered if Completed is already % set. In a ResponseMessage that contains a payload, this property is % normally set only if Body.Payload has been preserved and was converted to % Body.Data without an error. % % See also Body, matlab.net.http.HTTPOptions.ConvertResponse, % matlab.net.http.HTTPOptions.SavePayload, Completed, show matlab.net.http.internal.nargoutWarning(nargout,mfilename,'complete'); if obj.Completed return; else if ~isempty(obj.Body.ContentCoding) error(message('MATLAB:http:CannotCompleteEncodedResponse', ... char(strjoin(obj.Body.ContentCoding, ', ')))); end end % we always complete, even if we do nothing, unless we throw exception obj.Completed = true; if isempty(obj.Body) return; else end payload = obj.Body.Payload; contentTypeField = obj.getSingleField('Content-Type'); % errors if >1 if isempty(contentTypeField) newMediaType = []; else newMediaType = contentTypeField.convert(); end oldMediaType = obj.Body.ContentType; if newMediaType == oldMediaType % contentType not changed; do nothing return; end % ContentType changed if isempty(payload) % We have data but not payload. data = obj.Body.Data; if isempty(data) % No data or payload; done return; else end if isempty(oldMediaType) % If the oldMediaType was empty it means we didn't convert the payload at all, % so just copy Data to Payload so we can try again. assert(isa(data,'uint8')) obj.Body.PayloadInt = obj.Body.DataInt; payload = obj.Body.PayloadInt; else % Payload was deleted and data was converted. Need to unconvert data back to % derive the original payload. This doesn't reliably get us back to the actual % payload, because conversions are not necessarily reversible, but it's as % good as we can do. It probably fails miserably if the conversion involves % anything other than charsets. payload = matlab.net.http.internal.data2payload(data, oldMediaType); % If PayloadLength is set, don't change it, as it retains the length % of the original payload. obj.Body.PayloadInt = payload; end if isempty(obj.Body.PayloadLength) obj.Body.PayloadLength = length(payload); end end if ~isempty(payload) % New we have a (possibly new) payload. Convert it to data. obj.Body.DataInt = ... matlab.net.http.internal.readContentFromWebService(payload, newMediaType, true); obj.Body.ContentType = newMediaType; end obj.Completed = true; % above resets, so need to set again end end methods (Access=protected) function group = getPropertyGroups(obj) % Provide a custom display that removes StartLine (inherited from Message), % as it's redundant with StatusLine. Also displays StatusLine as string. group = getPropertyGroups@matlab.mixin.CustomDisplay(obj); if isscalar(obj) group.PropertyList = rmfield(group.PropertyList,'StartLine'); group.PropertyList.StatusLine = char(group.PropertyList.StatusLine); end end end methods (Static, Access=protected) function checkHeader(~) end function checkBody(~) end function type = getStartLineType() type = 'matlab.net.http.StatusLine'; end function badField = getInvalidFields(~) % All fields valid in Response badField = []; end function tf = shouldSetBodyContentType() % Return false to indicate that we don't want to set the body's ContentType % when the ContentTypeField in this message is set. This is because we want % the body's original ContentType to be preserved so that complete() can undo % the original conversion before converting it to the desired type. The % body's ContentType in a ResponseMessage should only be set by the % infrastructure when a message is originally received. tf = false; end end end