I am trying to parse JSON response using cppRest Library, but an exception is raised instead the JSON object, here is the error that is show below:
Incorrect Content-Type: must be textual to extract_string, JSON to extract_json.
And here is my code that I have tried so far:
#include <iostream>
#include <cpprest/http_client.h>
using namespace web::http;
using namespace web::http::client;
using namespace web;
using namespace std;
int main()
{
uri url(L"http://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0");
http_client client(url);
http_response response;
http_request req;
req.set_method(methods::GET);
req.headers().set_content_type(L"application/json");
response = client.request(req).get();
try
{
json::object json_object(response.extract_json().get().as_object());
}
catch (exception &e)
{
cout << e.what() << "\n";
}
return 0;
}
I solved my problem, looks like I need to set the response headers to get the received content type as json:
Updated my code:
#include <iostream>
#include <cpprest/http_client.h>
using namespace web::http;
using namespace web::http::client;
using namespace web;
using namespace std;
int main()
{
uri url(L"http://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0");
http_client client(url);
http_request req;
req.set_method(methods::GET);
pplx::task<json::value> requestTask = client.request(req).then([](http_response response)
{
json::value jsonObject;
try
{
if ( response.status_code() == status_codes::OK )
{
response.headers().set_content_type(L"application/json"); // Set headers to receive content type as JSON
jsonObject = response.extract_json().get();
}
}
catch (const http_exception& e)
{
cout << e.error_code().message() << "\n";
}
return jsonObject; // returned a json value
});
json::array dataseries = requestTask.get().at(L"dataseries").as_array(); // We get the returned response here
for (size_t i = 0; i < dataseries.size(); i++)
{
auto timepoint = dataseries[i].at(L"timepoint");
wcout << timepoint << endl;
}
return 0;
}
Related
I'm currently working in C++, getting an HTTP response from a request that I write into a .txt file using ostream. This happens asynchronously and I don't want to change this.
Once the data is done being written, I want to read from the file
{"data":{"request":[{"type":"City","query":"London, United Kingdom"}],"weather":[{"date":"2013-04-21","astronomy".....
~somehow~ prettify the string using either an outside library like nlohmann/json or other(?) and then
a)print it to the console and
b) save it in a different file (pretty.json)
I am having trouble understanding which method to use from:
https://github.com/nlohmann/json
Any ideas how to approach this?
I was thinking getting the file line by line until I hit EOF into a sort of "buffer" and then running _json on that and saving the solution which can be displayed on the console...
My code so far
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include <sstream>
#include "json.hpp"
using namespace utility; // string conversion
using namespace web; // URI
using namespace web::http; // HTTP commands
using namespace web::http::client; // HTTP Client features
using namespace concurrency::streams; // Asynch streams, like Node
using json = nlohmann::json;
int main()
{
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.txt"))
.then([=](ostream outFile)
{
*fileStream = outFile;
http_client client //gets the info
return client.request(methods::GET, stringBuilder.to_string());
})
.then([=](http_response response) // set up response handler
{
printf("Received response status code:%u\n", response.status_code());
return response.body().read_to_end(fileStream->streambuf());
})
.then([=](size_t) // close file stream
{
return fileStream->close();
})
.then([=]()
{
nlohmann::json j;
std::ifstream i;
i.open("results.txt"); // ?? <<< === this is where my question is
});
// Wait for all the outstanding I/O to complete, handle exceptions
try
{
requestTask.wait();
}
catch (const std::exception &e)
{
printf("Error exception:%s\n", e.what());
}
return 0;
}
SOLUTION:
.then([=]()
{
// read a JSON file
std::ifstream readFromFile("results.txt");
if (readFromFile.is_open()) {
nlohmann::json j;
readFromFile >> j;
// write prettified JSON to another file
std::ofstream writeToFile("pretty.json");
writeToFile << std::setw(4) << j << std::endl;
readFromFile.close();
writeToFile.close();
}
else {
std::cout << "unable to open file";
}
});
You have two choices to prettify with nlohmann.
Uses dump which produces a string
int indent = 4;
nlohmann::json data;
data.dump(indent);
Or use the stream output overload with field width set
std::ofstream o("pretty.json");
o << std::setw(4) << data << std::endl;
I recently started to use C++ Rest SDK and I'm trying to send an audio buffer to Watson Speech to Text service and the docs didn't make clear to me how to use or upload a buffer using this lib, I started using a Microsfot sample to upload files(https://msdn.microsoft.com/en-us/library/jj950081.aspx) and then a I tried to modify the code to send a buffer as the examples (https://msdn.microsoft.com/en-us/library/jj950083.aspx), but I for some how doesn't work.
This is my current code:
My current code:
#include <codecvt>
#include <cpprest/containerstream.h>
#include <cpprest/http_client.h>
#include <iostream>
#include <cpprest/producerconsumerstream.h>
#include <cpprest/rawptrstream.h>
#include <cpprest/json.h>
#include "ReqHTTP.h"
#include <sstream>
#include <fstream>
#include <Windows.h>
using namespace std;
using namespace web;
using namespace concurrency;
using namespace concurrency::streams;
using namespace web::http;
using namespace web::http::client;
using namespace utility::conversions;
#pragma comment(lib, "winmm.lib")
pplx::task<void> RequestHTTP::UploadFileToHttpServerAsync(streams::ostream outStream, LPSTR buffer)
{
container_buffer<LPSTR> outAudioBuffer(move(buffer));
return outStream.write(outAudioBuffer, outAudioBuffer.size()).then([](size_t
bytesWritten)
{
try {
http_client_config config;
credentials cred(L"c674021d-5a0f-4ec1-84a4-da6fbd50541c", L"WvYMlztHWCbC");
config.set_credentials(cred);
http_request req(methods::POST);
req.headers().add(L"Transfer-Encoding", L"chunked");
req.headers().add(L"Content-Type", L"audio/wav");
req.set_request_uri(L"speech-to-text/api/v1/recognize?continuous=true&model=pt-BR_BroadbandModel");
req.set_body(bytesWritten);
// Make HTTP request with the file stream as the body.
http_client client(L"https://stream.watsonplatform.net/", config);
//concurrency::streams::producer_consumer_buffer<uint8_t> buf;
//buf.putn_nocopy(&body[0], body.size());
return client.request(req).then([bytesWritten](pplx::task<http_response> previousTask)
{
//buffer.close;
std::wostringstream ss;
try
{
auto response = previousTask.get();
response.extract_json().then([=](json::value js) {
int i = 0;
auto campo = js.at(to_string_t("results"));
while (i < campo.size()) {
auto transc = campo.operator[](i).operator[](to_string_t("alternatives")).operator[](0);
wcout << transc.at(to_string_t("transcript")) << endl;
i++;
}
});
}
catch (const http_exception& e)
{
ss << e.what() << std::endl;
}
std::wcout << ss.str();
});
}
catch (const std::system_error& e)
{
std::wostringstream ss;
ss << e.what() << std::endl;
std::wcout << ss.str();
// Return an empty task.
return pplx::task_from_result();
}
});
}
I got the following code from internet. I expect it to print contents of post request of any URL.It is printing ->Added new Id: {"listOfAssets":[{"assetName":"Gold Asset"}]}->which is correct.I guess this is a string output. I want output in json which I need to convert to C++(serialize) Can someone advice what more should I do?I am running the code in linux environment.1st let me know how to get json output.serializing can be done later. To do this I added 2lines
It is giving me errors
terminate called after throwing an instance of 'web::http::http_exception'
what(): Incorrect Content-Type: must be textual to extract_string, JSON to extract_json.
#include <cpprest/http_client.h>
#include <pplx/pplxtasks.h>
#include <cpprest/json.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <cpprest/details/http_constants.dat>
#include <cpprest/http_msg.h>
using namespace std;
using namespace web;
using namespace web::json;
using namespace pplx;
using namespace web::http;
using namespace web::http::client;
using namespace web::http::details;
pplx::task<int> Post()
{
return pplx::create_task([]
{
json::value postData;
postData["name"] = json::value::string("Joe Smith");
postData["sport"] = json::value::string("Baseball");
http_client client("http://54.191.233.99:8080/sparkAPIs/testing.html");
return client.request(methods::POST, "",
/*postData.serialize().c_str(),*/ "application/json");
}).then([](http_response response)
{
if(response.status_code() == status_codes::OK)
{
//auto body = response.extract_string();
//std::cout << "Added new Id: " << body.get().c_str() << std::endl;
auto body = response.extract_json();
body.get();
//return std::stoi(body.get().c_str());
}
return 0;
});
}
int main()
{
cout<<"hello world"<<endl;
Post().wait();
}
I am trying to make a program that can display a JSON file in console with C++'s REST API. I'm trying to get the JSON file from api.trello.com but every example I come across gives me an error, usually about cbegin() & cend() and how it is not a value of web::json::value...
here is my code:
// The code includes the most frequently used includes necessary to work with C++ REST SDK
#include "cpprest/containerstream.h"
#include "cpprest/filestream.h"
#include "cpprest/http_client.h"
#include "cpprest/json.h"
#include "cpprest/producerconsumerstream.h"
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
using namespace ::pplx;
using namespace utility;
using namespace concurrency::streams;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
// Retrieves a JSON value from an HTTP request.
pplx::task<void> RequestJSONValueAsync()
{
// TODO: To successfully use this example, you must perform the request
// against a server that provides JSON data.
// This example fails because the returned Content-Type is text/html and not application/json.
http_client client(L"website.com/theRealURLContainsSecretKeys");
return client.request(methods::GET).then([](http_response response) -> pplx::task<json::value>
{
if (response.status_code() == status_codes::OK)
{
return response.extract_json();
}
// Handle error cases, for now return empty json value...
return pplx::task_from_result(json::value());
})
.then([](pplx::task<json::value> previousTask)
{
try
{
const json::value& v = previousTask.get();
// Perform actions here to process the JSON value...
}
catch (const http_exception& e)
{
// Print error.
wostringstream ss;
ss << e.what() << endl;
wcout << ss.str();
}
});
/* Output:
Content-Type must be application/json to extract (is: text/html)
*/
}
// Demonstrates how to iterate over a JSON object.
void IterateJSONValue()
{
// Create a JSON object.
json::value obj;
obj[L"key1"] = json::value::boolean(false);
obj[L"key2"] = json::value::number(44);
obj[L"key3"] = json::value::number(43.6);
obj[L"key4"] = json::value::string(U("str"));
// Loop over each element in the object.
for (auto iter = obj.cbegin(); iter != obj.cend(); ++iter)
{
// Make sure to get the value as const reference otherwise you will end up copying
// the whole JSON value recursively which can be expensive if it is a nested object.
const json::value &str = iter->first;
const json::value &v = iter->second;
// Perform actions here to process each string and value in the JSON object...
std::wcout << L"String: " << str.as_string() << L", Value: " << v.to_string() << endl;
}
/* Output:
String: key1, Value: false
String: key2, Value: 44
String: key3, Value: 43.6
String: key4, Value: str
*/
}
int wmain()
{
// This example uses the task::wait method to ensure that async operations complete before the app exits.
// In most apps, you typically don�t wait for async operations to complete.
wcout << L"Calling RequestJSONValueAsync..." << endl;
RequestJSONValueAsync().wait();
wcout << L"Calling IterateJSONValue..." << endl;
//IterateJSONValue();
system("pause");
}
I am having this error in VS 2015.
The only errors are in IterateJSONValue()
What is my problem and how can I fix it?
json::value does not contain a member function cbegin(). If you access obj.as_object() or obj.as_array() you will find your begin/end members.
// Loop over each element in the object.
for (const auto &pr : obj.as_object()) {
std::wcout << L"String: " << pr.first << L", Value: " << pr.second << endl;
}
when i build my own cpprestsdk server and client,i found that when my server receive a request and reply to it, my client have no reaction to it,and it never goes into the breakpoint where i handle the http_response,here is my code;
i was stuck for so many days,will someone help me fix this,thanks a lot
(client send request,server receives it and reply, client fail to receive http_response)
Server(i just got it from somewhere on internet):
#include "cpprest/json.h"
#include "cpprest/http_listener.h"
#include "cpprest/uri.h"
#include "cpprest/asyncrt_utils.h"
#include "cpprest/http_client.h"
using namespace web::http::experimental::listener;
using namespace web::http;
using namespace web;
void handle_get(http_request message)
{
message.reply(status_codes::OK, U("Hello, World!"));
};
void handle_post(http_request message)
{
message.reply(status_codes::NotFound);
};
void handle_put(http_request message)
{
message.reply(status_codes::NotFound);
};
void handle_delete(http_request message)
{
message.reply(status_codes::NotFound);
};
#define TRACE(msg) std::wcout << msg
#define TRACE_ACTION(a, k, v) std::wcout << a << L" (" << k << L", " << v << L")\n"
int main(int argc, char ** argv)
{
uri_builder uri(U("http://localhost:8888"));
http_listener listener(uri.to_uri());
listener.support(methods::GET, handle_get);
listener.support(methods::POST, handle_post);
listener.support(methods::PUT, handle_put);
listener.support(methods::DEL, handle_delete);
try
{
listener
.open()
.then([&listener](){TRACE(L"\nstarting to listen\n"); })
.wait();
while (true);
}
catch (std::exception const & e)
{
std::wcout << e.what() << std::endl;
}
catch (...)
{
std::wcout << "Unknown exception" << std::endl;
}
return 0;
}
and here is my Client
#include "cpprest/http_client.h"
#include "cpprest/filestream.h"
using namespace utility; // Common utilities like string conversions
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
int main(int argc, char* argv[])
{
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.html")).then([=](ostream outFile)
{
*fileStream = outFile;
// Create http_client to send the request.
http_client client(U("http://www.bing.com/"));
http_client localclient(U("http://localhost:8888"));
return localclient.request(methods::GET);
})
.then([=](http_response response)
{
printf("Received response status code:%u\n", response.status_code());
system("pause");
return response.body().read_to_end(fileStream->streambuf());
})
.then([=](size_t)
{
return fileStream->close();
});
try
{
requestTask.wait();
}
catch (const std::exception &e)
{
printf("Error exception:%s\n", e.what());
system("pause");
}
return 0;
}