web service calling problem? - web-services

When I call a web service data does not come in the proper way. Some blocks are there string, integer, chars are there means mixed data in json form.
1) When I use this approch to convert the data...
StringBuffer sb = new StringBuffer();
byte[] buf = new byte[256];
int n = 0;
while ((n = StrReader.read(buf)) > 0)
{
sb.append(new String(buf,0,n));
}
String returnContent = sb.toString();
System.out.println(new String(returnContent));
StrReader.close();
}
output...
text/htmlj
~"115.252.128.200", "roles": { "1": "anonymous user" }, "session": "", "cache": 0 } } }
No stack trace
2) and when I use this approch to convert the data...
dis = new DataInputStream(hc.openInputStream());
byte[] data1 = new byte[20];
int len = 0;
StringBuffer strBuffer = new StringBuffer();
while ( -1 != (len = dis.read(data1)) )
{
received = new String(data1, 0, len);
System.out.println(received);
}
OUTPUT....
text/html
j
~Salse, "#data": { "se
ssid": "fef51cf48aca
46e3b3aedafc02860f25
", "user": { "uid":
0, "hostname": "115.
252.128.200", "roles
": { "1": "anonymous
user" }, "session":
"", "cache": 0 } }
}
Outer---->>>}
No stack trace
NOTE.... the 'received' variable loses our data when it come out of loop...

The question appears to be: why does the local variable 'received' have only a fragment of the text that is printed to the console. It is because the variable is assigned a new string for each batch of bytes that are read from the DataInputStream.
This code does not appear to concisely get the job done - why use a DataInputStream for example - so perhaps asking about the larger task at hand will be more useful.

Related

How to remove or erase a "key":"value" pair in a Json::Value object using "key"?

I am working in C++ language, visual studio 2022, and using jsoncpp library for working with Json.
To Give you an Idea, here is an example of Json data I am working with
[
{
"name":"Regina Eagle",
"job":"Biologist",
"salary":"728148120",
"email":"Regina_Eagle6155#y96lx.store",
"city":"Nashville"
},
{
"name":"Julius Baker",
"job":"Fabricator",
"salary":"299380360",
"email":"Julius_Baker9507#voylg.center",
"city":"Las Vegas"
},
{
"name":"Rocco Sawyer",
"job":"Chef Manager",
"salary":"223764496",
"email":"Rocco_Sawyer4620#qu9ml.club",
"city":"San Francisco"
},
{
"name":"Chad Murray",
"job":"Project Manager",
"salary":"43031808",
"email":"Chad_Murray6940#jcf8v.store",
"city":"Bridgeport"
},
{
"name":"Rocco Parker",
"job":"Lecturer",
"salary":"322089172",
"email":"Rocco_Parker202#ag5wi.solutions",
"city":"Indianapolis"
}
]
It's a Json array of objects (with key:value pairs).
I have a set of column heads for eg: {"name","job","salary"}, and I want to sort the json data in a way that each object will have only columns that are in the given set.
This is my approach:
Store json data in a Json::Value object (let us say records).
Iterate through records (as it is an array).
Creating another loop to Iterate through object stored at each index.
Extract the key of the key:value pair and check if it's present in the set or not.
If it's present then continue, else if it isn't then remove that key:value entry from there.
This way we can delete unwanted column while looping through the object.
Here, is the code snippet:
set<string> col {"name","job","salary"};
Json::Value records = [
{
"name":"Regina Eagle",
"job":"Biologist",
"salary":"728148120",
"email":"Regina_Eagle6155#y96lx.store",
"city":"Nashville"
},
{
"name":"Julius Baker",
"job":"Fabricator",
"salary":"299380360",
"email":"Julius_Baker9507#voylg.center",
"city":"Las Vegas"
},
{
"name":"Rocco Sawyer",
"job":"Chef Manager",
"salary":"223764496",
"email":"Rocco_Sawyer4620#qu9ml.club",
"city":"San Francisco"
},
{
"name":"Chad Murray",
"job":"Project Manager",
"salary":"43031808",
"email":"Chad_Murray6940#jcf8v.store",
"city":"Bridgeport"
},
{
"name":"Rocco Parker",
"job":"Lecturer",
"salary":"322089172",
"email":"Rocco_Parker202#ag5wi.solutions",
"city":"Indianapolis"
}
];
for (int i = 0; i<records.size(); i++)
{
for (auto j = records[i].begin(); j != records[i].end(); j++)
{
string key = j.key().asString();
if (col.find(key) != col.end())
{
continue;
}
else
{
records[i].removeMember(key);
}
}
}
It works fine until the 'removeMember' function get to run, and throws an error saying can't increment the value of iterator.
Expression: cannot increment value-initialized map/set iterator
Am I doing something wrong?
Or there is another/better way of doing this ?
Please advice.
Don't remove or add elements in a container you're currently iterating.
The JSON objects are stored in a std::map and removeMember calls std::map::erase. It invalidates the current iterator and it can't be incremented anymore. j++ causes the error.
One approach is to first only store the keys of properties you want to delete, and then to delete the properties in a separate loop.
set<string> col {"name","job","salary"};
Json::Value records = [
{
"name":"Regina Eagle",
"job":"Biologist",
"salary":"728148120",
"email":"Regina_Eagle6155#y96lx.store",
"city":"Nashville"
},
{
"name":"Julius Baker",
"job":"Fabricator",
"salary":"299380360",
"email":"Julius_Baker9507#voylg.center",
"city":"Las Vegas"
},
{
"name":"Rocco Sawyer",
"job":"Chef Manager",
"salary":"223764496",
"email":"Rocco_Sawyer4620#qu9ml.club",
"city":"San Francisco"
},
{
"name":"Chad Murray",
"job":"Project Manager",
"salary":"43031808",
"email":"Chad_Murray6940#jcf8v.store",
"city":"Bridgeport"
},
{
"name":"Rocco Parker",
"job":"Lecturer",
"salary":"322089172",
"email":"Rocco_Parker202#ag5wi.solutions",
"city":"Indianapolis"
}
];
for (int i = 0; i<records.size(); i++)
{
std::vector<std::string> toRemove;
for (auto j = records[i].begin(); j != records[i].end(); j++)
{
string key = j.key().asString();
if (col.find(key) != col.end())
{
continue;
}
else
{
// records[i].removeMember(key);
toRemove.push_back(key);
}
}
for (const auto &key : toRemove)
{
records[i].removeMember(key);
}
}

UE4 C++ I can't get Json Nested Values to TArray

I'm doing a GET Request to an online API but I can't get nested Json values to set to an array in C++ (Unreal Engine 4).
I got all values except nested array LE (key)
Here is JSON
{
"Id": 8,
"Nome": "Name",
"DataInicial": "2018-10-01T00:00:00",
"DataFinal": "2018-12-31T00:00:00",
"VL": 270174.982,
"CN": 461,
"Met": 354940,
"PM": 76.118493829943088972784132529,
"LE": [
{
"Id": 25,
"Nome": "Suco",
"Cor": "#510077",
"ValorNegociacaoGanha": 57772.452,
"CountNegociacaoGanha": 107,
"Meta": 66700,
"PercentualMeta": 86.61537031484257871064467766
},
{
"Id": 23,
"Nome": "Espumante",
"Cor": "#edd865",
"ValorNegociacaoGanha": 52494.03,
"CountNegociacaoGanha": 93,
"Meta": 66700,
"PercentualMeta": 78.701694152923538230884557721
}
]
}
Here is important code
void AHttpActor::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) {
//Create a pointer to hold the json serialized data
TSharedPtr<FJsonObject> JsonObject;
//Create a reader pointer to read the json data
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
//Deserialize the json data given Reader and the actual object to deserialize
if (FJsonSerializer::Deserialize(Reader, JsonObject)) {
//Get the value of the json object by field name
int32 id = JsonObject->GetIntegerField("Id");
FString nome = JsonObject->GetStringField("Nome");
FString DataInicial = JsonObject->GetStringField("DataInicial");
FString DataFinal = JsonObject->GetStringField("DataFinal");
double VN = JsonObject->GetNumberField("VN");
int32 CN = JsonObject->GetIntegerField("CN");
int32 Met = JsonObject->GetIntegerField("Met");
double PM = JsonObject->GetNumberField("PM");
//Add data to array
Arr1.Emplace(FString::FromInt(id));
Arr1.Emplace(nome);
Arr1.Emplace(DataInicial);
Arr1.Emplace(DataFinal);
Arr1.Emplace(FString::SanitizeFloat(VN));
Arr1.Emplace(FString::FromInt(CN));
Arr1.Emplace(FString::FromInt(Met));
Arr1.Emplace(FString::SanitizeFloat(PM));
UE_LOG(LogTemp, Warning, TEXT("===== GET LE ====="));
//FString teste = JsonObject->GetField("LE");
//UE_LOG(LogTemp, Warning, TEXT(teste));
//ArrSuco = JsonObject->GetArrayField("LE");
//TArray<TSharedPtr<FJsonValue>> objArray = JsonObject->GetArrayField("LE");
//ArrTeste = JsonObject->GetArrayField("LE");
//GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, "printing LE...");
UE_LOG(LogTemp, Warning, TEXT("===== printing LE... ====="));
auto arr = JsonObject->GetArrayField("LE");
for (int32 index = 0; index < arr.Num(); index++)
{
//GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, "name:" + FString(objArray[index]->AsString()));
UE_LOG(LogTemp, Warning, TEXT("TESTE"));
//ArrSuco
if (index == 0) {
//ArrSuco.Emplace(FString::FromInt();
UE_LOG(LogTemp, Warning, TEXT("Index = 0"));
//FString teste = arr[0].Value;
//auto arr2 = arr[0].Get()->TryGetArray;
//UE_LOG(LogTemp, Warning, TEXT(arr[0].Get()->AsString()));
//GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, FString(sucoId));
//UE_LOG(LogTemp, Warning, TEXT(FString(arr[index]["Id"])));
//ArrSuco.Append(FString(arr[index]["Id"]), arr[index].Num());
//ArrSuco.Emplace(FString::FromInt(id));
//ArrSuco.Emplace(nome);
}
//ArrEspumante
else if (index == 1) {
UE_LOG(LogTemp, Warning, TEXT("Index = 1"));
}
//ArrCerveja
else if (index == 2) {
UE_LOG(LogTemp, Warning, TEXT("Index = 2"));
}
//ArrVinho
else if (index == 3) {
UE_LOG(LogTemp, Warning, TEXT("Index = 3"));
}
//UE_LOG(LogTemp, Warning, TEXT(objArray[index]->AsString()));
//UE_LOG(LogTemp, Warning, TEXT(FString(ArrSuco[index])));
}
//Count Array
//int32 CountArr = ArrSuco.Num();
}
}
I can print all (LE) indexes tests if (index == 0), but I can't put it to an array.
I really don't know how to get it, I'm stuck here all the day.
Did you try something like:
TArray<TSharedPtr<FJsonValue>> arr = JsonObject->GetArrayField("LE");
for (int32 index = 0; index < arr.Num(); index++)
{
TSharedPtr<FJsonObject> obj = arr[index]->AsObject();
/* get the object's fields:
obj->GetStringField("Nome");
*/
}

How to get JSON objects value using casablanca in C++

I am new to Json. And i m using codeplex (casablanca) for reading the json values.
Below is the sample json string:
[{ "rollno": 2000,
"name": "suhani","marks":{"grade":"C"} }, {"rollno": 3000,"name": "ishu", "marks":{ "grade":"A"} }]
The code to access name & rollno, i am writing below code:
json::value jobj = json::value::parse(utility::conversions::to_string_t(resultbody));
for (unsigned int i = 0; i < jobj.size(); i++) {
auto getval = jobj[i];
if (getval.at(U("name")).is_string()) {
auto xstr = getval.at(U("name")).as_string();
std::string wide = utility::conversions::to_utf8string(xstr);
std::string str(wide.begin(), wide.end());
string name = str;
}
if (getval.at(U("rollno")).is_integer()) {
auto xstr = getval.at(U("rollno")).as_integer();
int rollno = xstr;
} }
HOW TO GET VALUE AT GRADE ?? When i access marks it is of type object, i am not getting how to access grade from there. Please respond.
Marks is still a json object. You'll need to access the grade property. From your code snippet add the following:
for (unsigned int i = 0; i < jobj.size(); i++) {
auto getval = jobj[i];
auto marks_object = getval.at(U("marks"));
auto grade_value = marks_object.at(U("grade")).as_string();

Create a json array in C++

So im trying to create a json Object in c++ dynamically. I want to add a timestamp and then an array with the data included.
So thats what my json String would look like :
{
"timestep": "2160.00",
"vehicles": [
{
"id": "35092_35092_353",
"x": "6.988270",
"y": "50.872139",
"angle": "-20.812787",
"type": "passenger_P_14_1",
"speed": "0.000000",
"pos": "4.600000",
"lane": "4.600000",
"slope": "4.600000"
},
{
"id": "35092_35092_353",
"x": "6.988270",
"y": "50.872139",
"angle": "-20.812787",
"type": "passenger_P_14_1",
"speed": "0.000000",
"pos": "4.600000",
"lane": "4.600000",
"slope": "4.600000"
},
{
"id": "35092_35092_353",
"x": "6.988270",
"y": "50.872139",
"angle": "-20.812787",
"type": "passenger_P_14_1",
"speed": "0.000000",
"pos": "4.600000",
"lane": "4.600000",
"slope": "4.600000"
}
]
}
Im totally new to C++ and im using the Casablanca ( C++ REST SDK) package.
So im having a really hard time producing the code. And i cant find any working solutions. I found this on the wiki
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"));
and that works for me. But how do i create an array?
i tried several things but nothing worked. Maybe theres a better package? But as far as i understood its an official micorosft package for json and http.
Help would be really nice!
There are 2 mechanisms. If you are used to std c++ libraries, this should look familiar. Element vector is derived from std::vector.
json::value::element_vector e;
// the first item in the pair is the array index, the second the value
e.push_back(std::make_pair(json::value(0), json::value(false)));
e.push_back(std::make_pair(json::value(1), json::value::string(U("hello"))));
json::value arr(e);
And, if you prefer a cleaner look, and can accept a less efficient compiled result:
json::value arr;
arr[0] = json::value(false);
arr[1] = json::value(U("hello"));
From your message you have tried a bunch of stuff. If you have tried mechanisms like these but they didn't work, give us a sample program that demontrates the failure and we'll have a crack at it.
To get the basic structure in your file above:
json::value vehicles;
vehicles[0] = // 1st vehicle object
vehicles[1] = // 2nd vehicle object
// etc
json::value root;
root[L"timestep"] = json::number(2160.0);
root[L"vehicles"] = vehicles;
Here's how to create an array dynamically using vector. Assume that you have 10 vehicles to add.
std::vector<web::json::value> arrayVehicles;
for(int i = 0; i < 10; i++)
{
web::json::value vehicle;
std::string vehicleID = "id_prefix_" + std::to_string(i);
vehicle["id"] = web::json::value::string(vehicleID);
vehicle["x"] = web::json::value::number(6.988270);
vehicle["y"] = web::json::value::number(50.872139);
arrayVehicles.push_back(vehicle);
}
web::json::value myJSON;
myJSON["vehicles"] = web::json::value::array(arrayVehicles);
You could put it like this:
json::value vehicle1;
vehicle1[L"id"] = json::value::string(L"35092_35092_353");
vehicle1[L"x"] = json::value::number(6.988270);
vehicle1[L"y"] = json::value::number(50.872139);
json::value vehicle2;
vehicle2[L"id"] = json::value::string(L"35092_35092_353");
vehicle2[L"x"] = json::value::number(1.23456);
vehicle2[L"y"] = json::value::number(6.78901);
json::value vehicles;
vehicles[L"timestamp"] = json::value::number(2160);
vehicles[L"vehicles"] = json::value::array({vehicle1, vehicle2});
Here is another method to produce a json array in Casablanca:
int size = 3;
web::json::value yourJson;
yourJson[U("vehicles")] = web::json::value::array(size);
yourJson[U("vehicles")].as_array()[0] = web::json::value(U("some entry"));
yourJson[U("vehicles")].as_array()[1] = web::json::value(U("another entry"));
//...
If you wish to use the array as an answer on a received http_request (in case below it's a http_request request), you are free to use the following snippet of code as an example:
json::value answer;
auto array = answer.array();
for (size_t i = 0; i < GenFile.GetNumberOfCurves(); i++)
{
web::json::value vehicle;
vehicle[L"smth"] = web::json::value::number(WhatEverArray[i].whatever());
array[i] = vehicle;
}
request.reply(status_codes::OK, array);
The following sample json C++ array of strings works for me.
const char * const line_items_items =
"[\
{\
\"commodity_code\": \"44121903\",\
\"description\": \"Miscellaneous goods\",\
\"upc\": \"65100004327\",\
\"quantity\": \"2\",\
\"unit_of_measurement\": \"M62\",\
\"unit_cost\": \"23.09\",\
\"discount_amount\": \"10.03\",\
\"total_amount\": \"50.03\",\
\"tax_amount\": \"10.05\",\
\"extended_amount\": \"76.04\",\
\"debit_or_credit_indicator\": \"credit\",\
\"net_or_gross_indicator\": \"net\"\
},\
{\
\"commodity_code\": \"44121809\",\
\"description\": \"Miscellaneous goods\",\
\"upc\": \"65100007654\",\
\"quantity\": \"4\",\
\"unit_of_measurement\": \"M66\",\
\"unit_cost\": \"35.09\",\
\"discount_amount\": \"5.06\",\
\"total_amount\": \"0.53\",\
\"tax_amount\": \"8.07\",\
\"extended_amount\": \"96.12\",\
\"debit_or_credit_indicator\": \"debit\",\
\"net_or_gross_indicator\": \"gross\"\
}\
]";

Why is this encrypted message damaged?

I use the following code to encrypt a string with a key, using the 3-DES algorithm:
private bool Encode(string input, out string output, byte[] k, bool isDOS7)
{
try
{
if (k.Length != 16)
{
throw new Exception("Wrong key size exception");
}
int length = input.Length % 8;
if (length != 0)
{
length = 8 - length;
for (int i = 0; i < length; i++)
{
input += " ";
}
}
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.Zeros;
des.Key = k;
ICryptoTransform ic = des.CreateEncryptor();
byte[] bytePlainText = Encoding.Default.GetBytes(input);
MemoryStream ms = new MemoryStream();
CryptoStream cStream = new CryptoStream(ms,
ic,
CryptoStreamMode.Write);
cStream.Write(bytePlainText, 0, bytePlainText.Length);
cStream.FlushFinalBlock();
byte[] cipherTextBytes = ms.ToArray();
cStream.Close();
ms.Close();
output = Encoding.Default.GetString(cipherTextBytes);
}
catch (ArgumentException e)
{
output = e.Message;
//Log.Instance.WriteToEvent("Problem encoding, terminalID= "+objTerminalSecurity.TerminalID+" ,Error" + output, "Security", EventLogEntryType.Error);
return false;
}
return true;
}
I send the output parameter as is over to a WCF http-binding webservice, and I noticed that the actual encoded string looks different, it looks like there are some \t and \n but the charachters are about the same.
What is going on, why does the server get a different encoded string?
Usually cipher text is base64 encoded in an effort to be binary safe during transmission.
Also I would not use 3DES with ECB. That is awful, you must have copy pasted this from somewhere. Use AES with cbc mode and think about adding a cmac or hmac.