如何在自定义 java 类中表示递归 json 元素

发布于 2025-01-12 12:44:38 字数 1338 浏览 1 评论 0原文

我有下面的 json,我试图找出自定义 java 类可以表示的结构。 这是 json:

{
   "04000550":{
      "vr":"SQ",
      "Value":[
         {
            "00100010":{
               "vr":"PN",
               "Value":[
                  {
                     "Alphabetic":"TCGA-17-Z021"
                  }
               ]
            }
         }
      ]
   },
   "04000562":{
      "vr":"DT",
      "Value":[
         "20220103125232.022"
      ]
   },
   "04000563":{
      "vr":"LO",
      "Value":[
         "dcm4chee-arc"
      ]
   },
   "04000564":{
      "vr":"LO"
   },
   "04000565":{
      "vr":"CS",
      "Value":[
         "CORRECT"
      ]
   }
}

我尝试了 Map,自定义类 Tag 具有 vr 和 Value 属性,问题是 < code>Value 可以是一个一个字符串列表,或者一个Tag,基于vr属性(如果vr = "SQ ",该值的类型为Tag

我试图将此 json 映射到适当的 java 数据结构,以便我可以在 primefaces datatable 中使用它来在表中表示这些数据供用户编辑他们,如果我将此 json 表示为 Map 并且 Tag 具有 String vr, JsonNode Value,我将无法允许在 中编辑此值>素面datatable 因为它需要 Value 是一个自定义对象,该对象具有允许设置器和获取器的属性(这就是 jsf 或 primefaces 的工作方式),那么我如何映射这个 json?

顺便说一句,这是我的 primefaces 数据表

I have the below json which I'm trying to figure out which structure the custom java class can represent.
Here is the json:

{
   "04000550":{
      "vr":"SQ",
      "Value":[
         {
            "00100010":{
               "vr":"PN",
               "Value":[
                  {
                     "Alphabetic":"TCGA-17-Z021"
                  }
               ]
            }
         }
      ]
   },
   "04000562":{
      "vr":"DT",
      "Value":[
         "20220103125232.022"
      ]
   },
   "04000563":{
      "vr":"LO",
      "Value":[
         "dcm4chee-arc"
      ]
   },
   "04000564":{
      "vr":"LO"
   },
   "04000565":{
      "vr":"CS",
      "Value":[
         "CORRECT"
      ]
   }
}

I tried Map<String, Tag>, and custom class Tag has vr and Value properties, the problem is that Value can be a list of one String, or a Tag, based on vr attribute (if vr = "SQ", the Value will be of type Tag)

I'm trying to map this json to an appropriate java data structure so that I can use it in primefaces datatable to represent these data in a table for user to edit them, if I represent this json into Map<String, Tag> and Tag has String vr, JsonNode Value, I will not be able to allow edit this Value in primefaces datatable as it needs the Value to be a custom object which has properties to allow setters and getters on it (this is how jsf or primefaces work), so how can I map this json?

This is my primefaces datatable btw.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

影子是时光的心 2025-01-19 12:44:39

您可以使用 Custom Deserializer for Jackson ,然后像这样反序列化您的 JSON

ObjectMapper mapper = new ObjectMapper();
Map<String, Tag> tagMap = mapper.readValue(json, new TypeReference<>() {});

:一个解串器。它很脏,但正在工作。

POJO 类将如下所示:

@JsonDeserialize(using = TagDeserializer.class)
public class Tag {
     public final String type;
     // For other types
     public final List<String> valueList;
     // For `SQ` type
     public final Map<String, NestedTag> tags;

     // AllArgsConstructor, Getters
}

public class NestedTag {
     public final String type;
     public final Map<String, String> valueMap;
     
     // AllArgsConstructor, Getters
}

数据表将如下所示:

<p:dataTable value="#{tagController.tagMap.entrySet()}" var="entry">
    <p:column headerText="Id">
        <p:outputLabel value="#{entry.key}"/>
    </p:column>

    <p:column headerText="Type">
        <p:inputText value="#{entry.value.type}"/>
    </p:column>

    <p:column headerText="Value">
            <!--   List.toString(), you can replace it with another p:dataTable   -->
        <p:inputText value="#{entry.value.valueList}" rendered="#{entry.value.valueList != null}"/>

        <p:dataTable value="#{entry.value.tags.entrySet()}" var="nestedTag" rendered="#{entry.value.tags != null}">
            <p:column headerText="Id">
                <h:outputLabel value="#{nestedTag.key}"/>
            </p:column>

            <p:column headerText="Type">
                <p:inputText value="#{nestedTag.value.type}"/>
            </p:column>

            <p:column headerText="Value">
                    <!--   Map.toString(), you can replace it with another p:dataTable   -->
                <p:inputText value="#{nestedTag.value.valueMap}"/>
             </p:column>
        </p:dataTable>

    </p:column>

</p:dataTable>

You could use a Custom Deserializer for Jackson and then deserialize your JSON like this:

ObjectMapper mapper = new ObjectMapper();
Map<String, Tag> tagMap = mapper.readValue(json, new TypeReference<>() {});

I tried to make a deserializer. It is dirty but is working.

The POJO classes will look like this:

@JsonDeserialize(using = TagDeserializer.class)
public class Tag {
     public final String type;
     // For other types
     public final List<String> valueList;
     // For `SQ` type
     public final Map<String, NestedTag> tags;

     // AllArgsConstructor, Getters
}

public class NestedTag {
     public final String type;
     public final Map<String, String> valueMap;
     
     // AllArgsConstructor, Getters
}

The dataTable will look like this:

<p:dataTable value="#{tagController.tagMap.entrySet()}" var="entry">
    <p:column headerText="Id">
        <p:outputLabel value="#{entry.key}"/>
    </p:column>

    <p:column headerText="Type">
        <p:inputText value="#{entry.value.type}"/>
    </p:column>

    <p:column headerText="Value">
            <!--   List.toString(), you can replace it with another p:dataTable   -->
        <p:inputText value="#{entry.value.valueList}" rendered="#{entry.value.valueList != null}"/>

        <p:dataTable value="#{entry.value.tags.entrySet()}" var="nestedTag" rendered="#{entry.value.tags != null}">
            <p:column headerText="Id">
                <h:outputLabel value="#{nestedTag.key}"/>
            </p:column>

            <p:column headerText="Type">
                <p:inputText value="#{nestedTag.value.type}"/>
            </p:column>

            <p:column headerText="Value">
                    <!--   Map.toString(), you can replace it with another p:dataTable   -->
                <p:inputText value="#{nestedTag.value.valueMap}"/>
             </p:column>
        </p:dataTable>

    </p:column>

</p:dataTable>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文