json进阶---jackson底层之JsonParser理解使用

简介: json进阶---jackson底层之JsonParser理解使用(springboot多结构参数的映射方法的实现思路)

1.引子

如果你经常从事后端开发,那么一定会遇到各种各样的json数据,并非所有的数据都可以直接按照springboot的映射的默认规则进行映射。

以我的需求为例接受的一个参数可以是

{
  "event":"SendLinkMsg",
  "to_wxid": "wxid_rxhdmvaefp1922",
  "msg": {"xml" : "dwadadwadadwa","id" : "wxid_rxhdmvaefp1922"}
}

也可能是

{
  "event":"SendTextMsg",
  "to_wxid": "wxid_rxhdmvaefp1922",
  "msg": "草神真可爱,软软的,嘿嘿嘿"
}

毫无疑问这是两种完全不同的结构,如果直接进行映射的话势必存在一个数据无法映射的情况。

这里我们就会经常使用@JsonDeserializer手动处理参数,而其中的JsonParser则是我们不能不了解的。
在这里插入图片描述

那这里我就简单说一下JsonParser的使用方法和简单的运行原理!

2.JsonParser的简单使用和理解

1.使用JsonFactory创建JsonParser

故名思意,jsonFactory就是用于处理json的工厂,它可以把你所指定的json处理成标记的字段,它提供了解析器,让操作者高效率手动处理json成为可能。

String a = "{\n" +
                "  \"event\":\"SendLinkMsg\",\n" +
                "  \"to_wxid\": \"wxid_rxhdmvaefp1922\",\n" +
                "  \"msg\": {\"xml\" : \"dwadadwadadwa\",\"id\" : \"22131\"}";
JsonFactory jsonFactory = new JsonFactory();
JsonParser parser = jsonFactory.createParser(a)

当然也可以通过 createParser()方法传入 Reader, InputStream, URL, byte[] 或 char[] 来解析不同来源的json
在这里插入图片描述

这里我们就成功拿到了jsonfactory生成的json解析器。

2.JsonParser的使用:

解析器根据json规则把传入的json切分成带有标记的字段。

在这里插入图片描述
字段类型包括

    NOT_AVAILABLE((String)null, -1),
    START_OBJECT("{", 1),   //公共属性开始
    END_OBJECT("}", 2),     //公共属性结束
    START_ARRAY("[", 3),    //数组开始
    END_ARRAY("]", 4),      //数组结束
    FIELD_NAME((String)null, 5), //字段名
    VALUE_EMBEDDED_OBJECT((String)null, 12), 
    VALUE_STRING((String)null, 6),     //字符串值
    VALUE_NUMBER_INT((String)null, 7), //整数值
    VALUE_NUMBER_FLOAT((String)null, 8),//浮点值
    VALUE_TRUE("true", 9), //布尔值 正确
    VALUE_FALSE("false", 10), //布尔值 错误
    VALUE_NULL("null", 11); //空值

当我们处理json的时候,根据token标记,当token指针指到结尾的时候,JsonParser就会关闭,我们可以通过parser.isClosed()判断json是否解析到末尾。

parser给了我们很多操作读取字段的方法

currentToken(),nextToken()

用于返回当前token指针对应字段的类型;向右移动指针并且返回移动后的值

getCurrentName,getValueAsString()

获取当前指针对应字段的名字和值的类型。还有其他方法我就不一一阐述了

需要注意的是,当指针指向字段名的时候使用getValueAsString()并不能返回字段名对应的字段值

而指针指向值的时候使用getCurrentName却能获取对应的字段名

当然,我们也可以根据json规则,在字段名类型后面的字段必定是值类型
在这里插入图片描述
正确示例

    public static void main(String[] args) {
        String a = "{\n" +
                "  \"event\":\"SendLinkMsg\",\n" +
                "  \"to_wxid\": \"wxid_rxhdmvaefp1922\",\n" +
                "  \"msg\": {\"xml\" : \"dwadadwadadwa\",\"id\" : \"22131\"}\n" +
                "}";
        JsonFactory jsonFactory = new JsonFactory();
        try (JsonParser parser = jsonFactory.createParser(a)) {
            System.out.println(parser.currentToken());
            while(!parser.isClosed()){
                JsonToken jsonToken = parser.nextToken();
                if(JsonToken.FIELD_NAME.equals(jsonToken)){
                    String fieldName = parser.getCurrentName();
                    parser.nextToken();

                    System.out.println(fieldName+","+parser.getValueAsString());
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

3:多结构json映射解决思路:

回到最开始的问题,java是不能返回多种参数的,但是我们可以稍微变通下

我们可以把参数封装到一个实体类里,在实体类里多加一个字符串的属性
在这里插入图片描述

如果不是字符串的话就正常映射,如果是字符串的话把他打包,装到实体类的一个str属性里

那么字符串json和对象json区别很简单:

正常json是有字段名和json值的

把对应的json值封装即可
在这里插入图片描述

而单单读取字符串其实不是json数据的,仅仅会读取到一个value值,把值封装返回即可

    public Msg deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
        StringBuilder str = new StringBuilder();
        String xml = null;
        String name = null;
        String path = null;
        Integer type = null;
            while(!parser.isClosed()){
                if (parser.getValueAsString()!=null){
                    System.out.println(parser.getValueAsString());
                    str.append(parser.getValueAsString());
                }
                JsonToken jsonToken = parser.nextToken();
                if(JsonToken.FIELD_NAME.equals(jsonToken)){
                    String fieldName = parser.getCurrentName();
                    parser.nextToken();
                    if ("xml".equals(fieldName)){
                        xml = parser.getValueAsString();
                    } else if("name".equals(fieldName)){
                        name = parser.getValueAsString();
                    } else if ("path".equals(fieldName)){
                        path = parser.getValueAsString();
                    } else if ("type".equals(fieldName)){
                        type = parser.getIntValue();
                    }else {
                        str.append(parser.getValueAsString());
                    }
                }
            }
        Msg msg = new Msg(str.toString(),path,name,xml,type);
            return  msg;

    }

1.处理字符串
在这里插入图片描述
2.处理对象
在这里插入图片描述

至此需求解决,当然代码不够凝练,如果各位大佬有什么更好的思路可以一起分享交流。

相关文章
|
7月前
|
XML JSON JavaScript
javaweb实训第六天上午——JSON&SpringMVC进阶(1)
1.课程介绍 JSON; (了解) SpringMVC返回JSON; (掌握) SpringMVC文件上传、下载; (掌握) SpringMVC拦截器; (掌握) SpringMVC执行流程; (掌握) 2.JSON 2.1.JSON概述
79 0
|
7月前
|
JSON JavaScript fastjson
SpringMVC原理分析 | JSON、Jackson、FastJson
SpringMVC原理分析 | JSON、Jackson、FastJson
101 0
|
7月前
|
XML JSON 前端开发
Ajax技术【Ajax技术详解、 Ajax 的使用、Ajax请求、 JSON详解、JACKSON 的使用 】(一)-全面详解(学习总结---从入门到深化)
Ajax技术【Ajax技术详解、 Ajax 的使用、Ajax请求、 JSON详解、JACKSON 的使用 】(一)-全面详解(学习总结---从入门到深化)
181 1
|
2月前
|
JSON JavaScript Java
在Java中处理JSON数据:Jackson与Gson库比较
本文介绍了JSON数据交换格式及其在Java中的应用,重点探讨了两个强大的JSON处理库——Jackson和Gson。文章详细讲解了Jackson库的核心功能,包括数据绑定、流式API和树模型,并通过示例演示了如何使用Jackson进行JSON解析和生成。最后,作者分享了一些实用的代码片段和使用技巧,帮助读者更好地理解和应用这些工具。
116 0
在Java中处理JSON数据:Jackson与Gson库比较
|
4月前
|
JSON Java API
Jackson:SpringBoot中的JSON王者,优雅掌控数据之道
【8月更文挑战第29天】在Java的广阔生态中,SpringBoot以其“约定优于配置”的理念,极大地简化了企业级应用的开发流程。而在SpringBoot处理HTTP请求与响应的过程中,JSON数据的序列化和反序列化是不可或缺的一环。在众多JSON处理库中,Jackson凭借其高效、灵活和强大的特性,成为了SpringBoot中处理JSON数据的首选。今天,就让我们一起深入探讨Jackson如何在SpringBoot中优雅地控制JSON数据。
143 0
|
6月前
|
JSON fastjson 数据格式
使用jackson和fastjson实现list与json互转
使用jackson和fastjson实现list与json互转
|
7月前
|
JSON 安全 JavaScript
Java一分钟之-JSON处理:Gson与Jackson库
本文对比介绍了Java中常用的两个JSON库Gson和Jackson。Gson以其简洁易用和自动序列化/反序列化功能受到青睐,而Jackson则以优异性能和丰富功能(如字段忽略、日期格式化)著称。文中通过代码示例展示了两者的基本用法,并讨论了常见问题及解决策略,包括时间格式处理、循环引用和类型匹配。在实际应用中,应根据性能需求、安全性和版本兼容性选择合适的库,并遵循最佳实践。
210 0
|
7月前
|
JSON fastjson Java
Spring Boot Jackson 和Fast JSON 用哪个好啊 ?
【4月更文挑战第22天】
1118 1
|
JSON Cloud Native Java
解决Jackson解析JSON时出现的Illegal Character错误
解决Jackson解析JSON时出现的Illegal Character错误
919 0
|
7月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
145 0