Web Core TMS中解析API返回JSON并提取字段值的问题
问题:无法解析API返回的JSON并提取字段值
API调用能收到正确响应,响应内容如下:
{ "success": true, "data": { "accessToken": "eyJ0eXAiOiJKV1QiL....", "token_type": "bearer" }, "message": "Login Successful" }
但无法保存accessToken、token_type、success以及message的值,当前代码如下:
procedure TForm1.WebButton1Click(Sender: TObject); var AccessToken, TokenType: String; begin AccessToken := ''; TokenType := ''; APIConnection.URL := 'https://aaa/api/login'; APIConnection.Command := httpPOST; APIConnection.Headers.Clear; APIConnection.Headers.AddPair('Content-Type','application/json'); APIConnection.Headers.AddPair('Accept','application/json, text/plain, */*'); APIConnection.PostData := '{"email":"test@yahoo.com","password":"123456789"}'; APIConnection.Execute( procedure(AResponse: String; AReq: TJSXMLHttpRequest) var js: TJSON; ja: TJSONArray; jo: TJSONObject; i: Integer; begin js := TJSON.Create; try ja := TJSONArray(js.Parse(AResponse)); ShowMessage('Retrieved items:' + IntToStr(ja.Count)); for i := 0 to ja.Count - 1 do begin jo := TJSONObject(ja.Items[i]); WebListBox1.Items.Add(jo.GetJSONValue('data')); end; finally js.Free; end; end ); end;
测试发现Execute回调中的AResponse为空,但在APIConnectionRequestResponse事件中能拿到正确响应:
procedure TForm1.APIConnectionRequestResponse(Sender: TObject; ARequest: TJSXMLHttpRequestRecord; AResponse: string); var JS : TJSON; begin JS := TJson.Create; showmessage('Response: '+AResponse+' :END'); end;
请求指导如何正确解析该JSON响应并提取所需字段值。
解决方案
1. 切换响应处理入口
既然APIConnectionRequestResponse事件能稳定获取到正确响应,直接在这个事件中完成JSON解析和字段提取,比依赖Execute回调更可靠。
2. 修正JSON解析逻辑
API返回的是JSON对象(外层为{}),不是JSON数组([]),原代码错误地用TJSONArray解析,导致解析失败。需改用TJSONObject处理。
3. 完整修改代码示例
procedure TForm1.APIConnectionRequestResponse(Sender: TObject; ARequest: TJSXMLHttpRequestRecord; AResponse: string); var js: TJSON; rootObj: TJSONObject; dataObj: TJSONObject; success: Boolean; accessToken, tokenType, msg: string; begin // 空响应直接退出 if AResponse.IsEmpty then Exit; js := TJSON.Create; try // 解析根JSON对象 rootObj := TJSONObject(js.Parse(AResponse)); if not Assigned(rootObj) then Exit; // 提取顶层字段 success := rootObj.GetValue<TBoolean>('success'); msg := rootObj.GetValue<string>('message'); // 提取data子对象及内部字段 dataObj := rootObj.GetValue<TJSONObject>('data'); if Assigned(dataObj) then begin accessToken := dataObj.GetValue<string>('accessToken'); tokenType := dataObj.GetValue<string>('token_type'); end; // 弹出验证提取结果 ShowMessage(Format('Success: %s'#13#10'Message: %s'#13#10'AccessToken: %s'#13#10'TokenType: %s', [BoolToStr(success, True), msg, accessToken, tokenType])); // 根据需求将值保存到全局变量或控件 // AccessToken := accessToken; // TokenType := tokenType; finally js.Free; end; end;
4. 关键注意事项
- 避免强制类型转换:不要直接用
TJSONArray(js.Parse(...)),优先用泛型方法GetValue<T>,安全且不易出错。 - 空值检查:解析子对象(如
data)时,必须先判断是否为nil,防止空指针异常。 - 若坚持使用
Execute回调:检查组件文档,确认是否需要手动从TJSXMLHttpRequest对象中获取响应(比如调用AReq.responseText)。
内容的提问来源于stack exchange,提问作者user41758
相关产品推荐
相关产品推荐

