1

I am using boost for creating JSON string. I am trying to send this JSON string to server via http POST.

Following is the string created by Boost

{"TokenNo":"ABC123456","CPUID":"ABC123456","CommandID":"09","IsEncrypted":"0","CommandString:[{"ADD":"97","ESTBCODE":"99999999","EID":"XY","CID":"0154400000","DATE":"14042015","TIME":"1835","IOMODE":"I","REASONCODE":"55","LAT":"87","LONG":"90"}, {"ADD":"87","ESTBCODE":"99999998","EID":"XX","CID":"0154300000","DATE":"15052015","TIME":"1947","IOMODE":"O","REASONCODE":"54","LAT":"89","LONG":"91"}]}

The above json string is what I expected from the answers of my previous question . But after forming the correct json arrays i am still unable to send this string.

The server needs the JSON string in following format:

{"TokenNo":"ABC123456","CPUID":"ABC123456","CommandID":"09","IsEncrypted":"0","CommandString:[{\"ADD\":\"97\",\"ESTBCODE\":\"99999999\",\"EID\":\"XY\",\"CID\":\"0154400000\",\"DATE\":\"14042015\",\"TIME\":\"1835\",\"IOMODE\":\"I\",\"REASONCODE\":\"55\",\"LAT\":\"87\",\"LONG\":\"90\"}, {\"ADD\":\"87\",\"ESTBCODE\":\"99999998\",\"EID\":\"XX\",\"CID\":\"0154300000\",\"DATE\":\"15052015\",\"TIME\":\"1947\",\"IOMODE\":\"O\",\"REASONCODE\":\"54\",\"LAT\":\"89\",\"LONG\":\"91\"}]}  

Where are the required " \ " ?

Below is my DBAccess.cpp file

using namespace boost::property_tree;
ptree pt;
ptree pt1;
ptree pt2;

//===============XX==============XX================//

list<AttendanceT> sqliteDB::GET_Attendance()
{
        sqlite3 *db;
        const char *sql;
        sqlite3_stmt * stmt;

          /*-----
          Code to access Database
            ------*/


        sqlite3_finalize(stmt);
        sqlite3_close(db);

        return AttendanceT_list;
}

//===============XX==============XX================//

void sqliteDB::writeJson(std::ostream& os) const {

    for (auto &entry : AttendanceT_list) 
    {       
            pt.put("ADD", entry.Atten_Addr);
            pt.put("ESTBCODE", entry.Atten_EstablishmentCode);
            pt.put("EID", entry.Atten_EmployeeID);
            pt.put("CID", entry.Atten_CardID);
            pt.put("DATE", entry.Atten_PunchDate);
            pt.put("TIME", entry.Atten_PunchTime);
            pt.put("IOMODE", entry.Atten_InOutMode);
            pt.put("REASONCODE", entry.Atten_ReasonCode);
            pt.put("LAT", entry.Atten_Lat);
            pt.put("LONG", entry.Atten_Long);

            pt1.push_back(ptree::value_type("", pt));               
    } 

    write_json(os, pt1, false);


}//Function ends here

//===============XX==============XX================//

template <typename List>
void sqliteDB::printList(List const& list)
{
    int s = list.size();
    std::cout << "The number of Records is: " << s << "\n";

    for (auto& r : list) std::cout << r << "";
}

//===============XX==============XX================//

string sqliteDB::dump(sqliteDB const& db)
{
    printList(db.get());
    std::cout << "\n==============[ AS JSON ]===============\n";
    db.writeJson(std::cout);

    std::ofstream file("output1.txt");
 // db.writeJson(file);

    ifstream myReadFile;
    myReadFile.open("output1.txt");
    string output1;
    if (myReadFile.is_open()) 
    {
          while (!myReadFile.eof())
          {
                myReadFile >> output1;
          }
    }

 myReadFile.close();

 return output1;
}

//===============XX==============XX================//

std::string sqliteDB::to_json(POST3 const& o)
{
        pt2.put("TokenNo", o.TokenNo);
        pt2.put("CPUID", o.CPUID);
        pt2.put("CommandID", o.CommandID);
        pt2.put("IsEncrypted", o.IsEncrypted);
        pt2.push_back(ptree::value_type("CommandString", pt1));

        std::ostringstream oss;
        boost::property_tree::write_json(oss, pt2, false);

        std:: string json;
        json = oss.str();


    //=======SENDING(POSTING) DATA TO THE SERVER USING BOOST ASIO======//

      try{/*-----Code of HTTP POST------*/}

      catch (std::exception& e){ }

    return oss.str();
}

//===============XX==============XX================//

Below is content of DbAccess.h file

//=========================//

struct AttendanceT
{
  string Atten_Addr;
  string Atten_EstablishmentCode;
  string Atten_EmployeeID;
  string Atten_CardID;
  string Atten_PunchDate;
  string Atten_PunchTime;
  string Atten_InOutMode;
  string Atten_ReasonCode;
  string Atten_Lat; 
  string Atten_Long; 
};

struct POST3
{
    public:
    std::string TokenNo;
    std::string CPUID;
    std::string CommandID;
    std::string IsEncrypted;
    std::string JSON_Cmnd_String;
};

//=========================//

class sqliteDB {

    public:
     //---
        some other function declaration
     ----//

    void printList(List const& list);
    string dump(sqliteDB const& db);
    string to_json(POST3 const& o);
};

And this is main.cpp file

int main()
{
     sqliteDB object1;

     object1.GET_Attendance();
     object1.dump(object1);

     POST3 obj { "ABC123456", "ABC123456", "09", "0" /*,object1.dump(object1)*/};

     cout << "\nAll the statement were executed properly\n\n\n";

     return 0;
 }

I referred this resource here

I believe I am making some mistake while creating json string but I am not sure where exactly.

UPDATE

The boost Documentation says:

The property tree dataset is not typed, and does not support arrays as such. Thus, the following JSON / property tree mapping is used:

  • JSON objects are mapped to nodes. Each property is a child node.
  • JSON arrays are mapped to nodes. Each element is a child node with an empty name. If a node has both named and unnamed child nodes, it cannot be mapped to a JSON representation.
  • JSON values are mapped to nodes containing the value. However, all type information is lost; numbers, as well as the literals "null", "true" and "false" are simply mapped to their string form.
  • Property tree nodes containing both child nodes and data cannot be mapped.

So, Does that mean Boost does not completely conform to JSON standards ??

Kindly guide me. Thank you

Community
  • 1
  • 1
K.K
  • 401
  • 5
  • 22
  • 1
    Boost doesn't have a JSON parser. Boost Property Tree is a property tree library. – sehe Jun 02 '15 at 08:14
  • @sehe What would you suggest ? I what would be the best way to get the desired JSON format ? – K.K Jun 02 '15 at 08:19
  • 1
    I'd hire a competent programmer. Seriously. I'm writing an answer, but you've been asking questions about this task for months now, and it's not getting any better. I recommend starting much simpler. And doing this in python or similar. – sehe Jun 02 '15 at 08:52
  • As @sehe suggests use something simpler, i.e. header only [rapidjson](https://miloyip.github.io/rapidjson/md_doc_tutorial.html) Another helpful tool is [JSONLint](http://jsonlint.com) where you can validate your json string. – doqtor Jun 02 '15 at 10:50

1 Answers1

0
  • What server requires that? Because it's not JSON: the string "CommandString:[{\"AD... never ends so the array and containing object are incomplete/unclosed.

  • Neither is the first bit though ("string created by Boost"):

    "CommandString:[{"ADD"
    

    is not a valid object property (no : follows the property name).


Q. Where are the required " \ " ?

I'm pretty sure you need another thing:

{"TokenNo":"ABC123456","CPUID":"ABC123456","CommandID":"09","IsEncrypted":"0","CommandString":[{"ADD":"97","ESTBCODE":"99999999","EID":"XY","CID":"0154400000","DATE":"14042015","TIME":"1835","IOMODE":"I","REASONCODE":"55","LAT":"87","LONG":"90"}, {"ADD":"87","ESTBCODE":"99999998","EID":"XX","CID":"0154300000","DATE":"15052015","TIME":"1947","IOMODE":"O","REASONCODE":"54","LAT":"89","LONG":"91"}]}

Or, pretty printed:

{
    "TokenNo": "ABC123456",
    "CPUID": "ABC123456",
    "CommandID": "09",
    "IsEncrypted": "0",
    "CommandString": [{
        "ADD": "97",
        "ESTBCODE": "99999999",
        "EID": "XY",
        "CID": "0154400000",
        "DATE": "14042015",
        "TIME": "1835",
        "IOMODE": "I",
        "REASONCODE": "55",
        "LAT": "87",
        "LONG": "90"
    },
    {
        "ADD": "87",
        "ESTBCODE": "99999998",
        "EID": "XX",
        "CID": "0154300000",
        "DATE": "15052015",
        "TIME": "1947",
        "IOMODE": "O",
        "REASONCODE": "54",
        "LAT": "89",
        "LONG": "91"
    }]
}

Live On Coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>

using Tree = boost::property_tree::ptree;

struct AttendanceT {
    std::string Addr;
    std::string EstablishmentCode;
    std::string EmployeeID;
    std::string CardID;
    std::string PunchDate;
    std::string PunchTime;
    std::string InOutMode;
    std::string ReasonCode;
    std::string Lat;
    std::string Long;

    Tree to_tree() const {
        Tree pt;
        pt.put("ADD",        Addr);
        pt.put("ESTBCODE",   EstablishmentCode);
        pt.put("EID",        EmployeeID);
        pt.put("CID",        CardID);
        pt.put("DATE",       PunchDate);
        pt.put("TIME",       PunchTime);
        pt.put("IOMODE",     InOutMode);
        pt.put("REASONCODE", ReasonCode);
        pt.put("LAT",        Lat);
        pt.put("LONG",       Long);

        return pt;
    }
};

struct POST3 {
    std::string TokenNo;
    std::string CPUID;
    std::string CommandID;
    std::string IsEncrypted;

    std::vector<AttendanceT> AttendanceT_list;

    Tree to_tree() const {
        boost::property_tree::ptree pt;
        pt.put("TokenNo",     TokenNo);
        pt.put("CPUID",       CPUID);
        pt.put("CommandID",   CommandID);
        pt.put("IsEncrypted", IsEncrypted);

        auto& CommandString = pt.put_child("CommandString", {});

        for (auto& obj : AttendanceT_list) 
            CommandString.push_back({ "", obj.to_tree() });

        return pt;
    }
};

static inline std::string to_string(Tree const& tree) {
    std::ostringstream oss;
    boost::property_tree::write_json(oss, tree);
    return oss.str();
}

int main()
{
    std::vector<AttendanceT> list = {
        { "97", "99999999", "XY", "0154400000", "14042015", "1835", "I", "55", "87", "90" },
        { "87", "99999998", "XX", "0154300000", "15052015", "1947", "O", "54", "89", "91" },
    };

    POST3 obj { "ABC123456", "ABC123456", "09", "0", list };

    std::cout << to_string(obj.to_tree());
}

If you really wanted it

You can replace

auto& CommandString = pt.put_child("CommandString", {});

for (auto& obj : AttendanceT_list) 
    CommandString.push_back({ "", obj.to_tree() });

by

Tree CommandString;

for (auto& obj : AttendanceT_list) 
    CommandString.push_back({ "", obj.to_tree() });

pt.put("CommandString", to_string(CommandString));

See it also: Live On Coliru

printing

{
    "TokenNo": "ABC123456",
    "CPUID": "ABC123456",
    "CommandID": "09",
    "IsEncrypted": "0",
    "CommandString": "{\n    \"\": {\n        \"ADD\": \"97\",\n        \"ESTBCODE\": \"99999999\",\n        \"EID\": \"XY\",\n        \"CID\": \"0154400000\",\n        \"DATE\": \"14042015\",\n        \"TIME\": \"1835\",\n        \"IOMODE\": \"I\",\n        \"REASONCODE\": \"55\",\n        \"LAT\": \"87\",\n        \"LONG\": \"90\"\n    },\n    \"\": {\n        \"ADD\": \"87\",\n        \"ESTBCODE\": \"99999998\",\n        \"EID\": \"XX\",\n        \"CID\": \"0154300000\",\n        \"DATE\": \"15052015\",\n        \"TIME\": \"1947\",\n        \"IOMODE\": \"O\",\n        \"REASONCODE\": \"54\",\n        \"LAT\": \"89\",\n        \"LONG\": \"91\"\n    }\n}\n"
}
sehe
  • 374,641
  • 47
  • 450
  • 633