有组合关系的三个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" : ,
"address": {
"street": "Bulevard",
"city": "Helsinki"
},
"children": [
{
"name": "Mary",
"age": ,
"birthdate": "2004-09-04T18:06:22Z"
},
{
"name": "Mazy",
"age":
}
]
}
""") println(json.extract[Person])
}

spray json, jackson 转到type时多key和少key的比较的更多相关文章

  1. 解决 Jackson反序列化 Unexpected token ... , expected VALUE_STRING: need JSON String that contains type id (for subtype of ...)

    首先检查是否是 objectMapper.enableDefaultTyping(); 的受害者.优先考虑删除该配置. 使用Jackson把数组的json字符串反序列化为List时候报了个JsonMa ...

  2. Json --- Jackson工具

    一.Jackson简介 Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json.xml转换成Java对象.Jackson ...

  3. 对于json对像,怎么遍历json对象的所有key,在使用json对象时,如果无法知道key,怎么通过key变量来获取值

    对于json对像,怎么遍历json对象的所有key,在使用json对象时,如果无法知道key,怎么通过key变量来获取值?请参阅下面的关键代码: <html> <head> & ...

  4. new JSONObject(str)无法解析 报错:org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject

    org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject 解析服务器返回的Jso ...

  5. 【原创】大叔问题定位分享(12)Spark保存文本类型文件(text、csv、json等)到hdfs时为什么是压缩格式的

    问题重现 rdd.repartition(1).write.csv(outPath) 写文件之后发现文件是压缩过的 write时首先会获取hadoopConf,然后从中获取是否压缩以及压缩格式 org ...

  6. ASP.NET MVC another entity of the same type already has the same primary key value

    ASP.NET MVC项目 Repository层中,Update.Delete总是失败 another entity of the same type already has the same pr ...

  7. Github 访问时出现Permission denied (public key)

    一. 发现问题: 使用 git clone 命令时出现Permission denied (public key) . 二. 解决问题: 1.首先尝试重新添加以前生成的key,添加多次,仍然不起作用. ...

  8. Attaching an entity of type 'xxx' failed because another entity of the same type already has the same primary key value.

    问题的详细描述: Attaching an entity of type 'xxxxx' failed because another entity of the same type already ...

  9. json jackson

    1.引入依赖 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId&g ...

随机推荐

  1. Spring Cloud Config 配置中心 自动加解密功能 JCE方式

    1.首先安装JCE JDK8的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.h ...

  2. 【合集】TiDB 源码阅读系列文章

    [合集]TiDB 源码阅读系列文章 (一)序 (二)初识 TiDB 源码 (三)SQL 的一生 (四)INSERT 语句概览 (五)TiDB SQL Parser 的实现 (六)Select 语句概览 ...

  3. Linux抓包工具

    tcpdump -i em1 host 1.203.80.138 -w ~/aa.data 使用em1网卡,网卡可以通过命令ifconfig查看 host:目的或源地址是1.203.80.138的网络 ...

  4. QTcpSocket使用过程中的一些问题记录

    目前,在将原来C的socket通讯改为使用Qt类库QTcpSocket通讯,在修改过程中遇到不少问题,在此将问题一并记录,以备后面使用. 采用的通讯方式:QTimer定时器.QThread多线程和QT ...

  5. Android单行本+多渠道脚本工具

    多渠道包的build相信广大android开发者应该很熟悉了,既可以用ant,写一写正则替换然后build出n个apk, 有时后情况会更复杂些,你比如你有一个app,需要build出一些单行本,代码基 ...

  6. MD5骨骼动画模型加载(一)

    前面我们分析了静态模型OBJ格式,桢动画模型MD2,这篇主要分析骨骼动画MD5的一些概念并且实现. 混合桢动画有计算简单,容易实现等优点,但是在需要比较细致的效果时,则需要更多的关键桢,每桢都添加相同 ...

  7. C艹函数与结构体

    传递指针 代码: #include <iostream> #include <cmath> struct polar{ double distance; double angl ...

  8. WFA 认证 启动 sigma_dut方法

    WFA认证需要启动sigma_dut,记录记录一下启动过程. Android O平台命令如下 adb shell svc wifi disable adb shell rmmod wlan adb s ...

  9. 如何解决#1045 - Access denied for user 'root'@'localhost' (using password: NO)问题

    1. #1045 - Access denied for user 'root'@'localhost'  (using password: NO) 解决方案 在phpMyAdmin中librarie ...

  10. mac命令行启动tomcat

    一.修改授权 进入tomcat的bin目录,修改授权 ➜ bin pwd /Users/yp/Documents/workspace/apache-tomcat-7.0.68/bin ➜ bin su ...