带鉴权的JSON POST请求代码排错及实现方法
问题说明
需要向目标接口POST提交包含认证信息的JSON数据,同时读取接口返回的JSON响应结果,现有编写的代码运行异常,需排查错误并给出正确实现方式。
基础信息
- 接口地址:
api.abc.com/getlist/ - 待提交JSON入参定义:
jsoninput = { "MERCHANT":"merchid", "MERCHANT_KEY":"merchkey", "START_DATE":"2022-01-01", "END_DATE":"2022-02-02" }
原问题代码
ServerAdress = "api.abc.com"; Resource = "getlist"; ssl1 = new OpenSSLSecureConnection(Undefined, Undefined); HTTP = New HTTPConnection(ServerAdress,443,,,,10,ssl1); HTTPRequest = New HTTPRequest("getlist"); HTTPRequest.Headers.Insert("Authorization", jsoninput); HTTPRequest.Headers.Insert("Accept", "application/json"); HTTPRequest.Headers.Insert("Content-Type","application/x-www-form-urlencoded"); HTTPRequest.Headers.Insert("Accept-Language", "en_US"); HTTPRequest.Headers.Insert("Cache-Control", "no-cache"); HTTPRequest.SetBodyFromString("grant_type=client_credentials"); Connection = New HTTPConnection("api.abc.com",,,,,10,New OpenSSLSecureConnection); JSONReader = New JSONReader; Try HTTPAnswer = Connection.Post(HTTPRequest); // post Request JSONReader.SetString(HTTPAnswer.GetBodyAsString()); Data = ReadJSON(JSONReader, False); message(Data); Except ErrorText = "Sending " + ErrorDescription(); message(ErrorText); EndTry;
现存代码错误
- 连接实例重复创建且配置缺失:提前初始化了带443 HTTPS端口、自定义SSL配置的
HTTP连接对象但全程未使用,后续新建的Connection实例未指定端口,默认走80端口发起HTTP请求,和接口要求的HTTPS协议不匹配,无法正常建立连接。 - 请求路径配置错误:初始化
HTTPRequest时传入的路径为getlist,和接口要求的/getlist/路径不一致,会触发接口404路由错误。 - 参数位置错误:直接将结构化的
jsoninput对象插入Authorization请求头,既不符合Authorization请求头的格式规范,也未将业务认证参数放到请求体的正确位置,服务端无法读取到有效认证信息。 - Content-Type与载荷不匹配:需要提交JSON格式数据,却将
Content-Type设置为application/x-www-form-urlencoded表单类型,服务端会按表单规则解析请求,导致JSON参数无法被识别。 - 请求体内容不符合需求:实际写入请求体的内容是
grant_type=client_credentials表单字符串,完全没有传入预先定义的jsoninput业务参数,接口收不到必填入参必然返回异常。 - 结构化数据未做序列化:直接将对象类型的
jsoninput插入请求头的操作未做JSON序列化,网络传输层无法直接解析语言层面的结构化对象,会触发类型不匹配错误。
正确实现代码
// 基础配置 ServerAdress = "api.abc.com"; RequestPath = "/getlist/"; // 初始化SSL配置与HTTPS连接(指定443端口) sslConfig = new OpenSSLSecureConnection(Undefined, Undefined); httpConn = New HTTPConnection(ServerAdress, 443, , , , 10, sslConfig); // 定义入参并序列化为JSON字符串 jsoninput = { "MERCHANT":"merchid", "MERCHANT_KEY":"merchkey", "START_DATE":"2022-01-01", "END_DATE":"2022-02-02" } set tJSONWriter = ##class(%JSON.Formatter).%New() do tJSONWriter.ToString(jsoninput, .jsonBodyStr) // 初始化请求,配置正确请求头 httpRequest = New HTTPRequest(RequestPath); httpRequest.Headers.Insert("Accept", "application/json"); httpRequest.Headers.Insert("Content-Type","application/json"); httpRequest.Headers.Insert("Accept-Language", "en_US"); httpRequest.Headers.Insert("Cache-Control", "no-cache"); // 写入序列化后的JSON请求体 do httpRequest.SetBodyFromString(jsonBodyStr) // 发起请求并解析响应 JSONReader = New JSONReader; Try HTTPAnswer = httpConn.Post(httpRequest); // 校验响应状态码,可根据业务规则调整成功判定逻辑 if HTTPAnswer.StatusCode != 200 { write "请求失败,状态码:" _ HTTPAnswer.StatusCode return } JSONReader.SetString(HTTPAnswer.GetBodyAsString()); Data = ReadJSON(JSONReader, False); message(Data); Except ErrorText = "请求发送失败:" + ErrorDescription(); message(ErrorText); EndTry;
注意:如果接口要求认证信息放在
Authorization头而非请求体中,可根据接口实际鉴权规则(如Bearer、Basic、自定义签名等)调整头内容,不要直接把业务JSON对象塞入Authorization头。
内容的提问来源于stack exchange,提问作者dberdi
相关产品推荐
相关产品推荐

