Java-JSON

x33g5p2x  于2022-05-31 转载在 Java  
字(14.0k)|赞(0)|评价(0)|浏览(492)

JSON介绍

SON:JavaScript 对象表示法(JavaScript Object Notation)
JSON是存储和交换文本信息的语法。
JSON的特点:
1、JSON是轻量级的文本数据交换格式
2、JSON独立于语言和平台
3、JSON具有自我描述性,更易理解

JSON与XML
类似XML,比XML更小、更快,更易解析。
1、没有结束标签
2、更短
3、读写的速度更快
4、使用数组
5、不使用保留字

JSON的语法:
JSON语法是JavaScript对象表示法的子集。
1、数据在名称/值对中(键值对)
2、数据由逗号分隔
3、花括号保存对象
4、方括号保存数组

JSON值可以是:
1、数字(整数或浮点数)
2、字符串(在双引号中)
3、逻辑值(true或false)
4、数组(在方括号中)
5、对象(在花括号中)
6、null

JSON对象(JSON对象在花括号中书写,对象可以包含多个名称/值对)

{"firstName":"Jphn","lasrName":"Doe"}

JSON数组(JSON数组在方括号中书写,数组可包含多个对象,当然对象也可以包含数组)

{
    "employees": [
        {
            "firstName": "John",
            "lastName": "Doe",
            "hobby":["游泳","打游戏","跳舞"]
        },
        {
            "firstName": "Anna",
            "lastName": "Smith",
            "hobby":["游泳","打游戏","跳舞"]
        },
        {
            "firstName": "Peter",
            "lastName": "Jones",
            "hobby":["游泳","打游戏","跳舞"]
        },
    ]
}

常用的JSON工具

  1. Gson
  2. FastJSON
  3. Jackson(推荐)

Jackson基本教学

Jackson通过将JSON字段的名称与Java对象中的getter和setter方法进行匹配,将JSON对象的字段映射到Java对象中的属性。 Jackson删除了getter和setter方法名称的“ get”和“ set”部分,并将其余名称的第一个字符转换为小写。
如果需要以其他方式将JSON对象字段与Java对象字段匹配,则需要使用自定义序列化器和反序列化器,或者使用一些Jackson注解

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.6</version>
</dependency>

JSON字符串–>Java对象

ObjectMapper objectMapper = new ObjectMapper();
​
String carJson =
    "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
​
Car car = objectMapper.readValue(carJson, Car.class);

JSON数组字符串–>Java对象数组

String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
​
ObjectMapper objectMapper = new ObjectMapper();
​
Car[] cars2 = objectMapper.readValue(jsonArray, Car[].class);

JSON文件–>Java对象

ObjectMapper objectMapper = new ObjectMapper();
​
File file = new File("data/car.json");
​
Car car = objectMapper.readValue(file, Car.class);

JSON字节输入流–>Java对象

ObjectMapper objectMapper = new ObjectMapper();
​
InputStream input = new FileInputStream("data/car.json");
​
Car car = objectMapper.readValue(input, Car.class);

Jackson工具类

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 注意如果转换对象有内部类 那么这个对象的内部类必须设置static
// 不然报错can only instantiate non-static inner class by using default, no-argument constructor
@Slf4j
public class JsonJacksonUtil {

    private static ObjectMapper objectMapper = new ObjectMapper();
    // 日起格式化
    private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
    static {
        //对象的所有字段全部列入
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        //取消默认转换timestamps形式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        //忽略空Bean转json的错误
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
        //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
        objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
        //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        // 允许出现单引号
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    }

    /**
     * javaBean、列表(list,map),数组  转换为json字符串
     */
    @SneakyThrows
    public static String toJson(Object obj)  {
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * javaBean、列表(list,map),数组,转换为json字符串,忽略空值
     */
    @SneakyThrows
    public static String toJsonNotNull(Object obj)  {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsString(obj);
    }



    /**
     * json 转JavaBean
     */
    @SneakyThrows
    public static <T> T jsonToBean(String jsonString, Class<T> clazz)  {
        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        return objectMapper.readValue(jsonString, clazz);
    }



    /**
     *  json字符串转换为列表
     */
    @SneakyThrows
    public static <T> List<T> jsonToList(String jsonArrayStr, Class<T> clazz)  {

        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> lst = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
        return lst;
    }

    /**
     *  json字符串转换为列表
     */
    @SneakyThrows
    public static <T> T[] jsonToArray(String jsonArrayStr, Class<T> clazz)  {
        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> lst = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
        return (T[]) lst.toArray();
    }

    /**
     * json字符串  转换为map
     */
    @SneakyThrows
    public static  Map<String, Object> jsonToMap(String jsonString)  {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.readValue(jsonString, Map.class);
    }

    /**
     * json字符串 转换为map  指定转换类型
     */
    @SneakyThrows
    public static <T> Map<String, T> jsonToMap(String jsonString, Class<T> clazz)  {
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonString, new TypeReference<Map<String, Map<String, Object>>>() {
        });
        Map<String, T> result = new HashMap<String, T>();
        for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * 深度转换json成map
     *
     * @param json
     * @return
     */
    @SneakyThrows
    public static Map<String, Object> jsonToMapDepth(String json)  {
        return json2MapRecursion(json, objectMapper);
    }

    /**
     * map 转 json字符串
     *
     * @param map
     * @return
     */
    @SneakyThrows
    public static String mapToJson(Map map) {
        return objectMapper.writeValueAsString(map);
    }

    /**
     * map类型  转 指定JavaBean     原理就是key对应属性名称   value对应属性值
     */
    @SneakyThrows
    public static <T> T mapToBean(Object obj, Class<T> clazz) {
        return objectMapper.convertValue(obj, clazz);
    }

    // 将Bean转成Map     原理就是属性名称对应key   属性值对应value
    @SneakyThrows
    public static Map beanToMap(Object obj) {
        return objectMapper.readValue(toJson(obj), Map.class);
    }

    //将JSON写入文件中
    @SneakyThrows
    public  static  void writeFileJson(File file,String data){
        OutputStream outputStream= new FileOutputStream(file);
        objectMapper.writeValue(outputStream, data);
    }
    //读取文件的JSON
    @SneakyThrows
    public  static  String readFileJson(File file){
       ObjectMapper mapper= new ObjectMapper();
       JsonNode rootNode = mapper.readValue(file, JsonNode.class);
       return toJson(rootNode);
    }

    // ----------------------------------------------------底层方法----------------------------------------------------------



    /**
     * 把json解析成list,如果list内部的元素存在jsonString,继续解析
     *
     * @param json
     * @param mapper 解析工具
     * @return
     * @throws Exception
     */
    private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        }

        List<Object> list = mapper.readValue(json, List.class);

        for (Object obj : list) {
            if (obj != null && obj instanceof String) {
                String str = (String) obj;
                if (str.startsWith("[")) {
                    obj = json2ListRecursion(str, mapper);
                } else if (obj.toString().startsWith("{")) {
                    obj = json2MapRecursion(str, mapper);
                }
            }
        }

        return list;
    }




    /**
     * 把json解析成map,如果map内部的value存在jsonString,继续解析
     *
     * @param json
     * @param mapper
     * @return
     * @throws Exception
     */
    private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        }

        Map<String, Object> map = mapper.readValue(json, Map.class);

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Object obj = entry.getValue();
            if (obj != null && obj instanceof String) {
                String str = ((String) obj);

                if (str.startsWith("[")) {
                    List<?> list = json2ListRecursion(str, mapper);
                    map.put(entry.getKey(), list);
                } else if (str.startsWith("{")) {
                    Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
                    map.put(entry.getKey(), mapRecursion);
                }
            }
        }

        return map;
    }

    /**
     * 获取泛型的Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * map  转JavaBean
     */
    public static <T> T map2pojo(Map map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }

}

FastJSON

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.51</version>
        </dependency>

JSON字符串–>Java对象

public static <T> T parseObject(String text, Class<T> clazz)

JSON数组字符串–>Java对象数组

public static <T> List<T> parseArray(String text, Class<T> clazz)

JSON对象转字符串

//JSONObject  和JSONArray
 public static String toJSONString(Object object)

FastJSON工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;
import java.util.Map;

public class JsonFastJsonUtil {
    private final static Logger logger = LoggerFactory.getLogger(JsonFastJsonUtil.class);
    private static SerializeConfig config;

    static {
        config = new SerializeConfig();
        config.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
    }

    private static final SerializerFeature[] features = {
            // 输出空置字段
            SerializerFeature.WriteMapNullValue,
            // list字段如果为null,输出为[],而不是null
            SerializerFeature.WriteNullListAsEmpty,
            // 数值字段如果为null,输出为0,而不是null
            SerializerFeature.WriteNullNumberAsZero,
            // Boolean字段如果为null,输出为false,而不是null
            SerializerFeature.WriteNullBooleanAsFalse,
            // 字符类型字段如果为null,输出为"",而不是null
            SerializerFeature.WriteNullStringAsEmpty
    };

    /**
     * 将对象转为json字符串
     *
     * @param object
     * @return
     */
    public static String toFeaturesJson(Object object) {
        return JSON.toJSONString(object, config, features);
    }

    /**
     * 将对象转为json字符串
     *
     * @param object
     * @return
     */
    public static String toJson(Object object) {
        return JSON.toJSONString(object, config);
    }

    /**
     * 将json字符串转为Object实例
     *
     * @param json
     * @return
     */
    public static Object parse(String json) {
        return JSON.parse(json);
    }

    /**
     * 将json字符串转为指定类型的实例
     *
     * @param json
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T parse(String json, Class<T> cls) {
        return JSON.parseObject(json, cls);
    }

    /**
     * 将json转为Map
     *
     * @param json
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> Map<String, T> toMap(String json) {
        return (Map<String, T>) JSONObject.parseObject(json);
    }

    /**
     * 将json转为指定类型的List
     *
     * @param json
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> List<T> toList(String json, Class<T> cls) {
        return JSON.parseArray(json, cls);
    }

    /**
     *
     * @param json  必须是 JSONArray 或者JSONObject 才会进行样式转换
     * @return
     */
    public static String   pretty(JSON json){
        String pretty = JSON.toJSONString(json, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        return  pretty;
    }

}

Gson

<dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>

工具类

public class JsonGsonUtils<T> {

   private  static Gson gson ;

   static {
       GsonBuilder gsonBuilder = new GsonBuilder() ;
       // 设置成漂亮的输出
//       gsonBuilder.setPrettyPrinting();
       //设定日期解析格式
       gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss");
       gson=gsonBuilder.create();
   }

    //把json 字符串 转换为 Map
    public static Map<String, Object> jsonTurnMap(String json){
        Map<String, Object> res = null;
        try {
            res = gson.fromJson(json, new TypeToken<Map<String, Object>>() {
            }.getType());

        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }
        return res;
    }


    // 把JSOn 字符串 转实体类 泛型版
    public static <T>T jsonTurnJavaBena(String json, Class clazz){
       T res = null;
        try {
            res =  (T)gson.fromJson(json,clazz);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }
        return res;
    }

//    //把json 字符串 转换为 LIst
    public static  <T>  List<T>  jsonTurnList(String json,Class<T> clazz){
        List<T> newres = new ArrayList<>();
        List<T> res = null;
        try {
            res = gson.fromJson(json, new TypeToken<ArrayList<T>>() {}.getType());

        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }
        for (T re : res) {
            newres.add(JsonGsonUtils.jsonTurnJavaBena(JsonGsonUtils.objTurnJson(re),clazz));
        }

        return newres;
    }


    //把  实体类对象 , List , Map  转 json 字符串
    public static String objTurnJson(Object object){
        return  gson.toJson(object);
    }

}

美化输出的JSON(免依赖)

因为在有些场景下Json格式是需要给用户看的,如果不格式化那么就是一坨谁知道这是啥?

纯手写的美化json,无需任何依赖

package com.c4.utils;

public class JsonFormatTool
{
    /**
     * 单位缩进字符串。
     */
    private static String SPACE = "   ";

    /**
     * 返回格式化JSON字符串。
     *
     * @param json 未格式化的JSON字符串。
     * @return 格式化的JSON字符串。
     */
    public static String formatJson(String json)
    {
        StringBuffer result = new StringBuffer();

        int length = json.length();
        int number = 0;
        char key = 0;
        //遍历输入字符串。
        for (int i = 0; i < length; i++)
        {
            //1、获取当前字符。
            key = json.charAt(i);

            //2、如果当前字符是前方括号、前花括号做如下处理:
            if((key == '[') || (key == '{') )
            {
                //(1)如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
                if((i - 1 > 0) && (json.charAt(i - 1) == ':'))
                {
                    result.append('\n');
                    result.append(indent(number));
                }

                //(2)打印:当前字符。
                result.append(key);

                //(3)前方括号、前花括号,的后面必须换行。打印:换行。
                result.append('\n');

                //(4)每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
                number++;
                result.append(indent(number));

                //(5)进行下一次循环。
                continue;
            }

            //3、如果当前字符是后方括号、后花括号做如下处理:
            if((key == ']') || (key == '}') )
            {
                //(1)后方括号、后花括号,的前面必须换行。打印:换行。
                result.append('\n');

                //(2)每出现一次后方括号、后花括号;缩进次数减少一次。打印:缩进。
                number--;
                result.append(indent(number));

                //(3)打印:当前字符。
                result.append(key);

                //(4)如果当前字符后面还有字符,并且字符不为“,”,打印:换行。
                if(((i + 1) < length) && (json.charAt(i + 1) != ','))
                {
                    result.append('\n');
                }

                //(5)继续下一次循环。
                continue;
            }

            //4、如果当前字符是逗号。逗号后面换行,并缩进,不改变缩进次数。
            if((key == ','))
            {
                result.append(key);
                result.append('\n');
                result.append(indent(number));
                continue;
            }

            //5、打印:当前字符。
            result.append(key);
        }

        return result.toString();
    }

    /**
     * 返回指定次数的缩进字符串。每一次缩进三个空格,即SPACE。
     *
     * @param number 缩进次数。
     * @return 指定缩进次数的字符串。
     */
    private static String indent(int number)
    {
        StringBuffer result = new StringBuffer();
        for(int i = 0; i < number; i++)
        {
            result.append(SPACE);
        }
        return result.toString();
    }

    public static void main(String[] args) {
        JsonFormatTool json = new JsonFormatTool();
        String str = "{'age':23,'aihao':['pashan','movies'],'name':{'firstName':'zhang','lastName':'san','aihao':['pashan','movies','name':{'firstName':'zhang','lastName':'san','aihao':['pashan','movies']}]}}";
        String result = formatJson(str);

        System.out.println(result);

    }
}

点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复如有侵权,请私信联系我感谢,配合,希望我的努力对你有帮助^_^

相关文章