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。转换的步骤是这样的:

  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 获得属性类型

joda time, jackson 与 scala 反射的更多相关文章

  1. 初识Scala反射

    我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...

  2. 了解Scala反射

    本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...

  3. 一篇入门 -- Scala 反射

    本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...

  4. Scala反射(二)

    我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...

  5. Scala - 处理时间(nscala-time - Joda Time的scala封装)

    GITHUB : https://github.com/nscala-time/nscala-time MAVEN : (注意选对scala版本) <dependency> <gro ...

  6. Scala对class/object反射

    近期有需求,要根据解析字符串,根据字符串的内容去调用方法.想到的基本就是使用反射.但是基本上能找到的资料,全没有讲scala的反射.只有零星点点的讲解.大部分都是用scala的语法写java反射最后翻 ...

  7. Scala进阶(1)—— 反射 object 和 class

    1. Scala 的 反射 关于 Scala 反射的具体内容,可以参考官方文档:https://docs.scala-lang.org/overviews/reflection/overview.ht ...

  8. Scala的Json序列化

    import java.util.TimeZone import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMappe ...

  9. 基于Spark和SparkSQL的NetFlow流量的初步分析——scala语言

    基于Spark和SparkSQL的NetFlow流量的初步分析--scala语言 标签: NetFlow Spark SparkSQL 本文主要是介绍如何使用Spark做一些简单的NetFlow数据的 ...

随机推荐

  1. sqoop 常见错误以及处理方式

    Oracle: Connection Reset Errors 错误代码 // :: INFO mapred.JobClient: Task Id : attempt_201105261333_000 ...

  2. IDEA 修改文件编码

    Intellij Idea 修改 properties 文件编码 现象:idea 默认的properties文件是GBK,当有中文时,不同的客户端配置的编码不同时,可能产生中文乱码. 解决:修改pro ...

  3. Java设计模式(1)工厂模式(Factory模式)

    工厂模式定义:提供创建对象的接口. 为何使用工厂模式 工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见. 为什么工厂模式是如此常用?因 ...

  4. python 按照自然数排序遍历文件 python os.listdir sort by natural sorting

    import os import re def sorted_aphanumeric(data): convert = lambda text: int(text) if text.isdigit() ...

  5. Linux入门教程:如何检查Linux系统的最后重启时间

    问题: 是否有一个命令可以快速地检查系统已经运行了多久? 也就是我怎么知道Linux系统最后的重启时间? 有许多方法来查询系统最后的重启时间. 方法一 第一种方法是使用last命令. $ last r ...

  6. ie10以上媒体查询 css

    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { }

  7. 错误 未能找到类型或命名空间名称"xxxxxx"的真正原因

    今天又被这问题撞上了,结果神奇般的解决了 谷歌了很久都没有找到真正有用的解决方案,所以在这儿写下,让更多的人看到 最根本的原因其实就是引用的问题,引用错了,然后VS在这上面提示又不够智能,所以大家被坑 ...

  8. Xcode - 升级后模拟器无法响应电脑键盘

    链接 Q: I used to be able to type with my real mac keyboard after launching the iPhone Simulator. Typi ...

  9. browser process request

    What really happens when you navigate to a URL Beginner’s Guide: How IIS Process ASP.NET Request Wha ...

  10. CentOS 经常使用系统命令

    # uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue   # 查看操作系统版本号# cat /proc/cpuinfo      # 查看CPU信息# ...