• json2jsoncpp 高级应用篇


    上一篇文章已经简单介绍了json2jsoncpp的基本功能以及下载地址(已经更新linux/mac/win)。本篇将介绍json2jsoncpp的一个高级功能(类似RPC的功能)

    为了方便描述,我在这里以及以后将json2jsoncpp简称为j2jc

    上一篇文章的介绍,其实j2jc的功能实际上就是吧一个json数据格式文档转换为一个或多个类,所以只需要少许代码便可以实现rpc功能了,其中代码中要包含:

    1:过程名(类名)

    2:解析json并且调用相对于的过程或者是生成相对应的对象

    这样就实现了一个无返回值的rpc

    其实就是代码要实现 拿到一个json数据就自动生成一个相对应的类对象

    这里j2jc已经帮你实现了

    你只需要先生成一个h头文件:

    json2jsoncpp test.json test.h j

    请不要少打了这个j

    test.json

    {
    
    
       //先给你的json数据包格式起个名字叫做rpc1
       "rpc1" 
       : 
       {
    
          "age":16,//年龄
          "hp":99,//
          "mp":88//魔法
    
       }
    
    
    }

    自动会生成test.h

    //charset:
    
    #ifndef test_h
    #define test_h
    
    #include <vector>
    #include <string>
    #include "json/json.h"
    #include "json2jsoncpp.h"
    
    //////////////////////////////////////////////////////////////////////////
    //先给你的json数据包格式起个名字叫做rpc1
    class rpc1:public json2jsoncpp
    {
    private:
        virtual bool decodesuccess(){return true;}
    
        static string2object * NEW()
        {
            return new rpc1;
        }
    
    public:
        static bool REG(newobjfun fun=0)
        {
            if(fun)return string2object::REG("rpc1",fun);
            else return string2object::REG("rpc1",NEW);
        }
    
        static bool UNREG()
        {
            return string2object::UNREG("rpc1");
        }
    
        rpc1()
        {
            age = 16;
            hp = 99;
            mp = 88;
        }
    
        void reset()
        {
            age = 16;
            hp = 99;
            mp = 88;
        }
    
        bool decode(std::string json)
        {
            Json::Reader jr;
            Json::Value jv;
            if(!jr.parse(json,jv))
            {
                printf("parse err!\n");
                return false;
            }
            return decode(jv);
    
        }
    
        bool decode(Json::Value & _jv,int dontCheckPacketName=0)
        {
            Json::Value jv;
    
            if( dontCheckPacketName )
            {
                jv=_jv;
            }
            else
            {
                if( Json::objectValue!=_jv["rpc1"].type() )return false;
                jv=_jv["rpc1"];
            }
    
            if( jv["age"].type()==Json::intValue || jv["age"].type()==Json::uintValue )
                age = jv["age"].asInt64();
    
            if( jv["hp"].type()==Json::intValue || jv["hp"].type()==Json::uintValue )
                hp = jv["hp"].asInt64();
    
            if( jv["mp"].type()==Json::intValue || jv["mp"].type()==Json::uintValue )
                mp = jv["mp"].asInt64();
    
            return decodesuccess();
        }
    
        std::string encode2string(int dontMakePacketName=0)
        {
            return encode(dontMakePacketName).toStyledString();
        }
    
        Json::Value encode(int dontMakePacketName=0)
        {
            Json::Value root;
    
            root["age"]=Json::Value(age);
            root["hp"]=Json::Value(hp);
            root["mp"]=Json::Value(mp);
            if(dontMakePacketName)
            {
                return root;
            }
            else
            {
                Json::Value retval;
                retval["rpc1"]=root;
                return retval;
            }
        }
    
        long long age; //年龄
    
        long long hp; //
    
        long long mp; //魔法
    
    }
    ;
    //////////////////////////////////////////////////////////////////////////
    
    
    #endif //test_h

    写入demo.cpp来测试一下:

    // demo.cpp :
    //
    
    #include "demo.h"
    
    #include "json2jsoncpp.h"
    
    #ifdef _MSC_VER
        #pragma comment(lib,"json_vc71_libmt.lib")
        #pragma warning(disable:4996)
    #endif
    
    class G1:public rpc1
    {
    public:
        G1()
        {
            printf("G1();\n");
        }
    
        ~G1()
        {
            printf("~G1();\n");
        }
    
        bool decodesuccess()
        {
            printf("G1::decodesuccess()hp=%d;\n",this->hp);//当解析完毕保存好内容后,就调用decodesuccess
            return true;//返回false就是取消这次生成的对象,内部会自动销毁他
        }
    };
    
    
    int main(int argc, char* argv[])
    {
        json2jsoncpp::INIT();//初始化一下库
        json2jsoncpp::REG<G1>();//向json
    
        //先生成一个json数据拿来测试
        rpc1 aa;
        aa.hp=100;
        printf("%s\n",aa.encode2string().c_str());
    
        printf("///////////////////////////////////////\n");
    
        //把一个json数据放入库解析并且创建一个对象,如果创建成功后会调用对象的decodesuccess
        json2jsoncpp::decode(aa.encode2string());
    
        json2jsoncpp::UNREG<G1>();//反注册G1
        json2jsoncpp::UNINIT();//销毁库
        return 0;
    }

    执行结果:

    image

    可以看到,j2jc生成的对象encode出来的数据带着类名 “rpc1”  这样就满足了刚才说的第一点 包含了一个类名,这样解析方才能得知这个json数据是属于哪个类的,然后再生成对象出来

    当json数据放入json2jsoncpp::decode后, json2jsoncpp通过刚才注册过的类信息自动生成一个相对应的类来,并且调用decodesuccess来通知执行后面的逻辑,这时候你就可以在decodesuccess来执行相关的逻辑编码了

    这样的好处就是接收解码和逻辑代码分离,比较清晰

    刚才提到代码中用到的两个头文件和程序在这里:

    http://pan.baidu.com/share/link?shareid=309238&uk=3711199009

    好了,先写到这里,下一篇我将介绍j2jc实现这些功能的一些原理(代码分析)

    本篇博客为原创作品,个人转载或引用时请保留本人的署名及博客网址,商业转载请事先联系。我的博客地址是:http://www.cnblogs.com/vanis/ , 我的hotmail.com邮箱是vanishs
  • 相关阅读:
    向日葵、阳光
    laravel还是给我太多惊喜了
    滴滴笔试题——小试牛刀
    剑指offer——二叉搜索树的后序遍历序列
    2019春招美团笔试
    首次实习生招聘会——航天一院
    有趣的数字
    剑指offer——从上往下打印二叉树
    剑指offer——栈的压入、弹出序列
    剑指offer——包含min函数的栈
  • 原文地址:https://www.cnblogs.com/vanis/p/2934032.html
Copyright © 2020-2023  润新知