joda time, jackson 与 scala 反射
1. scala 反射,获得所有 field name
可以直接从 case class 获得 field 而不必创建实例 (get fields of a class without an instance)
def extractFieldNames[T<:Product:Manifest] = {
implicitly[Manifest[T]].erasure.getDeclaredFields.map(_.getName)
}
case class Person(name:String, age:Int)
scala> extractFieldNames[Person]
res4: Array[java.lang.String] = Array(name, age)
2. Joda time
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)
3. Jackson 注册 Module 用于序列化
同时也了解到,objectMapper 可以一次注册多个 module,这种可拔插的设计用起来真的很舒心。
在第一段代码中,用到了 scala 反射机制。其实这段代码的主要目标是编写一个简单的数据转换器,从 mysql resultSet 转到 case class。转换的步骤是这样的:
- 通过 case class instance 获得所有 field name
- 通过这些 field name 配合 result set 的 resultSet("column name") 获得对应的 value,拼装成 map
- 将 map 转化到 json string
- jackson 把 json string 映射到 case class
虽说实现了转换,但是代码非常的 ugly。首先,我们要用到的是 case class instance 而不是 case class 本身,这意味着必须创建一个 instance,这个 instance 除了提供 field 信息以外就没用了,其次,创建 instance 本身需要了解 case class 的定义,因为需要写入到构造函数中,而上面转换器的目标就在于shapeless,在于通用,这不得不让我们为 case class 编写很多的 default value。再一个,还用到了 jackson,先到 string,再转回去,非常麻烦。
注意到几个问题:
- 从 row("date") 获取的 joda.LocaDate 在 idea 中声明的是 Any,但是它内在的类型属性是保持的,强制转换成 String 会得到一串很长的东西
- ObjectMapper 可以注册多个 module,他们在转换的时候用于序列化
- 获得 case class 的 field 信息,需要初始化一个 instance,其必须调用 getDeclaredFields 而不是 getFields。获得的属性按照声明顺序给出,是个array
- Field 通过 getName 获得属性名,getType 获得属性类型
joda time, jackson 与 scala 反射的更多相关文章
- 初识Scala反射
我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...
- 了解Scala反射
本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...
- 一篇入门 -- Scala 反射
本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...
- Scala反射(二)
我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...
- Scala - 处理时间(nscala-time - Joda Time的scala封装)
GITHUB : https://github.com/nscala-time/nscala-time MAVEN : (注意选对scala版本) <dependency> <gro ...
- Scala对class/object反射
近期有需求,要根据解析字符串,根据字符串的内容去调用方法.想到的基本就是使用反射.但是基本上能找到的资料,全没有讲scala的反射.只有零星点点的讲解.大部分都是用scala的语法写java反射最后翻 ...
- Scala进阶(1)—— 反射 object 和 class
1. Scala 的 反射 关于 Scala 反射的具体内容,可以参考官方文档:https://docs.scala-lang.org/overviews/reflection/overview.ht ...
- Scala的Json序列化
import java.util.TimeZone import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMappe ...
- 基于Spark和SparkSQL的NetFlow流量的初步分析——scala语言
基于Spark和SparkSQL的NetFlow流量的初步分析--scala语言 标签: NetFlow Spark SparkSQL 本文主要是介绍如何使用Spark做一些简单的NetFlow数据的 ...
随机推荐
- 【javascript】js 检验密码强度
最近一直在做通行证项目,里面的注册模块中输入密码需要显示密码强度(低中高).今天就把做的效果给大家分享下,代码没有网上搜索的那么复杂,能够满足一般的需求. html 代码如下: <!DOCTYP ...
- WebRTC源码分析(一):安卓相机采集实现分析
WebRTC 的代码量不小,一次性看明白不太现实,在本系列中,我将试图搞清楚三个问题: 客户端之间如何建立连接? 客户端之间如何实现数据传输? 音视频数据的采集.预览.编码.传输.解码.渲染完整流程. ...
- php 常用的标签比较
eq或者 equal 等于 neq 或者notequal 不等于 gt 大于 egt 大于等于 lt 小于 elt 小于等于 heq 恒等于 nheq 不恒等于
- JAVA多线程笔试题
一.题目内容 二.我的答案 利用了线程池.考虑了超时处理.不知道这样写是否还有其他问题,或者更好更优的解决方案? import java.util.*; import java.util.concur ...
- 100 行代码实现的 JavaScript MVC 样式框架
介绍 使用过 JavaScript框架(如 AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现 ...
- 超频,如何超频CPU和显卡?
首先是良好的硬件体制,CPU.内存和显卡都必须是健康的,在100%负荷下工作也能拥有合理的温度和功耗.其次就是硬件准备,超频需要一块强大的主板做支撑,特别是主板供电部分,考虑到CPU和内存超频后功耗大 ...
- ASK,OOK,FSK的联系和区别
转自:http://www.cnblogs.com/zhihongyu/archive/2012/04/12/2443617.html ASK是幅移键控调制的简写,例如二进制的,把二进制符号0和1分别 ...
- ThinkPHP使用memcache缓存服务器
(1)Thinkphp的默认缓存方式是以File方式,在/Runtime/Temp 下生成了好多缓存文件. 服务器装了memcached后想给更改成memecache方式 在Conf/config.p ...
- Linux之计划任务
计划任务特性 1. 需要在指定的某时间段运行 2. 需要将任务结果邮件通知用户 3. 单次任务及循环任务区别 Linux计划任务的实现工具 1. at工具 其只能执行一次性任务 其会自动加载部分环境变 ...
- 解决IE6下浮层遮盖select刺穿的问题
图一未解决刺穿问题: 图二已解决 解决方法使用iframe间接挡住层,具体方法见源码 源码一(未解决刺穿): <html xmlns=" ...