1. 程式人生 > 實用技巧 >java json物件轉json字串(帶轉義符)(json物件巢狀json字串)

java json物件轉json字串(帶轉義符)(json物件巢狀json字串)

1.情景展示

  如上圖所示,這一個標準的json字串,雙引號需要使用反斜槓\進行轉義,

  一般情況下,我們是用不到這種json字串的,在java中,json字串的通常表現形式是這種:

  其本質還是json物件,並不是真正意義上的json字串(即使將json物件轉字串),哪裡會用到上面那種帶轉義符的json字串?(下面示例)

  完整請求引數:

  後臺用實體類接收,且Person用的是字串String來接收的

  一般情況下,是不會出現這種變態需求的,明明是json物件,卻用字串接收,我們通常通過java後臺傳送http請求時,往往傳送的資料格式是這樣的:

  而我們一旦使用這種標準的json資料格式傳送請求,對方伺服器在接收到資料後往Person裡塞資料時,將會報錯:大致資訊是-需要的是字串,提供的卻是json物件。

  如何生成這種格式的資料?

2.具體實踐

  準備工作:

  JSON物件常用的有兩種:一種是net.sf.json.JSONObject,另一種是com.alibaba.fastjson.JSONObect

  錯誤示例一:呼叫原生的toString()方法

  這是java形式的json字串,無論是net的toString()還是ali的toString()、toJSONString()方法,裡面存的還是物件,並不是我們想要的結果

  錯誤示例二:使用FackJson

  importcom.fasterxml.jackson.core.io.JsonStringEncoder;

  這種是javascript形式的json字串,雖然離目標近了,但還是不是我們想要的結果

  錯誤示例三:使用StringEscapeUtils

  import org.apache.commons.lang.StringEscapeUtils

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

3.解決方案

  方式一:通過JackJson實現

/*
 * 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 jsonStr;
        }

        log.debug("json-->字串前:\n" + json.toString());
        log.debug("json-->字串後:\n" + jsonStr);
    } else {
        log.error("不是json格式資料");
    }

    return jsonStr;
}

  方式二:通過谷歌的Gson實現

/*
 * 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字串格式化前:\n" + json.toString());
    log.debug("json字串格式化後:\n" + 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("\\\\", ""));
}

  方式三:

  方式四:

  如果是json物件巢狀json字串,則上面4種方式都可以實現。

  接下來就是在傳送請求的時候,告訴對方傳遞的是json物件就可以了

  postMethod.setRequestHeader("Content-Type", "application/json;charset=UTF-8");

寫在最後

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

相關推薦: