Java解析json——Jackson

原创 2016年08月29日 18:33:01

在Java下,想要解析json文件,已经有了现成的Jackson框架

有几个关于Jackson的基础例子,或者也可以看本文最后的附录。看过之后也就大致了解Jackson的基本用法了。至少Java对象和json的直接转化还是比较简单的。

在这里,我主要记录一下自己使用readTree从服务器接收json并解析的过程。

需求

写一个客户端程序,客户端从服务器接收json,并解析为Java自己的对象,进行处理。客户端与服务器之间的通信使用的是最基本的Socket通信。

难点

  • 需要从InputStream,流式读取json。
  • 读取到的json可能是多种Java对象。

在我的需求中,服务器发送来的json可能会对应Java中的多种任务对象:RebootTask、UpdateTask、TicketResTask。而他们都有一个共同的父类ServerTask。在json中,使用了一个“type”字段标识他们分别是哪一种任务类型。

策略

不能直接简单的像附录一样读取并转换json,需要对json的type字段进行判断,然后才能根据type进行转换。因此,需要解析json的节点。而JsonNode可以解决我们这方面的需求。

查官网,在ObjectMapper中有readTree方法,可以从InputStream中读取数据。其返回的形式恰好为JsonNode,正好可以解决上面的两个难题。

实现

首先,我们需要初始化一个ObjectMapper,用以接收json。如果没有什么特殊需求,ObjectMapper可以简单创建ObjectMapper mapper = new ObjectMapper();,不过在这里我需要保证Socket保持连接,而不会在读取一次之后就关闭,所以需要在初始化的时候多加入一些设定。具体可以参照JsonFactory,设定其Feature。类似的还有JsonParser的FeatureJsonGenerator的Feature。有更多需求的话再去看吧。

//初始化jackson,保持socket始终连通,不会在读写一次后关闭socket连接
JsonFactory jsonFactory = new JsonFactory();
jsonFactory.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
ObjectMapper mapper = new ObjectMapper(jsonFactory);

//读取json
JsonNode rootNode = mapper.readTree(cinemaClient.getInputStream());

拿到JsonNode对象之后,就可以使用其public abstract JsonNode path(String fieldName)方法,获取type字段的内容。

然后根据public <T> T treeToValue(TreeNode n, Class<T> valueType)方法,将JsonNode(implements TreeNode)传入,再传入需要转换成的Java对象的class即可。

具体代码中,我们是将json(数组,包含多个对象)转换为多个对象,然后存到ArrayList中的,ArrayList的类型为所有任务的父类ServerTask:

    /**
     * 根据Server发来的json文件解析ServerTask,生成ServerTask对象
     * @param mapper
     * @param rootNode
     * @return
     */
    private ArrayList<ServerTask> parseTask(ObjectMapper mapper, JsonNode rootNode) {
        try {
            //获取taskList列表
            JsonNode taskList = rootNode.path(Constant.CONST_TASKLIST);

            ArrayList<ServerTask> serverTasks = new ArrayList<ServerTask>();
            if(taskList.isArray()) {
                //遍历taskList,获取type字段,并根据type将任务解析为相应的对象
                for(JsonNode jNode : taskList) {
                //两句核心代码
                    String type = jNode.path(Constant.CONST_TYPE).asText();
                    serverTasks.add(mapper.treeToValue(jNode, getTaskClass(type)));
                }
            }
            return serverTasks;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Server发送json有误:任务列表不是Array。");
            System.out.println("Server sending json ERROR: taskList is not an Array.");
            return null;
        }
    }

在上面的代码中,为了方便传入Java对象的class进行转换,我们可以先写一个根据type字段的值返回对象类型的小函数:

    /**
     * 返回ServerTask子类的类类型
     * @param type
     * @return
     */
    private Class<? extends ServerTask> getTaskClass(String type) {
        switch (type) {
            case Constant.CONST_TICKETRES :
                return TicketResTask.class;
            case Constant.CONST_UPDATE :
                return UpdateTask.class;
            case Constant.CONST_REBOOT :
                return RebootTask.class;
            default:
                System.out.println("json任务类型出错!");
                System.out.println("Type of mission in json ERROR!");
                return null;
        }
    }

至此,解析完毕。就可以完全由Java去处理ArrayList<ServerTask>对象了。

附:基础的Java对象与json转换小示例

public static <T> T fromJson(Object object, TypeReference<T> clazz) {
//        ObjectMapper mapper = new ObjectMapper();
        try {
            if(object instanceof String){
                return mapper.readValue((String) object, clazz);
            }
            else if(object instanceof File){
                return mapper.readValue((File) object, clazz);
            }
            else return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

然后就可以将json转换为TicketResTask类型的Java对象了——
读取并转换单个:

TicketResTask ticketTask = fromJson(new File("CinemaClient/resource/TicketResTask.json"), new TypeReference<TicketResTask>() {});

读取并转换多个:

ArrayList<TicketResTask> ticketTasks = fromJson(new File("CinemaClient/resource/TicketResTasks.json"), new TypeReference<ArrayList<TicketResTask>>() {});
    public static boolean toJsonFile(File file, Object object) {
//        ObjectMapper mapper = new ObjectMapper();
        try {
            mapper.writeValue(file, object);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static String toJson(Object object) {

        try {
//            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
版权声明:本文为博主原创文章,未经博主允许不得转载。

Java下利用Jackson进行JSON解析和序列化

Java下常见的Json类库有Gson、JSON-lib和Jackson等,Jackson相对来说比较高效。
  • accountwcx
  • accountwcx
  • 2014年04月27日 14:33
  • 83554

Java下利用Jackson进行JSON解析和序列化

Java下常见的Json类库有Gson、JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的J...
  • zmx729618
  • zmx729618
  • 2016年08月09日 11:18
  • 26486

Java使用jackson操作Json格式数据

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,她是 JavaScript原生态的数据格式。 她独立于任何编程语言、可读性高、易于生成和解析、体积轻量,这...
  • WJshanggan
  • WJshanggan
  • 2015年04月21日 15:02
  • 1600

Json字符串和Java对象转换利器——Jackson

Maven配置: com.fasterxml.jackson.core jackson-databind 2.1.3 实体类GetOrdersResponse:package org.jacks...
  • zhangzeyuaaa
  • zhangzeyuaaa
  • 2015年10月27日 17:07
  • 3803

Android中解析Json——Jackson使用

面是一个大神关于几个常见的Json数据的解析速度的测试结果,原文请戳http://wangym.iteye.com/blog/738933          我们从上图可以看出,在大数...
  • hanfengzqh
  • hanfengzqh
  • 2017年01月06日 15:06
  • 166

Android中解析Json——Jackson使用

面是一个大神关于几个常见的Json数据的解析速度的测试结果,原文请戳http://wangym.iteye.com/blog/738933          我们从上图可以看...
  • wuqilianga
  • wuqilianga
  • 2016年03月31日 09:56
  • 640

Android中解析Json——Jackson使用

面是一个大神关于几个常见的Json数据的解析速度的测试结果,原文请戳http://wangym.iteye.com/blog/738933          我们从上图可以看出,在大数据量的情...
  • yan8024
  • yan8024
  • 2015年05月27日 16:43
  • 8565

比Gson解析速度快10倍!——Json解析神器Jackson使用介绍

在前面的两篇文章中,我们介绍了Json数据格式和系统自带Json以及Google的Gson项目,如果能学会这些东西,基本能满足工作需求了。但是,程序员都有追求极致效率的嗜好,在满足了基本需求之...
  • dzc372787439
  • dzc372787439
  • 2015年04月08日 14:47
  • 1507

【Android开发经验】比Gson解析速度快10倍!——Json解析神器Jackson使用介绍

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992    因为在之前的项目中,xml和json数据格式都用过,所以深深的了解在java语言的编程中,使用json...
  • bz419927089
  • bz419927089
  • 2014年11月27日 18:34
  • 10636

Java下利用Jackson进行JSON解析和序列化

Java下常见的Json类库有Gson、JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的J...
  • z69183787
  • z69183787
  • 2015年05月29日 14:49
  • 1612
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java解析json——Jackson
举报原因:
原因补充:

(最多只允许输入30个字)