• java json对象转json字符串(带转义符)(json对象嵌套json字符串)


    1.情景展示

      如上图所示,这一个标准的json字符串,双引号需要使用反斜杠进行转义,

      一般情况下,我们是用不到这种json字符串的,在java中,json字符串的通常表现形式是这种:

      其本质还是json对象,并不是真正意义上的json字符串(即使将json对象转字符串),哪里会用到上面那种带转义符的json字符串?(下面示例)

      完整请求参数:

      后台用实体类接收,且Person用的是字符串String来接收的 

      一般情况下,是不会出现这种变态需求的,明明是json对象,却用字符串接收,我们通常通过java后台发送http请求时,往往传送的数据格式是这样的:

      而我们一旦使用这种标准的json数据格式发送请求,对方服务器在接收到数据后往Person里塞数据时,将会报错:大致信息是-需要的是字符串,提供的却是json对象。

      ↓↓↓如果是想在json对象里嵌套json字符串,直接看最后↓↓↓

      如何生成这种格式的数据?

    2.具体实践

      准备工作:

      JSON对象常用的有两种:一种是net.sf.json.JSONObject,另一种是com.alibaba.fastjson.JSONObect

      错误示例一:调用原生的toString()方法

      这是java形式的json字符串,无论是net的toString()还是ali的toString()、toJSONString()方法,里面存的还是对象,并不是我们想要的结果

      错误示例二:使用FackJson

      import com.fasterxml.jacks on.core.io.JsonStringEncoder;

      这种是javascript形式的json字符串,虽然离目标近了,但还是不是我们想要的结果

      错误示例三:使用StringEscapeUtils

      import org.apache.commons.lang.StringEscapeUtils

      还是不行,生成的也是JavaScript形式的json字符串 

    3.解决方案

      方式一:通过Jackson实现

      所需jar包:

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

      导入:

    import com.fasterxml.jackson.core.io.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    

      代码实现:

    /*
     * json转字符串(带转义符且两边带双引号)
     * @attention: 与 当formatJson()的入参为json字符串 实现的效果一致
     * @date: 2020年10月24日 0024 10:01
     * @param: json JSONObject/JSONArray
     * @return: java.lang.String 字符串(带转义符)
     */
    public static String toJsonString(Object json) {
        if (null == json) return "";
    
        String jsonStr = "";
    
        // JSONObject,JSONArray 都实现了JSON接口
        if (json instanceof net.sf.json.JSONObject || json instanceof net.sf.json.JSONArray || json instanceof com.alibaba.fastjson.JSONObject || json instanceof com.alibaba.fastjson.JSONArray) {
            Map<String, String> map = new HashMap<>(1);
            ObjectMapper om = new ObjectMapper();
    
            map.put("JSON", json.toString());
            try {
                jsonStr = om.writeValueAsString(map.get("JSON"));
            } catch (JsonProcessingException e) {
                log.error(e.getMessage());
                e.printStackTrace();
                return "";
            }
    
            log.debug("json-->字符串前:
    " + json.toString());
            log.debug("json-->字符串后:
    " + jsonStr);
        } else {
            log.error("不是json格式数据");
        }
    
        return jsonStr;
    }

      方式二:通过谷歌的Gson实现

      所需jar包:

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

      导包:

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    

      代码实现:

    /*
     * json对象转格式化后的json字符串
     * @attention: 入参格式不同,返回结果不同
     * @date: 2020年11月12日 0012 15:32
     * @param: json
     *  如果参数是json对象,返回的将是:格式化后的json字符串(小于号>会被转码成u003c,大于号>会被转码成u003e,且替换无效);
     *  如果参数是json字符串,返回的将是:带转义符且两边带双引号的json字符串;
     *  当参数是json字符串时,实现的效果与toJsonString()方法一样
     * @return: java.lang.String
     */
    public static String formatJson(Object json) {
        // 非空校验
        if (null == json) return "";
    
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setPrettyPrinting();
        Gson gson = gsonBuilder.create();
        String jsonStr = gson.toJson(json);
        // 替换无效
        // jsonStr = jsonStr.replaceAll("\u003c","<").replaceAll("\u003e", ">");
    
        log.debug("json字符串格式化前:
    " + json.toString());
        log.debug("json字符串格式化后:
    " + jsonStr);
        return jsonStr;
    }
    

    4.测试  

      测试一:

      上面的这两种方式,会在生成的json字符串两边加上双引号

      测试二:

      方式一:

    public static void main(String[] args) {
        JSONObject jo = new JSONObject();
        jo.put("name","Marydon");
        jo.put("age",18);
        JSONObject params = new JSONObject();
        params.put("Person", toJsonString(jo));
        params.put("Time", "2020-11-12");
        System.out.println(params.toString().replace("\\", ""));
    }
    

      方式二:

    public static void main(String[] args) {
        JSONObject jo = new JSONObject();
        jo.put("name","Marydon");
        jo.put("age",18);
        JSONObject params = new JSONObject();
        params.put("Person", formatJson(jo.toString()));
        params.put("Time", "2020-11-12");
        System.out.println(params.toString().replace("\\", ""));
    }
    

      方式三:

    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.3</version>
    </dependency> 

      方式四:Jackson核心包

      如果是json对象嵌套json字符串,则上面4种方式都可以实现(但不一定能用,未测试)。

    5.json对象嵌套json字符串

      已知这种数据

      需要转成这种数据

    public static void main(String[] args) {
        JSONObject jo = new JSONObject();
        jo.put("name","Marydon");
        jo.put("age",18);
        // 需要转成json字符串,外层必须使用Map组装数据(不能用json)
        Map<String,String> params = new HashMap<>();
        params.put("Person", jo.toString());
        params.put("Time", "2020-11-12");
        try {
            System.out.println(params);
            // 由Jackson将map转成json字符串,再转成json对象
            JSONObject json = JSONObject.fromObject(new ObjectMapper().writeValueAsString(params));
            System.out.println(json);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    
    }
    

     

    2021-06-11

      我发现了一个诡异的情况,那就是:

      Map转Json,当Map的Value带有闭合标签时,转化成json后,会被强制添加转义符"",一起来看下:

    Map<String, Object> map = new HashMap<>(2);
    map.put("name", "<Name>Marydon</name>");
    map.put("website", "<Blog>https://www.cnblogs.com/Marydon20170307/</Blog>");
    

      使用net.sf.json将map转json

    System.out.println(JSONObject.fromObject(map));
    

      被强制添加了转义符

      解决办法:

      使用com.alibaba.fastjson

    System.out.println(JSONObject.toJSONString(map));
    

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    算法笔记 第3章 入门篇(1) 学习笔记
    算法笔记 上机训练实战指南 第3章 入门篇(1)--入门模拟 学习笔记 3.1简单模拟
    机器学习实战:基于Scikit-Learn和TensorFlow 第5章 支持向量机 学习笔记(硬间隔)
    机器学习实战:基于Scikit-Learn和TensorFlow 读书笔记 第6章 决策树
    算法笔记 第7章 提高篇(1)--数据结构专题(1) 学习笔记
    算法笔记 第6章 C++标准模版库(STL)介绍 学习笔记
    自然语言处理入门 何晗 读书笔记 第2章 词典分词
    自然语言处理入门 何晗 读书笔记 第1章 新手上路
    [ML]随机森林
    [ML]LightGBM论文理解
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/13878907.html
Copyright © 2020-2023  润新知