程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> JSON 在C++中的使用

JSON 在C++中的使用

編輯:C++入門知識

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對象的值轉換成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的源代碼。

摘自 sheismylife的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved