上篇入门教程里实现了JSON数据与Java对象的相互转换,在那篇文章里,我们编写了Java对象的class所以才能存放它。实际上,在不需要class的场景下,一个Map就可以简单地将对象表示出来。
还是拿上次的Demo项目做演示,这次我们删除User.class,项目结构:
Main里改成:
package com.hankcs;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Main
{
public static void main(String[] args)
{
// write your code here
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
try
{
// 读取JSON数据
Map userData = mapper.readValue(new File("user.json"), Map.class);
System.out.println(userData);
// 写入JSON数据
userData = new HashMap();
Map nameStruct = new HashMap();
nameStruct.put("first", "Joe");
nameStruct.put("last", "Hankcs");
userData.put("name", nameStruct);
userData.put("gender", "MALE");
userData.put("verified", Boolean.FALSE);
userData.put("userImage", "Rm9vYmFyIQ==");
mapper.writeValue(new File("user-modified.json"), userData);
} catch (IOException e)
{
e.printStackTrace();
}
}
}
输出:
{name={first=Joe, last=Sixpack}, gender=MALE, verified=false, userImage=Rm9vYmFyIQ==}
/user-modified.json:
{"verified":false,"name":{"last":"Hankcs","first":"Joe"},"userImage":"Rm9vYmFyIQ==","gender":"MALE"}
值得注意的是name字段的处理,name字段是一个嵌套的map,在JSON数据里,每个Map都被一个括号包起来了。
估计Jackson库使用了反射来处理这些字段,所以所有的字段必须是对象或者包装类。一个官方的对照表:
JSON Type
Java Type
object
LinkedHashMap
array
ArrayList
string
String
number (no fraction)
Integer, Long or BigInteger (smallest applicable)
number (fraction)
Double (configurable to use BigDecimal)
true|false
Boolean
null
null
上文的Map对象类型是string-object类型的,假如遇上了泛型会怎样呢?比如Map,要知道,Java里的擦除机制可不允许使用Map.class的。
Jackson框架考虑到了这一点,这要这么干就行了:
Map result = mapper.readValue(src, new TypeReference>() { });
关于这里的匿名类的作用,可以参考我写的获取T.class的一篇文章: