放牧代码和思想
专注自然语言处理、机器学习算法
    This thing called love. Know I would've. Thrown it all away. Wouldn't hesitate.

五分钟Jackson入门(四) JSON Streaming API (附项目源码)

据说Streaming API 的效率是最高的,写入的时候直接调用JsonGenerator.writexxxfield,最后一个close就flush到文件了。不过读取的时候则比较蠢(?),需要一个while循环,不断地将文件里的字段与对象的字段作是否等于的比较,然后setField。

这次Demo里需要用到User.class,在第一个Demo的基础上改好了:

项目结构:

package com.hankcs;

import org.codehaus.jackson.*;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;

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) throws IOException
    {
        JsonFactory f = new JsonFactory();
        JsonGenerator g = f.createJsonGenerator(new File("user.json"), JsonEncoding.UTF8);

        g.writeStartObject();
        g.writeObjectFieldStart("name");
        g.writeStringField("first", "Joe");
        g.writeStringField("last", "Hankcs");
        g.writeEndObject(); // for field 'name'
        g.writeStringField("gender", "MALE");
        g.writeBooleanField("verified", false);
        g.writeFieldName("userImage"); // no 'writeBinaryField' (yet?)
        byte[] binaryData = {0x1, 0x2, 0x3};
        g.writeBinary(binaryData);
        g.writeEndObject();
        g.close(); // important: will force flushing of output, close underlying output stream

        // 解析
//        JsonFactory f = new JsonFactory();
        JsonParser jp = f.createJsonParser(new File("user.json"));
        User user = new User();
        jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
        while (jp.nextToken() != JsonToken.END_OBJECT)
        {
            String fieldname = jp.getCurrentName();
            jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
            if ("name".equals(fieldname))
            { // contains an object
                User.Name name = new User.Name();
                while (jp.nextToken() != JsonToken.END_OBJECT)
                {
                    String namefield = jp.getCurrentName();
                    jp.nextToken(); // move to value
                    if ("first".equals(namefield))
                    {
                        name.setFirst(jp.getText());
                    }
                    else if ("last".equals(namefield))
                    {
                        name.setLast(jp.getText());
                    }
                    else
                    {
                        throw new IllegalStateException("Unrecognized field '" + fieldname + "'!");
                    }
                }
                user.setName(name);
            }
            else if ("gender".equals(fieldname))
            {
                user.setGender(User.Gender.valueOf(jp.getText()));
            }
            else if ("verified".equals(fieldname))
            {
                user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
            }
            else if ("userImage".equals(fieldname))
            {
                user.setUserImage(jp.getBinaryValue());
            }
            else
            {
                throw new IllegalStateException("Unrecognized field '" + fieldname + "'!");
            }
        }
        jp.close(); // ensure resources get cleaned up timely and properly
        System.out.println(user);
    }
}

输出:

User{_gender=MALE, _name=Name{_first='Joe', _last='Hankcs'}, _isVerified=false, _userImage=[1, 2, 3]}

对于数组类型的JSON数据,则简单了不少:

 // 对于数组有更好的方法
        ObjectMapper mapper = new ObjectMapper();
        String json = "[{\"foo\": \"bar\"},{\"foo\": \"biz\"}]";
        jp = f.createJsonParser(json);
        // advance stream to START_ARRAY first:
        jp.nextToken();
        // and then each time, advance to opening START_OBJECT
        while (jp.nextToken() == JsonToken.START_OBJECT)
        {
            Foo foobar = mapper.readValue(jp, Foo.class);
            // process
            System.out.println(foobar);
            // after binding, stream points to closing END_OBJECT
        }

输出:

Foo{foo='bar'}
Foo{foo='biz'}

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

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

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » 五分钟Jackson入门(四) JSON Streaming API (附项目源码)

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    小数如何处理,保留2位 BigDecimal类型的

    我是你的小蛋糕8年前 (2016-05-24)回复

我的作品

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