fasterxml jaskson的使用

为啥要撰写这玩儿?

由于SpringBoot的依赖默认使用fasterxml-jaskson(可能是由于不想使用其他json处理包,也不知道为啥,即使其他jar包用法很简单,但是本着jar包的简洁性,还是想研究一下fasterxml-jaskson对json数据格式的创建和解析)。既然SpringBoot使用了这个jaskson依赖,一定也有它的道理。
后面发现,用这个玩意儿,可以不用创建POJO对象。这估计也是我想研究该类方法的一个原因吧。

解析json格式字符串

先上代码:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class TestMain {

    public static final ObjectMapper MAPPER = new ObjectMapper();
    public static void main(String[] args) {

		// 定义json字符串,格式中的“需要进行转意
        String jsonStr = "{\"username\":\"hello\", \"password\": \"world\"}";

        try {
        	// JsonParser 对象中有解析json格式的方法
        	// 该方法也可以用来验证 传入的字符串是否是json格式的字符串
        	// 如果不是json格式的字符串,则会抛出异常(毕竟要抛出异常)。
            JsonParser parser = MAPPER.createParser(jsonStr);
			// TODO ...编写解析方法
			// 该部分代码将会在后面添加
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

}

maven库官网:https://mvnrepository.com/
fasterxml-json maven坐标:

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.13.4.2</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.13.4</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>2.13.4</version>
</dependency>

不要问我怎么知道需要这三个,因为这个:
请添加图片描述
推理呗!并且根据上面可以得到,jackson-databind.jar这个包是依赖jackson-annotations.jar 和 jackson-core.jar这两个包的!!

判断是否是json格式字符串

其中的代码片:

try {
 	JsonParser parser = MAPPER.createParser(jsonStr);
catch(IOException e){
 	throw new RuntimeException(e);
}

以上这段代码可以用来验证传入的字符串是否是json格式的字符串毕竟如果解析不正确,会抛出异常。

解析原理与解析函数

fasterxml-jackson是如何判断每个符号的呢?请看下面的截图:
请添加图片描述
嗯~,熟悉的味道。该枚举类定义了START_OBJECT、END_OBJECT等常量,就是用来判断传进来的字符串。但是目前没有搞懂NOT_AVAILABLE和VALUE_EMBEDDED_OBJECT具体怎么用,如果知道的博友,可以交流哈。

开始使用这个方法进行解析json字符串时,真的只是为了学习!没有其他的本意。但是,这个fasterxml-jackson包解析字符串确实比较麻烦。为此我专门研究了一个方法,给出代码:

public static void parse(JsonParser parser, JsonNode objectNode){
        try {


            ObjectNode objNode = null;
            ArrayNode arrNode = null;
            if(objectNode instanceof ObjectNode) {
                  objNode =(ObjectNode) objectNode;
            }else{
                arrNode = (ArrayNode) objectNode;
            }


            //只要是正规的json格式的字符串,则一定会有key
            String key = null;

            while(!parser.isClosed()) {
                JsonToken jsonToken = parser.nextToken();

                // 这里只过滤我们感兴趣的字段
                //
                switch (jsonToken){
                    case FIELD_NAME:
                        key = parser.getCurrentName();
                        break;
                    case VALUE_STRING:
                        String value = parser.getValueAsString();
                        objNode.put(key, value);
                        break;
                    case VALUE_NUMBER_FLOAT:
                        // 为了使得表示浮点数足够大,因此这里用getDoubleValue()来获取。
                        objNode.put(key, parser.getDoubleValue());
                        break;
                    case VALUE_NUMBER_INT:
                        objNode.put(key, parser.getIntValue());
                        break;
                    case VALUE_TRUE:
                    case VALUE_FALSE:
                        objNode.put(key, parser.getBooleanValue());
                        break;
                    case VALUE_NULL:
                        // put方法中没有可以负值null的接口,这里暂且用"null"代替。
                        objNode.put(key, "null");
                        break;

                    case START_OBJECT:
                        // 碰到值是对象的类型,则新建一个JsonNode类型的对象
                        JsonNode embededObj = MAPPER.createObjectNode();
                        if(objectNode instanceof ObjectNode) {
                            // springboot2.x.x的版本需要传个null,
                            // 即:"!objNode.isEmpty(null)"
                            if (!objNode.isEmpty()) {

                                objNode.set(key, embededObj);

                                // 递归调用处理,这里不能够和外层的else,中的parse()合并来写,因为,如果是处理根{},则不需要递归调用!
                                parse(parser, embededObj);
                            }
                        } else {
                            arrNode.add(embededObj);
                            // 递归调用处理
                            parse(parser, embededObj);
                        }


                        break;
                    case END_OBJECT:
                        // 如果对象解析结束则推出该层函数的解析
                        // 递归处理出口,直接返回return
                        return;
                    case START_ARRAY:
                        if(objectNode instanceof ObjectNode) {
                            // 当{}内部有[],就需要进入该判断。
                            if (!objectNode.isEmpty()) {
                                JsonNode arrayObj = MAPPER.createArrayNode();
                                objNode.set(key, arrayObj);
                                parse(parser, arrayObj);
//                            ((ObjectNode)objectNode).putArray(key);
                            }
                        }else{
                            // 如果根是[],并且是第一次进入该代码段,即objectNode是空的,则跳过。
                            if(!objectNode.isEmpty()) {
                                JsonNode arrObj = MAPPER.createArrayNode();
                                arrNode.add(arrObj);
                                // 递归调用处理,如果[]内部有{}则交给递归处理。
                                parse(parser, arrObj);
                            }
                        }
                        break;
                    case END_ARRAY:
                        // 如果数组解析结束则推出该层函数的解析
                        // 递归处理出口,直接返回return
                        return;

                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

以上代码是一个递归调用的代码,如果有余力,看看改成栈的形式,那是极好的。

如何使用该函数?

MAPPER.createParser()方法提供了多种解析的入口,大家可以自行选用。

public static void main(String[] args) {

        String jsonStr = "{\"username\":\"hello\", \"password\": \"world\", \"isNull\": null, \"embededObj\": {\"prop1\":\"value1\", \"prop2\": \"value2\"}, \"arrayObj\": [{\"objK1\": \"val1\"},{\"objK2\": \"val2\"}]}";

        try {

            JsonParser parser = MAPPER.createParser(jsonStr);

            // 可以从文件中解析,MAPPER.createParser(xxx)支持多种解析的入口。
            // JsonParser parser = MAPPER.createParser(new File("xxxx.json"));

            // 如果根是{} 则用MAPPER.createObjectNode()
            ObjectNode objectNode = MAPPER.createObjectNode();

            // 如果根是[] 则用MAPPER.createArrayNode()
            ArrayNode arrayNode = MAPPER.createArrayNode();


            parse(parser, objectNode);
            parse(parser, arrayNode);
            
            System.out.println(objectNode);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

以上就是对fasterxml-jackson使用的初步探索,大家有其他的想法可以多多交流哈。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
com.fasterxml.jackson.databind是Java中的一个库,用于处理JSON数据的序列化和反序列化。它是Jackson库的一部分,提供了一组用于操作和处理JSON数据的类和方法。 以下是com.fasterxml.jackson.databind的一些常见用法和示例: 1. 将Java对象序列化为JSON字符串: ```java import com.fasterxml.jackson.databind.ObjectMapper; // 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); // 将Java对象转换为JSON字符串 String json = objectMapper.writeValueAsString(object); ``` 2. 将JSON字符串反序列化为Java对象: ```java import com.fasterxml.jackson.databind.ObjectMapper; // 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); // 将JSON字符串转换为Java对象 Object object = objectMapper.readValue(json, Object.class); ``` 3. 自定义JSON序列化和反序列化规则: ```java import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; // 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); // 创建自定义序列化器 StdSerializer<MyClass> serializer = new StdSerializer<MyClass>(MyClass.class) { @Override public void serialize(MyClass value, JsonGenerator gen, SerializerProvider provider) throws IOException { // 自定义序列化逻辑 } }; // 创建自定义反序列化器 StdDeserializer<MyClass> deserializer = new StdDeserializer<MyClass>(MyClass.class) { @Override public MyClass deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 自定义反序列化逻辑 } }; // 创建SimpleModule对象,并注册自定义序列化器和反序列化器 SimpleModule module = new SimpleModule(); module.addSerializer(MyClass.class, serializer); module.addDeserializer(MyClass.class, deserializer); // 将SimpleModule对象注册到ObjectMapper中 objectMapper.registerModule(module); ``` 以上是com.fasterxml.jackson.databind库的一些基本用法和示例。你可以根据具体的需求和场景来使用这个库进行JSON数据的处理和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

majinshanNUN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值