放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

五分钟Jackson入门(二) JSON数据与Map数据相互转换(附项目源码)

上篇入门教程里实现了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<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);
            System.out.println(userData);
            // 写入JSON数据
            userData = new HashMap<String,Object>();
            Map<String,String> nameStruct = new HashMap<String,String>();
            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<String,Object>

array

ArrayList<Object>

string

String

number (no fraction)

IntegerLong or BigInteger (smallest applicable)

number (fraction)

Double (configurable to use BigDecimal)

true|false

Boolean

null

null

上文的Map对象类型是string-object类型的,假如遇上了泛型会怎样呢?比如Map<String,User>,要知道,Java里的擦除机制可不允许使用Map<String,User>.class的。

Jackson框架考虑到了这一点,这要这么干就行了:

  Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });

关于这里的匿名类的作用,可以参考我写的获取T.class的一篇文章:

http://www.hankcs.com/program/t-class.html

项目源码:http://pan.baidu.com/s/1jGFk04I

参考资料:http://wiki.fasterxml.com/JacksonInFiveMinutes#Full_Data_Binding_.28POJO.29_Example

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » 五分钟Jackson入门(二) JSON数据与Map数据相互转换(附项目源码)

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》