一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 復(fù)雜JSON字符串轉(zhuǎn)換為Java嵌套對象的實(shí)現(xiàn)

復(fù)雜JSON字符串轉(zhuǎn)換為Java嵌套對象的實(shí)現(xiàn)

2022-01-07 13:17琴水玉 Java教程

這篇文章主要介紹了復(fù)雜JSON字符串轉(zhuǎn)換為Java嵌套對象的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

背景

實(shí)際開發(fā)中,常常需要將比較復(fù)雜的 JSON 字符串轉(zhuǎn)換為對應(yīng)的 Java 對象。這里記錄下解決方案。

如下所示,是入侵事件檢測得到的 JSON 串:

[{"rule_id":"反彈shell","format_output":"進(jìn)程 pname 反向連接到 %dest_ip%:%dest_port%","info":{"process_events":{"pid":21,"pname":"nginx","cmdline":"curl www.cfda.com","ppid":7,"ppname":"bash"},"proc_trees":[{"pid":21,"pname":"nginx","cmdline":"curl www.cfda.com","ppid":7,"ppname":"bash"}],"containers":{"container_id":"fef4636d8403871c2e56e06e51d609554564adbbf8284dd914a0f61130558bdf","container_name":"nginx","image_id":"4eb8f7c43909449dbad801c50d9dccc7dc86631e54f28b1a4b13575729065be8","status":"Running"},"sockets":{"src_ip":"127.0.0.1","src_port":"8080","type":"1","in_out":"0","dest_ip":"localhost","dest_port":"80"}}}]

方法

預(yù)備工作

把上述 json 串放在 src/test/resources 下,寫一個(gè)文件讀寫程序來解析。 其實(shí)放在哪里不重要,重要的是拿到這個(gè) JSON 串便于后續(xù)解析。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static String readFromSource(String filename) {
    try {
      InputStream is = RWTool.class.getResourceAsStream(filename);
      byte[] bytes = new byte[4096];
      int num = 0;
      String json = "";
      while((num=is.read(bytes))>0){
        json=new String(bytes,0,num);
      }
      return json;
    } catch (Exception ex) {
      throw new RuntimeException(ex.getCause());
    }
}

構(gòu)建對象模型

首先,要根據(jù)這個(gè) JSON 字符串解析出對應(yīng)的數(shù)據(jù)模型 AgentDetectEventData。主要就是按照 JSON 串中的 key 的層次結(jié)構(gòu)來建立。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
@Getter
@Setter
public class AgentDetectEventData {
    @SerializedName("rule_id")
    @JsonProperty("rule_id")
    private String ruleId;
    @SerializedName("format_output")
    @JsonProperty("format_output")
    private String formatOutput;
    @SerializedName("info")
    @JsonProperty("info")
    private AgentDetectEventDetail info;
}
@Getter
@Setter
public class AgentDetectEventDetail {
    @SerializedName("process_events")
    @JsonProperty("process_events")
    private ProcessEvent processEvent;
    @SerializedName("proc_trees")
    @JsonProperty("proc_trees")
    private List<ProcessTree> procTree;
    @SerializedName("containers")
    @JsonProperty("containers")
    private Container container;
    @SerializedName("sockets")
    @JsonProperty("sockets")
    private Socket socket;
}
@Getter
@Setter
public class ProcessEvent {
    @SerializedName("pid")
    @JsonProperty("pid")
    private String pid;
    @SerializedName("pname")
    @JsonProperty("pname")
    private String pname;
    @SerializedName("cmdline")
    @JsonProperty("cmdline")
    private String cmdline;
    @SerializedName("ppid")
    @JsonProperty("ppid")
    private String ppid;
    @SerializedName("ppname")
    @JsonProperty("ppname")
    private String ppname;
}
@Getter
@Setter
public class ProcessTree {
    @SerializedName("pid")
    @JsonProperty("pid")
    private String pid;
    @SerializedName("pname")
    @JsonProperty("pname")
    private String pname;
    @SerializedName("cmdline")
    @JsonProperty("cmdline")
    private String cmdline;
    @SerializedName("ppid")
    @JsonProperty("ppid")
    private String ppid;
    @SerializedName("ppname")
    @JsonProperty("ppname")
    private String ppname;
}
@Getter
@Setter
public class Container {
    @SerializedName("container_id")
    @JsonProperty("container_id")
    private String containerId;
    @SerializedName("container_name")
    @JsonProperty("container_name")
    private String containerName;
    @SerializedName("image_id")
    @JsonProperty("image_id")
    private String imageId;
    @SerializedName("status")
    @JsonProperty("status")
    private String status;
}
@Getter
@Setter
public class Socket {
    @SerializedName("src_ip")
    @JsonProperty("src_ip")
    private String srcIp;
    @SerializedName("src_port")
    @JsonProperty("src_port")
    private String srcPort;
    @SerializedName("type")
    @JsonProperty("type")
    private String type;
    @SerializedName("in_out")
    @JsonProperty("in_out")
    private String inOut;
    @SerializedName("dest_ip")
    @JsonProperty("dest_ip")
    private String destIp;
    @SerializedName("dest_port")
    @JsonProperty("dest_port")
    private String destPort;
}

這里有兩個(gè)注意點(diǎn):

  • JSON 字符串的字段命名是下劃線形式,而 Java 對象的屬性命名是駝峰式的,這里需要做一個(gè)字段名映射轉(zhuǎn)換。 使用 Jackson 庫來轉(zhuǎn)換,是 @JsonProperty 注解; 使用 gson 庫來轉(zhuǎn)換,是 @SerializedName 注解。
  • 需要加 getter / setter 方法。

對象模型建立后,就成功了一大半。接下來,就是使用 json 庫來解析了。

使用jackson 庫解析

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public class JsonUtil {
  private static Logger logger = LoggerFactory.getLogger(JsonUtil.class);
  private static final ObjectMapper MAPPER = new ObjectMapper();
  static {
    // 為保持對象版本兼容性,忽略未知的屬性
    MAPPER.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // 序列化的時(shí)候,跳過null值
    MAPPER.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    // date類型轉(zhuǎn)化
    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    MAPPER.setDateFormat(fmt);
  }
  /**
   * 將一個(gè)json字符串解碼為java對象
   *
   * 注意:如果傳入的字符串為null,那么返回的對象也為null
   *
   * @param json json字符串
   * @param cls  對象類型
   * @return 解析后的java對象
   * @throws RuntimeException 若解析json過程中發(fā)生了異常
   */
  public static <T> T toObject(String json, Class<T> cls) {
    if (json == null) {
      return null;
    }
    try {
      return MAPPER.readValue(json, cls);
    } catch (Exception e) {
      throw new RuntimeException(e.getCause());
    }
  }
  public static <T> String objectToJson(T obj){
    if(obj == null){
      return null;
    }
    try {
      return obj instanceof String ? (String) obj : MAPPER.writeValueAsString(obj);
    } catch (Exception e) {
      return null;
    }
  }
  public static <T> T jsonToObject(String src, TypeReference<T> typeReference){
    if(StringUtils.isEmpty(src) || typeReference == null){
      return null;
    }
    try {
      return (T)(typeReference.getType().equals(String.class) ? src : MAPPER.readValue(src, typeReference));
    } catch (Exception e) {
      logger.warn("Parse Json to Object error",e);
      throw new RuntimeException(e.getCause());
    }
  }
  public static <T> T jsonToObject(String src, Class<?> collectionClass,Class<?>... elementClasses){
    JavaType javaType = MAPPER.getTypeFactory().constructParametricType(collectionClass,elementClasses);
    try {
      return MAPPER.readValue(src, javaType);
    } catch (Exception e) {
      logger.warn("Parse Json to Object error",e);
      throw new RuntimeException(e.getCause());
    }
  }
}

單測:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class JsonUtilTest {
    @Test
    public void testParseJson() {
        String json = RWTool.readFromSource("/json.txt");
        List<AgentDetectEventData> ade = JsonUtil.jsonToObject(json, new TypeReference<List<AgentDetectEventData>>() {});
        Assert.assertNotNull(ade);
    }
    @Test
    public void testParseJson2() {
        String json = RWTool.readFromSource("/json.txt");
        List<AgentDetectEventData> ade = JsonUtil.jsonToObject(json, List.class, AgentDetectEventData.class);
        Assert.assertNotNull(ade);
    }
}

引入POM依賴為:

?
1
2
3
4
5
<dependency>
       <groupId>org.codehaus.jackson</groupId>
       <artifactId>jackson-mapper-asl</artifactId>
       <version>1.9.4</version>
</dependency>

使用GSON解析

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class GsonUtil {
  static GsonBuilder gsonBuilder = null;
  static {
    gsonBuilder = new GsonBuilder();
    gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss");
  }
  public static Gson getGson() {
    return gsonBuilder.create();
  }
  public static <T> T fromJson(String json, Class<T> cls) {
    return getGson().fromJson(json, cls);
  }
  public static <T> T fromJson(String json, Type type) {
    return getGson().fromJson(json, type);
  }
}

單測:

?
1
2
3
4
5
6
7
8
public class GsonUtilTest {
    @Test
    public void testParseJson() {
        String json = RWTool.readFromSource("/json.txt");
        List<AgentDetectEventData> ade = GsonUtil.fromJson(json, new TypeToken<List<AgentDetectEventData>>(){}.getType());
        Assert.assertNotNull(ade);
    }
}

引入 POM 為:

?
1
2
3
4
5
<dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
       <version>2.3.1</version>
</dependency>

不含列表的嵌套對象

如果是不含列表的嵌套對象,則使用帶 Class cls 入?yún)⒌姆椒ǎ?/p>

?
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void testParseSimpleNestedJson() {
    String json = "{\"goods\":{\"desc\":\"2箱*250g\",\"goodsId\":8866,\"orderNo\":\"E20210522120237009258\",\"shopId\":659494,\"title\":\"認(rèn)養(yǎng)一頭牛\"},\"order\":{\"bookTime\":1621656157,\"codPay\":false,\"deliveryType\":\"express\",\"orderNo\":\"E20210522120237009258\",\"shopId\":659494,\"userId\":1476}}";
    BookInfo bookInfo = JsonUtil.toObject(json, BookInfo.class);
    Assert.assertNotNull(bookInfo);
}
@Test
public void testParseSimpleNestedJson() {
    String json = "{\"goods\":{\"desc\":\"2箱*250g\",\"goodsId\":8866,\"orderNo\":\"E20210522120237009258\",\"shopId\":659494,\"title\":\"認(rèn)養(yǎng)一頭牛\"},\"order\":{\"bookTime\":1621656157,\"codPay\":false,\"deliveryType\":\"express\",\"orderNo\":\"E20210522120237009258\",\"shopId\":659494,\"userId\":1476}}";
    BookInfo bookInfo = GsonUtil.fromJson(json, BookInfo.class);
    Assert.assertNotNull(bookInfo);
}

讀者可以自行解析出 BookInfo 的對象模型。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.cnblogs.com/lovesqcc/p/14798434.html

延伸 · 閱讀

精彩推薦
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯(cuò)誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)搶紅包功能,采用多線程模擬多人同時(shí)搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

    這篇文章主要為大家分享了20個(gè)非常實(shí)用的Java程序片段,對java開發(fā)項(xiàng)目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望...

    spcoder14552021-10-18
主站蜘蛛池模板: 欧美综合亚洲图片综合区 | 无码乱人伦一区二区亚洲 | 白丝校花掀起短裙呻吟小说 | 欧美日韩人成在线观看 | 亚洲人成在线观看一区二区 | 五月婷婷丁香色 | 美女做又爽又黄又猛 | 希望影院高清免费观看视频 | 鄂州一家三口完整版免费 | 午夜国产精品福利在线观看 | 免费一区二区 | 四虎音影| 成年人视频在线免费观看 | 成年人视频在线播放 | 爱草视频| 免费理伦片高清在线 | 亚洲日本va中文字幕 | 欧美视频网址 | 日日碰日日操 | 成人国产午夜在线视频 | 久久爽狠狠添AV激情五月 | 国产91区 | 91影视在线看免费观看 | 天堂成人影院 | 69短视频| 亚洲色图综合网 | 国产欧美日韩精品一区二区三区 | 果冻传媒在线播放1 | chinese圣水黄金调教 | 欧美成人aletta ocean | 久久久精品成人免费看 | 小妇人电影免费完整观看2021 | 久久精品一区二区三区资源网 | 成人不卡在线 | 91高清在线视频 | 日本丰满www色 | 成人国产精品一级毛片视频 | 亚洲H成年动漫在线观看不卡 | 免费观看美景之屋 | 日本男男gayxxxxx免费 | 天堂成人影院 |