由于SpringBoot的依赖默认使用fasterxml-jaskson(可能是由于不想使用其他json处理包,也不知道为啥,即使其他jar包用法很简单,但是本着jar包的简洁性,还是想研究一下fasterxml-jaskson对json数据格式的创建和解析)。既然SpringBoot使用了这个jaskson依赖,一定也有它的道理。
后面发现,用这个玩意儿,可以不用创建POJO对象。这估计也是我想研究该类方法的一个原因吧。
先上代码:
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坐标:com.fasterxml.jackson.core jackson-databind 2.13.4.2 com.fasterxml.jackson.core jackson-core 2.13.4 com.fasterxml.jackson.core jackson-annotations 2.13.4 不要问我怎么知道需要这三个,因为这个:
推理呗!并且根据上面可以得到,jackson-databind.jar这个包是依赖jackson-annotations.jar 和 jackson-core.jar这两个包的!!
其中的代码片:
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格式的字符串,则一定会有keyString 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:// 如果对象解析结束则推出该层函数的解析// 递归处理出口,直接返回returnreturn;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:// 如果数组解析结束则推出该层函数的解析// 递归处理出口,直接返回returnreturn;}}} 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使用的初步探索,大家有其他的想法可以多多交流哈。