zoukankan      html  css  js  c++  java
  • spray json, jackson 转到type时多key和少key的比较

    有组合关系的三个class定义

    A {

      B {

      C {...}

          ...

      }

      ...

    }

    每个class都有loadFromJson和writeAsJson方法。过去几年,三个class里的成员变量一直在添加,而数据库里有很多json string类型的老数据,为了能够正确的把它们转化为class,就需要对一些域进行判断,举个例子。

    在 db 中有一个json string,是这样的 name: xins, age: 24

    而几年后C添加了一个新的域,company

    那么loadFromJson就要添加判断,如果json中没有company这个key,就要写上 company: null 

    现在,要重写A, B, C。目标是,代码尽可能的少,扩展性要好,不要if/else判断域的存在情况。

    老数据中json的域不足,转到class时可能会有问题。

    class转到json会添加一些域,但这可能没有关系,因为前端可能只从json中拿它感兴趣的key,val

    下面测了两种json库,分别是spray.json和jackson_scala_module

    结果:

    jackson_scala_module在从string json 到 type进行转换时,能够接受域缺失的问题。比如

    case class Demo(x: Boolean, y: Int, c: String, d: Double)
    val demo = mapper.readValue("{}", classOf[Demo])
    println(demo)

    Demo(false,0,null,0.0)

    其实这个结果是不太理想的,我更希望当一个域不出现时,该域就不要在json中出现。比如false, 0 和 null 的地位是不一样的。false, 0 是个有效的值,而null则明确说明没有值。

    对于spray.json发生key缺失的情况,则会exception

    而对于域key出现多余的情况

    jackson报错

    val demo1 = mapper.readValue("{"x": true, "y": 1100, "c": "str", "d": "str"}", classOf[Demo])

    spray.json则没有问题

    对于变量的顺序则没有关系,两个库都能正确处理key顺序不正确的情况。

    新的程序是用scala写的,spray框架。首先想到的就是spray.json。从别人的blog上看到spray.json的速度很慢,但是spray对spray.json内置了很多支持,比如post的数据可以通过entity.as[Person]直接转到Person对象。考虑到程序面对的数据量并不太大,spray.json慢点其实无所谓,但多key的情况它处理不了,就用不了了。

    update: json4s

    后来我又测试了下 json4s,发现json4s对于多key或者少key的情况都能正确的处理,唯一的问题是case class每个域都要用option来修饰,不太美观

    import org.json4s._
    import org.json4s.jackson.JsonMethods._
    
    object Json4s extends App {
      implicit val formats = DefaultFormats
    
      case class Child(name: Option[String], age: Int, birthdate: Option[java.util.Date])
    
      case class Address(street: String, city: String)
    
      case class Person(name: Option[String], address: Address, children: Option[List[Child]])
    
      val json = parse( """
             { "name": "joe",
               "sss" : "sss",
               "ssss" : 3,
               "address": {
                 "street": "Bulevard",
                 "city": "Helsinki"
               },
               "children": [
                 {
                   "name": "Mary",
                   "age": 5,
                   "birthdate": "2004-09-04T18:06:22Z"
                 },
                 {
                   "name": "Mazy",
                   "age": 3
                 }
               ]
             }
                        """)
    
      println(json.extract[Person])
    }
  • 相关阅读:
    配置FTP服务
    Tomcat
    LNMP环境配置(下)
    LNMP环境配置(上)
    Ansible---
    Ansible
    正则三剑客-------grep
    Docker仓库的使用与维护
    Docker 引擎的安装 -->>存储库安装
    shell脚本实例
  • 原文地址:https://www.cnblogs.com/xinsheng/p/4346485.html
Copyright © 2011-2022 走看看