joda time 与 jackson

joda time 据称是 jdk1.8 以前最好的时间系统,我觉得 joda time 的确比 java 自带的时间系统好用。java 自带的时间系统需要花很大的功夫来处理格式的问题,time 与 calendar 也没结合到一起,印象中,每次处理时间问题起码要写三行代码。因用 asyn mysql db 引入 joda time,但在 joda time 与 json 的序列化和非序列化时遇到了问题。

val res = Tag(new LocalDate, "id", "tag")
val names    = res.getClass.getDeclaredFields.map(field => field.getName)
val mapping  = names.map(name => (name -> row(name))).toMap
val str = JacksonUtils.objectMapper.writeValueAsString(mapping)
val ins = JacksonUtils.objectMapper.readValue(str, classOf[Tag])

joda time 的 toString 并不简单,比如LocalDate类型的 "2014-05-05" 转化到 json 后会有很长一串数据,再从 json 转到 joda time,jackson 报错,序列化有问题了。

在 jackson 2.0 (也就是 fastxml)以后,处理 joda time 有一种很简单的做法,就是直接注册 joda time module 到 jackson mapper

val objectMapper = new ObjectMapper()objectMapper.registerModule(DefaultScalaModule)objectMapper.registerModule(new JodaModule)

同时也了解到,objectMapper 可以一次注册多个 module,这种可拔插的设计用起来真的很舒心。

在第一段代码中,用到了 scala 反射机制。其实这段代码的主要目标是编写一个简单的数据转换器,从 mysql resultSet 转到 case class。转换的步骤是这样的:

  1. 通过 case class instance 获得所有 field name
  2. 通过这些 field name 配合 result set 的 resultSet("column name") 获得对应的 value,拼装成 map
  3. 将 map 转化到 json string
  4. jackson 把 json string 映射到 case class

虽说实现了转换,但是代码非常的 ugly。首先,我们要用到的是 case class instance 而不是 case class 本身,这意味着必须创建一个 instance,这个 instance 除了提供 field 信息以外就没用了,其次,创建 instance 本身需要了解 case class 的定义,因为需要写入到构造函数中,而上面转换器的目标就在于shapeless,在于通用,这不得不让我们为 case class 编写很多的 default value。再一个,还用到了 jackson,先到 string,再转回去,非常麻烦。

注意到几个问题:

  1. 从 row("date") 获取的 joda.LocaDate 在 idea 中声明的是 Any,但是它内在的类型属性是保持的,强制转换成 String 会得到一串很长的东西
  2. ObjectMapper 可以注册多个 module,他们在转换的时候用于序列化
  3. 获得 case class 的 field 信息,需要初始化一个 instance,其必须调用 getDeclaredFields 而不是 getFields。获得的属性按照声明顺序给出,是个array
  4. Field 通过 getName 获得属性名,getType 获得属性类型
时间: 2024-08-07 05:30:18

joda time 与 jackson的相关文章

Dubbo Jackson序列化使用说明

Jackson序列化提供了对基本数据类型和简单Bean的序列化的支持, 以及对类继承的支持. 已经经过测试的数据类型包括: Boolean/boolean Long/long Integer/int Double/double Short/short Float/float Byte/byte java.util.Date org.joda.time.DateTime 以及由这些基本数据类型组成的数组和Bean, 如 int[], String[]等. jackson序列化使用 <dubbo:p

Json 工具介绍 fastjson gson jackson

1. fastjson fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致, 是目前Java语言中最快的JSON库. fastjson接口简单易用,已经被广泛使用在缓存序列化.协议交互.Web输出.Android客户端等多种应 用场景. fastjson是java库,可以用来转换成java对象的JSON表示.它也可以用来转换为等效的java对象的JSON字符串.Fastjson可以任意的java 对象包

Jackson - Date Handling

Handling dates on Java platform is complex business. Jackson tries not to make it any harder than it has to be. Here's how. All time objects that have associated TimeZone (java.util.Calendar etc) that Jackson constructs use the standard timezone (GMT

如何正确地在Spring Data JPA和Jackson中用上Java 8的时间相关API(即JSR 310也即java.time包下的众神器)

用过的肯定知道,JSR310的时间API真的是神器,极大的方便了在Java中对时间操作的过程. JSR 310规范领导者Stephen Colebourne就是joda-time作者,其主要思想也是借鉴了joda-time,而不是直接把joda-time移植到Java平台中,API是类似的,但做了改进,具体的改进请参考其2009年的一篇文章和InfoQ对他的采访: http://blog.joda.org/2009/11/why-jsr-310-isn-joda-time_4941.html h

springboot之jackson的两种配置方式

springboot 针对jackson是自动化配置的,如果需要修改,有两种方式: 方式一:通过application.yml 配置属性说明:## spring.jackson.date-format指定日期格式,比如yyyy-MM-dd HH:mm:ss,或者具体的格式化类的全限定名 spring.jackson.deserialization是否开启Jackson的反序列化 spring.jackson.generator是否开启json的generators. spring.jackson

Jackson包依赖冲突,出现NoSuchMethodError异常

Jackson异常信息:java.lang.NoSuchMethodError java.lang.NoSuchMethodError: com.fasterxml.jackson.datatype.joda.ser.JodaDateSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Lj

java.lang.ClassNotFoundException: org.codehaus.jackson.JsonProcessingException 异常解决方案

问题: 在SpringMVC中使用Jackson实现json输出时配置如下: <!-- 输出对象转JSON支持 --> <bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list>

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields异常

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) at com.fasterxml.jackson.databind.ser.impl.IndexedListSe

使用Jackson操作Json

1.引入jasckson-core.jar,jackson-annotations.jar和jackson-databind.jar 2.因为没有做从http获取和提交json数据,所以做个数据类代替 1 class WxJson { 2 public String getAccess_token() { 3 return access_token; 4 } 5 6 public void setAccess_token(String access_token) { 7 this.access_