精华内容
下载资源
问答
  • ajax使用json数据格式提交 一开始这么写的 var flobj = { UserId: userid, ForbidSDT: ForbidSDT, ForbidEDT: ForbidEDT } $.ajax({ type: "POST", url: "/Limit/Forbid", contentType: "applicati

    ajax使用json数据格式提交

    一开始这么写的

    var flobj = {
                UserId: userid,
                ForbidSDT: ForbidSDT,
                ForbidEDT: ForbidEDT
            }
            $.ajax({
                type: "POST",
                url: "/Limit/Forbid",
                contentType: "application/json", //必须有  
                dataType: "json", //表示返回值类型,不必须  
                data: { Types: chk_value, fl: flobj, remark: remark, tip: tip },
                success: function (jsonResult) {
                    if (jsonResult.Code == 1)
                    {
                        alert("添加成功");
                        $(target).parent().parent().find("input").attr("disabled", true);
                    } else {
                        alert("添加失败");
                    }
                }
            });
    

    提交的数据格式:

    这种会报错误:

    无效的 JSON 基元: Types

    改为了:

    var flobj = {
                UserId: userid,
                ForbidSDT: ForbidSDT,
                ForbidEDT: ForbidEDT
            }
            $.ajax({
                type: "POST",
                url: "/Limit/Forbid",
                contentType: "application/json", //必须有  
                dataType: "json", //表示返回值类型,不必须  
                data: JSON.stringify({ Types: chk_value, fl: flobj, remark: remark, tip: tip }), 
                success: function (jsonResult) {
                    if (jsonResult.Code == 1)
                    {
                        alert("添加成功");
                        $(target).parent().parent().find("input").attr("disabled", true);
                    } else {
                        alert("添加失败");
                    }
                }
            });
    

    提交的数据格式:

    记录:

    data必须是一个“表示JSON对象的字符串”,而不是一个“JSON”对象

    原因是jquery会把JSON对象序列化成标准POST的形式,ASP.NET WebService需要的是JSON格式的数据,所以必须把你的数据变成一个JSON样子的字符串

    展开全文
  • json格式

    千次阅读 2018-03-29 20:38:38
    标准JSON的合法符号:{(左大括号) }(右大括号) "(双引号) :(冒号) ,(逗号) [(左中括号) ](右中括号)JSON字符串:特殊字符可在字符前面加 \ 或使用 \u 加 4位16进制数来处理[html]view plaincopy{"name&...

    标准JSON的合法符号:{(左大括号)  }(右大括号)  "(双引号)  :(冒号)  ,(逗号)  [(左中括号)  ](右中括号)

    JSON字符串:特殊字符可在字符前面加 \ 或使用 \u 加 4位16进制数来处理

    {"name":"jobs"}  

    JSON布尔:必须小写的true和false

    {"bool":true}  

    JSON空:必须小写的null

    {"object":null}  
    JSON数值:不能使用8/16进制
    {"num":60}  
    {"num":-60}  
    {"num":6.6666}  
    {"num":1e+6}<!-- 1乘10的6次方,e不区分大小写 -->  
    {"num":1e-6}<!-- 1乘10的负6次方,e不区分大小写 -->  

     

    JSON对象

    {  
        "starcraft": {  
            "INC": "Blizzard",  
            "price": 60  
        }  
    }  

     

    JSON数组

    {  
        "person": [  
            "jobs",  
            60  
        ]  
    }  

     

    JSON对象数组

    {  
        "array": [  
            {  
                "name": "jobs"  
            },  
            {  
                "name": "bill",  
                "age": 60  
            },  
            {  
                "product": "war3",  
                "type": "game",  
                "popular": true,  
                "price": 60  
            }  
        ]  
    } 

     


     

    展开全文
  • json localdatetime时间格式无效问题

    千次阅读 2020-06-18 09:03:35
    之前有的javabean ,但是进行某些请求时候需要传json格式的字符串所以需要将其转化为json,发现其中localdatetime转换时候时间中间带有T 导致调用失败 网上查阅都是 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",...

    之前有的javabean ,但是进行某些请求时候需要传json格式的字符串所以需要将其转化为json,发现其中localdatetime转换时候时间中间带有T 导致调用失败 网上查阅都是

    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") 

    直接就能搞定 放上去表示无效,后点开标签发现该方法是springboot自带的json方法的   而当前项目是阿里巴巴

    的json  为了区分其标签头部的json  分别是Json和JSON 的区别

    阿里巴巴的

    springboot的

    就觉得之前JSONObject.fromObject都不能用了 偏要用JSON.TOJSON方法。。 百度了有4种json

    Gson

    项目地址:https://github.com/google/gson

    Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,但自从在2008年五月公开发布第一版后已被许多公司或用户应用。 Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。 在使用这种对象转换之前,需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。 类里面只要有get和set方法,Gson完全可以实现复杂类型的json到bean或bean到json的转换,是JSON解析的神器。

    FastJson

    项目地址:https://github.com/alibaba/fastjson

    Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。 FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。 FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。

    Jackson

    项目地址:https://github.com/FasterXML/jackson

    Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson社区相对比较活跃,更新速度也比较快, 从Github中的统计来看,Jackson是最流行的json解析器之一,Spring MVC的默认json解析器便是Jackson。

    Jackson优点很多:

    1. Jackson 所依赖的jar包较少,简单易用。
    2. 与其他 Java 的 json 的框架 Gson 等相比,Jackson 解析大的 json 文件速度比较快。
    3. Jackson 运行时占用内存比较低,性能比较好
    4. Jackson 有灵活的 API,可以很容易进行扩展和定制。

    目前最新版本是2.9.4,Jackson 的核心模块由三部分组成:

    1. jackson-core 核心包,提供基于”流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
    2. jackson-annotations 注解包,提供标准注解功能;
    3. jackson-databind 数据绑定包,提供基于”对象绑定” 解析的相关 API( ObjectMapper )和”树模型” 解析的相关 API(JsonNode);基于”对象绑定” 解析的 API 和”树模型”解析的 API 依赖基于”流模式”解析的 API。

    为什么Jackson的介绍这么长啊?因为它也是本人的最爱。

    Json-lib

    项目地址:http://json-lib.sourceforge.net/index.html

    json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,对于复杂类型的转换,json-lib对于json转换成bean还有缺陷, 比如一个类里面会出现另一个类的list或者map集合,json-lib从json到bean的转换就会出现问题。json-lib在功能和性能上面都不能满足现在互联网化的需求。

    这个json介绍来自于https://www.cnblogs.com/javalyy/p/10723634.html 各位看官可以自行去看 特此记录

     

     

    展开全文
  • C++编写配置文件解析模块(基于JSON格式

    万次阅读 多人点赞 2021-04-24 19:12:02
    C++编写一个简单的配置文件解析模块(基于JSON格式

    1、环境准备

    本文是基于bifang框架的配置模块的,可以看这里 bifang框架运行环境搭建入门指南 将代码环境搭建起来,拉下代码之后就可以看里面的配置模块了,主要是src/config.cpp和src/config.h这两个文件

    2、JSON-CPP简单使用

    由于配置文件的格式是json的,所以有必要了解一下json格式,网上教程很多,这里就不赘述了。代码中使用的是JSON-CPP来解析json格式的,使用的版本比较新,具体的版本忘记了,可能使用起来会和老版本的不太一样(因为代码里面有宏提示某部分代码已经不建议使用了),所以下面举两个简单的例子说明JSON-CPP使用方法

    2.1、将json格式字符串转换为Json::Value

    Json::Value root;
    Json::String errs;
    Json::CharReaderBuilder reader;
    std::unique_ptr<Json::CharReader> const jsonReader(reader.newCharReader());
    if (!jsonReader->parse(v.c_str(), v.c_str() + v.length(), &root, &errs))
    {
        std::stringstream ss;
        ss << message << " strerror: " << errs;
        throw std::logic_error(ss.str());
    }
    

    2.2、将Json::Value转换为json格式字符串

    std::stringstream ss;
    ss << root;
    std::string v = ss.str()
    

    3、序列化和反序列化的实现

    3.1、通用序列化转换模板

    可以看到下面代码使用了boost的lexical_cast来实现一些基本类型的转换(比如std::string转int、float),这也就是为什么之前搭建环境的时候要安装boost依赖的原因了,这里会使用到

    template<class F, class T>
    struct LexicalCast
    {
        /**
         * brief: 类型转换
         * param: v 源类型值
         * return: 返回v转换后的目标类型
         * exception: 当类型不可转换时抛出异常
         */
        T operator()(const F& v)
        {
            return boost::lexical_cast<T>(v);
        }
    };
    

    3.2、序列化反序列化通用代码块宏定义

    如下所示,将每个序列化和反序列化会使用到的通用代码用宏封装了起来,实现的功能也就是 std::string->Json::Value 和 Json::Value->std::string

    #define SEQUENCE(root, v, message) \
        Json::Value root; \
        Json::String errs; \
        Json::CharReaderBuilder reader; \
        std::unique_ptr<Json::CharReader> const jsonReader(reader.newCharReader()); \
        if (!jsonReader->parse(v.c_str(), v.c_str() + v.length(), &root, &errs)) \
        { \
            std::stringstream ss; \
            ss << message << " strerror: " << errs; \
            throw std::logic_error(ss.str()); \
        }
    
    #define RESEQUENCE(root) \
        std::stringstream ss; \
        ss << root; \
        return ss.str()
    

    3.3、实现std::vector和json格式字符串的转换

    序列化,可以看到就是将std::vector的数据一个一个压进去Json::Value(数组类型)里面,然后将其转换为字符串输出

    template<class T>
    struct LexicalCast<std::vector<T>, std::string>
    {
        std::string operator()(const std::vector<T>& v)
        {
            Json::Value root(Json::arrayValue);
            for (auto& i : v)
                root.append(Json::Value(LexicalCast<T, std::string>()(i)));
    
            RESEQUENCE(root);
        }
    };
    

    反序列化,可以看到就是将json格式字符串转为Json::Value(数组类型),然后将其一个一个压进去std::vector里,最后输出

    template<class T>
    struct LexicalCast<std::string, std::vector<T> >
    {
        std::vector<T> operator()(const std::string& v)
        {
            SEQUENCE(root, v, "json string(vector) is illegal!");
    
            typename std::vector<T> vec;
            std::stringstream ss;
            for (uint32_t i = 0; i < root.size(); i++)
            {
                ss.str("");
                ss << root[i];
                vec.push_back(LexicalCast<std::string, T>()(ss.str()));
            }
    
            return vec;
        }
    };
    

    3.4、实现std::map和json格式字符串的转换

    序列化,可以看到就是将std::map的数据一个一个压进去Json::Value(对象类型)里面,然后将其转换为字符串输出

    template<class T>
    struct LexicalCast<std::map<std::string, T>, std::string>
    {
        std::string operator()(const std::map<std::string, T>& v)
        {
            Json::Value root(Json::objectValue);
     
            for (auto& i : v)
                root[i.first] = Json::Value(LexicalCast<T, std::string>()(i.second));
    
            RESEQUENCE(root);
        }
    };
    

    反序列化,可以看到就是将json格式字符串转为Json::Value(对象类型),然后将其一个一个压进去std::map里,最后输出

    template<class T>
    struct LexicalCast<std::string, std::map<std::string, T> >
    {
        std::map<std::string, T> operator()(const std::string& v)
        {
            SEQUENCE(root, v, "json string(map) is illegal!");
    
            typename std::map<std::string, T> _map;
            std::stringstream ss;
            auto names = root.getMemberNames();
            for (auto& i : names)
            {
                ss.str("");
                ss << root[i];
                _map[i] = LexicalCast<std::string, T>()(ss.str());
            }
    
            return _map;
        }
    };
    

    3.5、其他类型数据的转换

    代码中还实现了其他stl容器与json字符串的转换,这里就不赘述了,与上面的实现差不多。从上面的例子可以看出,只要实现了自定义数据结构的序列化和反序列化的,就能支持自定义配置文件格式,具体大家可以去看一下代码中日志配置文件、tcp服务配置文件、数据库配置文件的序列化和反序列化、数据结构定义以及配置文件的格式。接下来以数据库配置文件为例简单分析一下
    配置文件格式

    "mysql" :
    {
        "sql1" : 
        {
            "host" : "127.0.0.1",
            "port" : 3306,
            "user" : "root",
            "passwd" : "123456",
            "dbname" : "mysql",
            "poolSize" : 15
        }
    }
    

    自定义配置类

    struct MySqlConf
    {
        typedef std::shared_ptr<MySqlConf> ptr;
    
        std::string host;
        int port;
        std::string user;
        std::string passwd;
        std::string dbname;
        uint32_t poolSize = 10;
    
        bool operator==(const MySqlConf& oth) const
        {
            return host == oth.host
                && port == oth.port
                && user == oth.user
                && passwd == oth.passwd
                && dbname == oth.dbname
                && poolSize == oth.poolSize;
        }
    };
    

    序列化代码,将MySqlConf的成员赋值到Json::Value(对象类型)中,与配置文件一致

    template<>
    struct LexicalCast<MySqlConf, std::string>
    {
        std::string operator()(const MySqlConf& conf)
        {
            Json::Value root;
    
            root["host"] = conf.host;
            root["port"] = conf.port;
            root["user"] = conf.user;
            root["passwd"] = conf.passwd;
            root["dbname"] = conf.dbname;
            root["poolSize"] = conf.poolSize;
    
            RESEQUENCE(root);
        }
    };
    

    反序列化代码,将json字符串转换为Json::Value(对象类型),然后将对象中各个成员赋值到MySqlConf中,与配置文件一致

    template<>
    struct LexicalCast<std::string, MySqlConf>
    {
        MySqlConf operator()(const std::string& v)
        {
            SEQUENCE(root, v, "json string(MySqlConf) is illegal!");
    
            MySqlConf conf;
            if (root.isMember("host"))
                conf.host = root["host"].asString();
    
            if (root.isMember("port"))
                conf.port = root["port"].asInt();
    
            if (root.isMember("user"))
                conf.user = root["user"].asString();
    
            if (root.isMember("passwd"))
                conf.passwd = root["passwd"].asString();
    
            if (root.isMember("dbname"))
                conf.dbname = root["dbname"].asString();
    
            if (root.isMember("poolSize"))
                conf.poolSize = root["poolSize"].asInt();
    
            return conf;
        }
    };
    

    4、配置器类的设计

    配置类要实现的功能由配置项的初始化,获取,以及变更通知功能

    4.1、ConfigBase - 配置基类

    如下所示,配置基类有两个成员,一个是参数名称,另一个是参数描述,还有三个虚函数由派生类实现(参数名一律转换为小写字母)

    class ConfigBase
    {
    public:
        typedef std::shared_ptr<ConfigBase> ptr;
    
        /**
         * brief: 构造函数
         * param: name 参数名称(自动转换为小写, 故参数名称不区分大小写)
         *        description 参数描述
         */
        ConfigBase(const std::string& name, const std::string& description = "")
            :m_name(name)
            ,m_description(description)
        {
            std::transform(m_name.begin(), m_name.end(), m_name.begin(), ::tolower);
        }
    
        virtual ~ConfigBase() {}
    
        /**
         * brief: 返回配置参数名称
         */
        const std::string& getName() const { return m_name; }
    
        /**
         * brief: 返回配置参数的描述
         */
        const std::string& getDescription() const { return m_description; }
    
        /**
         * brief: 返回配置参数值的类型名称
         */
        virtual std::string getTypeName() const = 0;
    
        /**
         * brief: 将配置参数转成字符串
         */
        virtual std::string toString() = 0;
    
        /**
         * brief: 从字符串初始化值
         */
        virtual bool fromString(const std::string& val) = 0;
    
    protected:
        // 参数名称
        std::string m_name;
        // 参数描述
        std::string m_description;
    };
    

    4.2、Config - 配置类

    可以看到该类有三个成员,分别是读写锁,参数值,变更回调函数组。可以看到toString和fromString的实现是基于前面序列化反序列化模板的,使用setValue后逐个调用变更回调函数,也就实现了变更通知功能

    template<class T, class FromStr = LexicalCast<std::string, T>,
                      class ToStr = LexicalCast<T, std::string> >
    class Config : public ConfigBase
    {
    public:
        typedef std::shared_ptr<Config> ptr;
        typedef RWMutex RWMutexType;
        typedef std::function<void(const T& old_value, const T& new_value)> OnChangeCb;
    
        /**
         * brief: 通过参数名, 参数值, 描述构造Config
         * param: name 参数名称
         *        default_value 参数默认值
         *        description 参数描述
         */
        Config(const std::string& name,
               const T& default_value,
               const std::string& description = "")
            :ConfigBase(name, description)
            ,m_val(default_value)
        {
        }
    
        /**
         * brief: 将参数值转换成 JSON String
         */
        std::string toString() override
        {
            try
            {
                RWMutexType::ReadLock lock(m_mutex);
                return ToStr()(m_val);
            }
            catch (std::exception& e)
            {
                SystemLogger();
                log_error << "Config::toString exception " << e.what()
                    << ", convert: " << type_to_name<T>() << " to string"
                    << ", name=" << m_name;
            }
            return "";
        }
    
        /**
         * brief: 从 JSON String 转成参数的值
         */
        bool fromString(const std::string& val) override
        {
            try
            {
                setValue(FromStr()(val));
            }
            catch (std::exception& e)
            {
                SystemLogger();
                log_error << "Config::fromString exception " << e.what()
                    << ", convert: string to " << type_to_name<T>()
                    << ", name=" << m_name << ": " << val;
            }
            return false;
        }
    
        /**
         * brief: 获取当前参数的值
         */
        const T getValue()
        {
            RWMutexType::ReadLock lock(m_mutex);
            return m_val;
        }
    
        /**
         * brief: 设置当前参数的值
         * details: 如果参数的值有发生变化, 则通知对应的注册回调函数
         */
        void setValue(const T& v)
        {
            {
                RWMutexType::ReadLock lock(m_mutex);
                if (v == m_val)
                    return;
                for (auto& i : m_cbs)
                    i(m_val, v);
            }
            RWMutexType::WriteLock lock(m_mutex);
            m_val = v;
        }
    
        /**
         * brief: 返回参数值的类型名称(typeinfo)
         */
        std::string getTypeName() const override { return type_to_name<T>(); }
    
    public:
        /**
         * brief: 添加变化回调函数
         */
        void addCallback(OnChangeCb cb)
        {
            RWMutexType::WriteLock lock(m_mutex);
            m_cbs.push_back(cb);
        }
        /**
         * brief: 清理所有的回调函数
         */
        void clearCallback()
        {
            RWMutexType::WriteLock lock(m_mutex);
            m_cbs.clear();
        }
    
    private:
        // RWmutex
        RWMutexType m_mutex;
        // 参数值
        T m_val;
        // 变更回调函数组
        std::vector<OnChangeCb> m_cbs;
    };
    

    4.3、ConfigManager - 配置器管理类

    从代码中可以看到,所有配置项都是放在类成员m_datas里面,get方法也是根据名称从其中取出对应的Config的。其他的都比较简单,下面重点讲一下载入配置项的两个load方法

    class ConfigManager
    {
    public:
        typedef RWMutex RWMutexType;
        typedef std::unordered_map<std::string, ConfigBase::ptr> ConfigMap;
    
        /**
         * brief: 获取对应参数名的配置参数(若不存在则自动创建, 并用default_value赋值)
         * param: name 配置参数名称
         *        default_value 参数默认值
         *        description 参数描述
         * return: 返回对应的配置参数, 如果参数名存在但是类型不匹配则返回nullptr
         */
        template<class T>
        typename Config<T>::ptr get(const std::string& name,
                                    const T& default_value,
                                    const std::string& description = "")
        {
            RWMutexType::WriteLock lock(m_mutex);
            auto it = m_datas.find(name);
            if (it != m_datas.end())
            {
                SystemLogger();
                auto tmp = std::dynamic_pointer_cast<Config<T> >(it->second);
                if (tmp)
                {
                    log_debug << "Lookup name=" << name << " exists";
                    return tmp;
                }
                else
                {
                    log_debug << "Lookup name=" << name << " exists but type not "
                        << type_to_name<T>() << ", real_type="
                        << it->second->getTypeName() << " " << it->second->toString();
                    return nullptr;
                }
            }
    
            typename Config<T>::ptr v(new Config<T>(name, default_value, description));
            m_datas[v->getName()] = v;
            return v;
        }
        /**
         * brief: 查找配置参数
         * param: name 配置参数名称
         * return: 返回配置参数名为name的配置参数
         */
        template<class T>
        typename Config<T>::ptr get(const std::string& name)
        {
            auto it = m_datas.find(name);
            return it == m_datas.end() ? nullptr : std::dynamic_pointer_cast<Config<T> >(it->second);
        }
    
        /**
         * brief: 遍历配置模块里面所有配置项
         * param: cb 配置项回调函数
         */
        void visit(std::function<void(ConfigBase::ptr)> cb)
        {
            RWMutexType::ReadLock lock(m_mutex);
            for (auto& it : m_datas)
                cb(it.second);
        }
    
        /**
         * brief: 从Json::Value中加载配置模块
         */
        void load(Json::Value& root);
        
        /**
         * brief: 读取path文件夹里面的配置文件用以加载配置模块
         */
        void load(const std::string& path);
    
    private:
        // RWmutex
        RWMutexType m_mutex;
        // Config列表
        ConfigMap m_datas;
    };
    

    首先介绍一下我配置文件与配置项之间的转换规则,如下所示,还是以sql的配置文件举例,要获取sql1的数据,对应的配置项名称为mysql.sql1,要获取host则是mysql.sql1.host,类与类一层一层的关系用.来表示,则可以写出下面的解析代码listAllMember

    "mysql" :
    {
        "sql1" : 
        {
            "host" : "127.0.0.1",
            "port" : 3306,
            "user" : "root",
            "passwd" : "123456",
            "dbname" : "mysql",
            "poolSize" : 15
        }
    }
    

    listAllMember的实现比较简单,递归解析json格式,遇到json对象类型则继续递归解析,非对象类型则结束当前层次的解析。这样的解析存在一个问题,就是会会往配置管理器中压入一些根本用不到的数据,还是用上面sql配置文件的例子来说明,经过解析之后,势必会出现很多配置项,比如mysql、mysql.sql1、mysql.sql1.host、mysql.sql1.port等等,由于我们事先无法知道究竟哪一部分时代码要用的,所以只能全部将他们作为独立的配置项提取出来了,由于没用的配置项在接下来的load方法中会被剔除,所以这里多出来的那些配置项只会影响一开始读取配置文件的速度而已,对运行时的速度和内存占用没有影响,所以没必要优化这部分内容(事实上对于这个例子来说,除了mysql之外的配置项全部没有意义,因为sql的配置文件是实现了自己特使的序列化和反序列化的,所以该配置文件的其他子配置项在代码中根本用不到,也不会被载入配置器管理类)。

    static void listAllMember(std::string prefix, const Json::Value& root,
                    std::vector<std::pair<std::string, const Json::Value> >& nodes)
    {
        std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
    
        // 会多压入一些无用的数据, 考虑到map配置点和配置文件并非频繁使用, 暂不优化
        nodes.push_back(std::make_pair(prefix, root));
        if (root.isObject())
        {
            auto names = root.getMemberNames();
            for (auto& i : names)
                listAllMember(prefix.empty() ? i : prefix + "." + i, root[i], nodes);
        }
    }
    

    接下来时load方法的实现,比较简单,用listAllMember将配置项取出来,然后将有效地配置信息更新到配置器管理类中,无效的剔除

    void ConfigManager::load(Json::Value& root)
    {
        std::vector<std::pair<std::string, const Json::Value> > nodes;
        listAllMember("", root, nodes);
    
        for (auto& i : nodes)
        {
            if (i.first.empty())
                continue;
    
            auto it = m_datas.find(i.first);
            ConfigBase::ptr var = it == m_datas.end() ? nullptr : it->second;
            if (var)
            {
                if (i.second.isString()) // 防止字符串值打出双引号, 只能对其单独处理
                {
                    var->fromString(i.second.asString());
    
                    // 打印配置点
                    //std::cout << i.first << "=" << i.second.asString() << std::endl;
                }
                else
                {
                    std::stringstream ss;
                    ss << i.second;
                    var->fromString(ss.str());
    
                    // 打印配置点
                    //std::cout << i.first << "=" << ss.str() << std::endl;
                }
            }
        }
    }
    

    这个是load方法的重载实现,实现了读取文件夹中全部配置文件,然后载入配置的功能,实现比较简单,大家有兴趣的可以看一看

    void ConfigManager::load(const std::string& path)
    {
        std::string absoulte_path = FileUtil::PureDirname(path);
        absoulte_path = EnvMgr::GetInstance()->getAbsolutePath(absoulte_path);
        std::vector<std::string> files;
    
        FileUtil::ListAllFile(files, absoulte_path, ".json");
    
        for (auto& i : files)
        {
            try
            {
                Json::Value root;
                Json::String errs;
                Json::CharReaderBuilder reader;
                std::ifstream ifs;
                ifs.open(i);
                if (!Json::parseFromStream(reader, ifs, &root, &errs))
                {
                    log_error << "parse json err " << errs;
                    throw std::logic_error("read file:" + i + " error!");
                }
    
                load(root);
                //log_debug << "LoadConfFile file=" << i << " ok";
            }
            catch (...)
            {
                log_error << "LoadConfFile file=" << i << " failed";
            }
        }
    }
    

    5、总结

    大家如果想知道更多关于本文编写的配置器的使用方法,可以 点击这里 下载我的开源框架去看一下里面的源码,相信一定会有所收获的,也麻烦大家顺手点一下star,谢谢

    展开全文
  • linux wget发送json格式的请求方式

    千次阅读 2020-11-25 10:04:03
    使用wget发送json格式的body需要添加header Content-Type:application/json 所以发送格式如下 wget --header=“Content-Type:application/json” --post-file=file.json http://xxxxxx 其中file.json文件中就是需要...
  • Pretty Json 插件,用于JSON格式化,默认快捷键:Ctrl + Alt + J 1. 安装 Pretty Json 插件 a. 打开命令面板,快捷键:Ctrl + Shift + P b. 输入 install c. 等待一会、下面停止了会弹出插件搜索框 d. 选中以下...
  • 我们要实现下图所示,报错后返回json格式的信息,相当于把默认的html格式的异常变成json格式的。 但是我们继承了HTTPException就会出现下图的结果: 首先异常分为两种: 完全可以预知的异常 已知异常 可以...
  • Python下JSON格式的读写

    千次阅读 2018-07-31 07:40:10
    一、 JSON (JavaScript Object Notation)是一...JSON格式的数组或者对象中,不同的元素用逗号隔开,最后一个元素后面,不能加逗号。 二、 1、dump()和load() dump主要用来json文件写入,和load(读取)配合使...
  • 【Python3.5】读写JSON格式的数据

    万次阅读 2016-12-14 00:29:40
    由于最近在玩ELK数据分析,慢慢的对JSON格式的数据有了一些了解,之前只知道JSON是Javascript Object Notation编码格式的数据,且在web开发中的前后端数据传输时会大部分用的都是json格式的数据,那么接下来我们就...
  • json格式化插件,Pretty Json

    千次阅读 2018-09-30 14:38:00
    cmd + shift + p,输入installpacket,选择第1个 ...尝试一下,cmd + shift + p打开输入窗口,选择第2个,就可以格式化这个json了 转载于:https://www.cnblogs.com/sailJs/p/9729497.html...
  • 访问一个网站,通过浏览器获取到json数据,需要将浏览器获取的数据右键另存为json格式 ,然后通过以下方法把json文件导入到数据库碰到一个困惑很久的问题,需要将大批数据(万级)导入到数据库中,而那些数据都是密密...
  • 下载之后是一个crx插件,但是可能会出现拖到到谷歌浏览器安装会出现程序包无效的情况,可以用开发者模式安装,强制把文件改为zip格式: 然后解压zip,解压成一个文件夹 打开文件夹,将文件夹名“_metadata”改...
  • json格式正确却无法转换成 JSONObject

    千次阅读 2015-07-18 15:44:07
    json格式正确却无法转换成 JSONObject
  • ASP.NET Web API的controller默认的返回数据格式是XML格式,要改成返回JSON格式只需要在WebApiConfig.cs文件里的Register方法末尾加上如下代码 var json = config.Formatters.JsonFormatter; json....
  • 小程序json格式解析

    2019-04-08 15:34:27
    小程序json解析第一种格式 that.setData({ goldData: res.data.result[0], //result里多了个{}所以要标个[0] }) 1:解析这个json:http://www.intmote.com/myproject/test/new_file.json wxml <text ...
  • json格式出现中文乱码 发送json 1)使用json.dumps方式 return json.dumps(ret_json, ensure_ascii=False) 增加ensure_ascii=False 2)使用jsonify(ret_json)方式时 可以配置flask app.config[‘JSON_AS_ASCII...
  • HIVE json格式数据的处理

    千次阅读 2016-12-20 19:43:07
    今天要处理一个以json格式存储的数据,想要直接把json的各个项的数据存入HIVE表中。 HIVE直接读入json的函数有两个: (1)get_json_object(string json_string, string path) 返回值: string  说明
  • 今天遇到一个JSON数据转对象失败额问题,一开始服务返回的json就不是很干净,开头和结尾有换行符,明显不符合json格式用JSON.parse肯定就报错啦    这里告诉我们json的第一个位置的词不是所期望的。这时先用正则...
  • hive如何使用json格式的数据

    千次阅读 2018-09-26 14:12:09
    查看当前hive支持的json函数 show functions like &amp;quot;*json*&amp;quot;; OK get_json_object json_tuple Time taken: 0.006 seconds, Fetched: 2 row(s) get_json_object describe function get...
  • java实现json格式的状态码数据

    千次阅读 2017-08-28 16:05:19
    创建返回json格式的类 JsonResult 编写登陆页面的类 LoginController 编写启动程序JsonStatusApplication 浏览器中访问url 返回结果功能编写一个返回格式是json格式的数据,并且此数据是状态码的数据。例如: {...
  • 安装方法查看:谷歌浏览器安装json格式化插件 亲测可用。
  • 数据源:json格式文件,内容为json; Elasticsearch和Logstash版本:5.6.1; 前提环境:Elasticsearch单机或集群;Logstash客户端; 实践 json文件内容: {"name":"sixmonth","age":"23","sex":"男","address":...
  • 【已解决】Date类型日期返回JSON格式yyyy-MM-dd 日期不需要返回时分秒,可用注解@JsonFormat(pattern = “yyyy-MM-dd”): 返回JSON数据为 试过了@JSONField(format = “yyyy-MM-dd”),但是无效。 @JsonFormat...
  • 今天在写项目是遇到时间转换一直是英文格式,无法装换成中文日期格式 解决办法 先在对应的实体类属性上加入注解 @Temporal(TemporalType.TIMESTAMP) private Date articleInputDate; 然后在对应的html页面加上${#...
  • url地址栏传输json格式数据

    万次阅读 2018-10-11 11:07:49
    在url地址栏中传输json数据时需要进行转码,因为在程序里url若包含 “ 字符或者 ‘ 等字符时会认为这是无效的url     例:JSONObject json = new JSONObject();//new一个json对象  Map&lt;String,...
  • 后台返回json,在json格式化中也是正确,前台就是打不出来里面的元素. 强转json报错Unexpected token :
  • java后台HTTP请求返回json格式数据 枚举类ResponseState(所有自定义的状态码写在里面) package com.xxx.common.enums; public enum ResponseState { //状态码添加在这里 /** * 系统繁忙,此时请...
  • iOS Apns推送消息Json格式

    万次阅读 2017-02-27 21:18:09
    以下是两种Json格式 iOS 10 之前 { "aps" :{ "alert" : "内容" , "badge" : 1 , "sound" : "default" , "userinfo" :{ "username" : "tom" } } } ---------- iOS 10 及之后(iOS7、iOS...
  • VS调试时JSON格式文件加载不了

    千次阅读 2015-11-25 09:00:37
    在使用VS2012进行调试时发现加载数据为JSON格式的都加载不了,应该是MIME类型没有正确设置的问题。 直接通过浏览器地址栏访问时会收到提示,根据提示在IIS EXPRESS的安装目录下面执行一条命令即可: appcmd set ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,016
精华内容 24,806
关键字:

无效的json格式