網絡接口如下圖:
返回信息是一個json格式的字符串:{"errorMsg":"登錄成功!","result":"1","sign":"56519e7b026a4f0e82eeb6496fd5c555"}
現在我想用TIdhttp控件來傳遞json格式的數據。那么它的方法是Get(AURL:string,AResponseContent:TStream);根據意思可知第二個參數是TStream類型的返回值。
那么下面參數aURL:string,aURL:=‘http://xxx.xxx.xxx.xxx/web/login!doLogin?data='+jo.ToString;
jo:TJsonObject;通過AddPair()添加數值對。用的是ToString方法。
如果我的jo(json)不是這樣寫的,我直接通過字符串jsontosend:TStringStream;jsontosend:=tstringream.creat('{"password":"yy123","userCode":"yy123","terminalCode":"123"}');那么get的時候就是get(aURL+jsontosend.DataString);
注意:這個時候用get(aURL+jsontosend.ToString);是會格式錯誤的。
中文亂碼問題:
就是關於第二個參數aResponseContent,(要重命名)
aResponseContent:TStringStream
aResponseContent:=TStringStream.create(' ',65001);這樣就可以了。至於這個65001請參考:http://blog.sina.com.cn/s/blog_549f50ec01019cgc.html
把它寫到TMemo中:Memo1.lines.add(aResponseContent.DataString);
下面是源碼:可能沒什么用在實現部分uses DBXjson,如果不知道該引用什么,先選擇變量或方法,右鍵,Refactor--Find Unit。添加一個就好了。
- procedure TForm1.btnTestClick(Sender: TObject);
- var
- jo: tjsonobject;
- jp: tjsonpair;
- responsejson: tstringstream;
- aURL: string;
- http: TIdcustomHTTP;
- begin
- jo := tjsonobject.Create;
- try
- jp := tjsonpair.Create('terminalCode', TEterminalcode.Text);
- jo.AddPair(jp);
- jp := tjsonpair.Create('password', TEpassword.Text);
- jo.AddPair(jp);
- jo.AddPair('userCode', tjsonstring.Create(TEusercode.Text));
- aURL := 'http://112.64.158.30:7777/web/login!doLogin?data=';
- responsejson := tstringstream.Create('', 65001);
- http := TIdHTTP.Create(nil);
- http.HandleRedirects := true;
- http.ReadTimeout := 3000;
- http.Request.Accept := 'text/javascript';
- http.Request.ContentType := 'application/json';
- http.Request.CharSet := 'utf-8';
- http.Request.ContentEncoding := 'utf-8';
- responsejson := tstringstream.Create('', 65001);
- http.Get(aURL + jo.ToString, responsejson);
- Memo1.Lines.Add(responsejson.DataString);
- finally
- jo.Free;
- responsejson.Free;
- http.Free;
- end;
- end;
這個post方法怎么用都不對,后來才知道,http.Request.ContentType := 'application/json'是不對的,應該改為:http.Request.ContentType := 'application/x-www-form-urlencoded';這樣就對了。郁悶死,大概服務器接收的不是json類型。關於這類問題可以查看MIME。
- var
- jo: tjsonobject;
- jp: tjsonpair;
- jsontosend: tstringstream;
- responsestr: string;
- aURL: string;
- http: TIdcustomHTTP;
- begin
- jo := tjsonobject.Create;
- try
- jp := tjsonpair.Create('terminalCode', TEterminalcode.Text);//生成tjsonpair
- jo.AddPair(jp);
- jp := tjsonpair.Create('password', TEpassword.Text);
- jo.AddPair(jp);
- jo.AddPair('userCode', tjsonstring.Create(TEusercode.Text));
- aURL := 'http://xxx.xxx.xxx.xxx/web/login!doLogin';
- http := TIdHTTP.Create(nil);
- http.HandleRedirects := true;
- http.ReadTimeout := 3000;
- // http.Request.ContentType := 'application/json';
- http.Request.ContentType := 'application/x-www-form-urlencoded';
- http.Request.CharSet := 'utf-8';
- http.Request.ContentEncoding := 'utf-8';//可以省略,目前感覺沒用。
- jsontosend := tstringstream.Create('data=' + jo.ToString);
- responsestr := http.Post(aURL, jsontosend);//jsontosend是要發送的json參數
- if getjsonvalue(responsestr, 'errorMsg') = '登錄成功!' then//由於參數不同,返回結果不同,需要判斷一下。可以無視
- TEerrorcode.Text := '0'
- else
- TEerrorcode.Text := getjsonvalue(responsestr, 'errorCode');//下面的是顯示json解析結果的,可以無視。
- TEresult.Text := getjsonvalue(responsestr, 'result');
- TEerrorMsg.Text := getjsonvalue(responsestr, 'errorMsg');
- TEsign.Text := getjsonvalue(responsestr, 'sign');
- finally
- jo.Free;
- http.Free;
- end;
解析json的函數:其實不用這么麻煩,因為要解析的json格式相同,所以寫了一個外部unit。下面是這個getjsonvalue函數:
- unit UnitJSON;
- interface
- uses DBXJSON, DBXJSONReflect, System.SysUtils;
- function getJSONValue(jsonstr: string; jsonvalue:string): string;
- implementation
- function getJSONValue(jsonstr: string; jsonvalue:string): string;
- var
- jo: tjsonobject;
- jv: tjsonvalue;
- begin
- jo := nil;
- try
- jo := tjsonobject.Create;
- jo := tjsonobject.ParseJSONValue(tencoding.UTF8.GetBytes(jsonstr), 0)
- as tjsonobject;
- jv := jo.Get(jsonvalue).jsonvalue;
- Result := jv.Value;
- finally
- jo.Free;
- end;
- end;
- end.
詳細的json字符串解析可以看我寫的相關帖子,比較詳細,也很容易理解。
http://blog.csdn.net/syndicater/article/details/17302857