JSON 在C++中的使用

來源:互聯網
上載者:User
CppCMS的編譯和使用

請參考我的相關文章。

將C++對象轉換成JSON字串

假定有一個類response,兩個欄位,一個是status,0代表正確。其他代表錯誤。另一個是message欄位,表示操作結果的具體資訊。代碼如下:

class response {public:    //0 is ok    //other values are wrong    int status;    string message;};

現在需要將response對象的資料轉換成JSON格式字串。還需要寫一個模板類來,代碼如下:

namespace cppcms {    namespace json {        template<>        struct traits<response> {            static void set(value &v, response const& in) {                v.set("status", in.status);                v.set("message", in.message);            }        };    }}

好,現在編寫調用代碼,並查看運行結果。

#include <cppcms/json.h>...int main(int argc, char** argv) {    response r1;    r1.status=0;    r1.message="ok";    cout<< cppcms::json::value(r1)<<endl;    response r2;    r2.status=1;    r2.message="unknown error";    cout<< cppcms::json::value(r2)<<endl;    return 0;}

運行結果:
{"message":"ok","status":0}
{"message":"unknown error","status":1}

cppcms::json::value類程式碼分析

之所以很容易就轉換成JSON串,是因為使用了value類。現在來分析一下上面的調用代碼裡面是如何工作的。
1.cppcms::json::value(r1) 建立了匿名對象value,value的建構函式內部調用了set_value方法。參數v此時就是response對象。

template<typename T>        value(T const &v)        {                set_value(v);        }

2.set_value方法調用了traits<T>::set(this,v),這個就是前面我們重載的模板方法。

template<typename T>        void set_value(T const &v)        {                traits<T>::set(this,v);        }

3.剩下的事情目的很明確了,需要將value對象的屬性按照key,value的形式儲存在map中。最後轉換成JSON字串,然後輸出到流中。Artyom重載了operator<<函數,底層實現函數如下:

std::ostream &operator<<(std::ostream &out,value const &v)        {                v.save(out);                return out;        }        void value::save(std::ostream &out,int how) const        {                int tabs=(how & readable) ? 0 : -1;                write(out,tabs);        }        void value::write(std::ostream &out,int tabs) const        {                std::locale original(out.getloc());                out.imbue(std::locale("C"));                try {                        write_value(out,tabs);                }                catch(...) {                        out.imbue(original);                        throw;                }                out.imbue(original);        }        void value::write_value(std::ostream &out,int tabs) const        {                switch(type()) {                case json::is_undefined:                        throw bad_value_cast("Can't write undefined value to stream");                case json::is_null:                        out<<"null";                        break;                case json::is_number:                        out<<std::setprecision(std::numeric_limits<double>::digits10+1)<<number();                        break;                case json::is_string:                        out<<escape(str());                        break;                case json::is_boolean:                        out<< (boolean() ? "true" : "false") ;                        break;                case json::is_array:                        {                                json::array const &a=array();                                unsigned i;                                indent(out,'[',tabs);                                for(i=0;i<a.size();) {                                        a[i].write_value(out,tabs);                                        i++;                                        if(i<a.size())                                                indent(out,',',tabs);                                }                                indent(out,']',tabs);                        }                        break;                case json::is_object:                        {                                json::object const &obj=object();                                object::const_iterator p,end;                                p=obj.begin();                                end=obj.end();                                indent(out,'{',tabs);                                while(p!=end) {                                        out<<escape(p->first);                                        indent(out,':',tabs);                                        p->second.write_value(out,tabs);                                        ++p;                                        if(p!=end)                                                indent(out,',',tabs);                                }                                indent(out,'}',tabs);                        }                        break;                default:                        throw bad_value_cast("Unknown type found: internal error");                }        }

上面的程式碼封裝含了很多細節,很多都可以獨立成文描述。這裡主要是為了搞明白cppcms::json::value內部的設計原理,便於更好的使用。就暫時追蹤到這裡。

將JSON字串轉換成C++對象

下面的代碼示範了如何將流裡面的JSON串放入value對象,然後通過get方法尋找,"null"是假定找不到的時候的預設值。

stringstream stream;    stream << "{\"message\":\"ok\",\"status\":0}";    cppcms::json::value value2;    stream >> value2;    string m = value2.get("message","null");

也可以用更嚴格的get方法的重載,沒有預設值,如果找不到就會拋出bad_cast異常。

///        /// Get an object of type T from the path \a path. Throws bad_value_cast if such path does not        /// exists of conversion can't be done        ///        template<typename T>        T get(std::string const &path) const        {                return at(path).get_value<T>();        }

我不喜歡寫篇幅很大的文章,本篇主要描述如何使用,順便挖了一下原始碼。後面會陸續深挖CppCMS的原始碼。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.