使用C++restSDK调用Binance RESTful API的JSON解析问题排查
Hey there, let's break down your JSON parsing issue with the Binance REST API and Microsoft's cpprestsdk. You mentioned the problem is likely in your print_test function, and that makes sense—cpprestsdk's web::json::value requires type-specific handling, and skipping that will lead to broken parsing or exceptions.
Common Pitfall in Your Original Code
The core issue is that you're not checking the type of the json::value before accessing its data. Binance's API returns different JSON structures (objects, arrays, strings, numbers) depending on the endpoint, and calling methods like as_string() on an object or array will throw a json_exception.
Fixed print_test Function
Here's a revised version that handles all common JSON types recursively, so it works with any Binance API response:
void print_test(json::value const & value){ if(!value.is_null()){ // Handle JSON objects (key-value pairs) if (value.is_object()) { auto obj = value.as_object(); for (const auto& key_value_pair : obj) { const std::string& key = key_value_pair.first; const json::value& val = key_value_pair.second; std::cout << "* " << key << ": "; print_test(val); // Recurse to handle nested values std::cout << "\n"; } } // Handle JSON arrays else if (value.is_array()) { auto arr = value.as_array(); std::cout << "[ "; for (size_t i = 0; i < arr.size(); ++i) { if (i > 0) std::cout << ", "; print_test(arr[i]); } std::cout << " ]"; } // Handle primitive types else if (value.is_string()) { std::cout << "\"" << value.as_string() << "\""; } else if (value.is_number()) { if (value.is_integer()) { std::cout << value.as_integer(); } else { std::cout << value.as_double(); } } else if (value.is_boolean()) { std::cout << (value.as_bool() ? "true" : "false"); } } }
Debugging Tips to Confirm the Issue
- Print Raw API Response
Before parsing, output the raw string response to verify you're getting valid JSON from Binance:try { auto response = client.request(methods::GET, "/api/v3/ticker/price?symbol=BTCUSDT").get(); // Print raw response first std::string raw_response = response.extract_string().get(); std::cout << "Raw Binance Response:\n" << raw_response << "\n\n"; // Now parse to JSON json::value json_data = response.extract_json().get(); print_test(json_data); } catch (const web::json::json_exception& e) { std::cerr << "\nJSON Parsing Error: " << e.what() << "\n"; } catch (const std::exception& e) { std::cerr << "\nGeneral Error: " << e.what() << "\n"; } - Catch Exceptions
cpprestsdk throws specific exceptions for JSON type mismatches. Catchingweb::json::json_exceptionwill tell you exactly where the parsing failed (e.g., trying to convert an array to a string). - Match Binance's API Structure
Refer to Binance's REST API docs to know what structure to expect:- Endpoints like
/api/v3/ticker/pricereturn a single object - Endpoints like
/api/v3/klinesreturn an array of arrays
Knowing this helps you write targeted parsing code instead of relying solely on a generic print function.
- Endpoints like
内容的提问来源于stack exchange,提问作者runesbane

