gpt4 book ai didi

java - 使用 Jackson 与自定义逻辑绑定(bind) JSON 数据

转载 作者:行者123 更新时间:2023-11-30 03:52:01 24 4
gpt4 key购买 nike

我已经定义了 JSON 响应,我想将其反序列化为 Java 对象。我设法使用树模型“手动”完成此操作,但如果可能的话我想使用数据绑定(bind)。问题是我的某些部分需要一些自定义逻辑。

JSON 如下所示:

{
"resourcedescriptions": [
{
"path": "somePath",
"tag_pagetype": "default",
"tag_bookingcenter": [
"bc_ch",
"bc_de"
],
"resources": [
{
"path": "somePathDe.html",
"lang": "de",
"lastmodified": 1399020442914,
"mimetype": "text/html"
},
{
"path": "somePathEn.html",
"lang": "en",
"lastmodified": 1399907224208,
"mimetype": "text/html"
}
],
"lastmodified": 1399907224208
},
{
"path": "someOtherPath",
"tag_pagetype": "special",
"tag_bookingcenter": [
"bc_ch"
],
"resources": [
{
"path": "someOtherPathDe.html",
"lang": "de",
"lastmodified": 1399020442914,
"mimetype": "text/html"
},
{
"path": "someOtherPathEn.html",
"lang": "en",
"lastmodified": 1399907224208,
"mimetype": "text/html"
}
],
"lastmodified": 1399907224208
}
]
}

我的 Java 类是:

public class ResourceDescription {
private String path;
private LocalDateTime lastModified;
private String chartConfig;
private final List<Tag> tags = new ArrayList<Tag>();
private final List<Resource> resources = new ArrayList<Resource>();
}
public class Resource {
private String lang;
private String path;
private String mimeType;
private LocalDateTime lastModified;
}
public class Tag {
private String namespace;
private String name;
}

第一个问题,即使阅读了这里的很多帖子,我仍然不完全理解。如何将 JSON 中的资源数组反序列化到我的资源描述列表中?

第二个也是最复杂的问题。以“tag_”为前缀的 JSON 属性需要转换为 Tag 类,而属性名称代表命名空间,值(单个或数组)代表名称。因此,如果模式是“namespace:name”,第一个 ResourceDescription 将具有以下标签:

  • tag_pagetype:默认
  • tag_bookingcenter:bc_ch
  • tag_bookingcenter:bc_de

第三,“lastmodified”应该从 Joda-Time 转换为 DateTime。

这是否可以通过数据绑定(bind)实现,还是应该坚持使用树模型?

最佳答案

How do I deserialize this array of Resources from the JSON into my List of the ResourceDescription?

您必须创建额外的root类,其中包含resourcedescriptions属性。例如:

class Root {

private List<ResourceDescription> resourcedescriptions;

public List<ResourceDescription> getResourcedescriptions() {
return resourcedescriptions;
}

public void setResourcedescriptions(List<ResourceDescription> resourcedescriptions) {
this.resourcedescriptions = resourcedescriptions;
}

@Override
public String toString() {
return String.valueOf(resourcedescriptions);
}
}

The JSON properties prefixed with "tag_" need to be transformed into the Tag class, whereas the the property name represents the namespace and the value (single or array) represent the name.

您可以使用@JsonAnySetter注释来处理这种情况。您必须向 ResourceDescription 类添加新方法,如下所示:

@JsonAnySetter
public void setAnyValues(String propertyName, Object value) {
if (propertyName.startsWith("tag_")) {
if (value instanceof String) {
tags.add(new Tag(propertyName, value.toString()));
} else if (value instanceof List) {
List<?> values = (List<?>) value;
for (Object v : values) {
tags.add(new Tag(propertyName, v.toString()));
}
}
// throw exception?
} else {
// handle another unknown properties
}
}

Third the "lastmodified" should be transformed into DateTime from Joda-Time.

您可以通过添加 jackson-datatype-joda 来处理 JodaTime 类型图书馆。添加后,您可以注册 JodaModule 模块。

mapper.registerModule(new JodaModule());

另一个问题是您的 JSON 包含使用小写字母编写的属性,但您的 POJO 属性是使用驼峰式大小写编写的。您可以更改 JSONPOJO 或使用 @JsonProperty("property-name-from-JSON") 注解或实现您自己的命名策略。例如:

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.PropertyNamingStrategyBase() {
@Override
public String translate(String propertyName) {
return propertyName.toLowerCase();
}
});

如何反序列化 JSON 的完整 Java 示例:

import java.util.ArrayList;
import java.util.List;

import org.joda.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.datatype.joda.JodaModule;

public class JacksonProgram {

public static void main(String[] args) throws Exception {
String json = "{ ... }";
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.PropertyNamingStrategyBase() {
@Override
public String translate(String propertyName) {
return propertyName.toLowerCase();
}
});

System.out.println(mapper.readValue(json, Root.class));
}
}

class Root {

private List<ResourceDescription> resourcedescriptions;

public List<ResourceDescription> getResourcedescriptions() {
return resourcedescriptions;
}

public void setResourcedescriptions(List<ResourceDescription> resourcedescriptions) {
this.resourcedescriptions = resourcedescriptions;
}

@Override
public String toString() {
return String.valueOf(resourcedescriptions);
}
}

class ResourceDescription {

private String path;
private LocalDateTime lastModified;
private String chartConfig;
private final List<Tag> tags = new ArrayList<Tag>();
private final List<Resource> resources = new ArrayList<Resource>();

@JsonAnySetter
public void setAnyValues(String propertyName, Object value) {
if (propertyName.startsWith("tag_")) {
if (value instanceof String) {
tags.add(new Tag(propertyName, value.toString()));
} else if (value instanceof List) {
List<?> values = (List<?>) value;
for (Object v : values) {
tags.add(new Tag(propertyName, v.toString()));
}
}
// throw exception?
} else {
// handle another unknown properties
}
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public LocalDateTime getLastModified() {
return lastModified;
}

public void setLastModified(LocalDateTime lastModified) {
this.lastModified = lastModified;
}

public String getChartConfig() {
return chartConfig;
}

public void setChartConfig(String chartConfig) {
this.chartConfig = chartConfig;
}

public List<Tag> getTags() {
return tags;
}

public List<Resource> getResources() {
return resources;
}

@Override
public String toString() {
return "ResourceDescription [path=" + path + ", lastModified=" + lastModified
+ ", chartConfig=" + chartConfig + ", tags=" + tags + ", resources=" + resources
+ "]";
}
}

class Resource {

private String lang;
private String path;
private String mimeType;
private LocalDateTime lastModified;

public String getLang() {
return lang;
}

public void setLang(String lang) {
this.lang = lang;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public String getMimeType() {
return mimeType;
}

public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}

public LocalDateTime getLastModified() {
return lastModified;
}

public void setLastModified(LocalDateTime lastModified) {
this.lastModified = lastModified;
}

@Override
public String toString() {
return "Resource [lang=" + lang + ", path=" + path + ", mimeType=" + mimeType
+ ", lastModified=" + lastModified + "]";
}
}

class Tag {

private String namespace;
private String name;

public Tag() {
}

public Tag(String namespace, String name) {
this.namespace = namespace;
this.name = name;
}

public String getNamespace() {
return namespace;
}

public void setNamespace(String namespace) {
this.namespace = namespace;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Tag [namespace=" + namespace + ", name=" + name + "]";
}
}

以上程序打印:

[ResourceDescription [path=somePath, lastModified=2014-05-12T17:07:04.208, chartConfig=null, tags=[Tag [namespace=tag_pagetype, name=default], Tag [namespace=tag_bookingcenter, name=bc_ch], Tag [namespace=tag_bookingcenter, name=bc_de]], resources=[Resource [lang=de, path=somePathDe.html, mimeType=text/html, lastModified=2014-05-02T10:47:22.914], Resource [lang=en, path=somePathEn.html, mimeType=text/html, lastModified=2014-05-12T17:07:04.208]]], ResourceDescription [path=someOtherPath, lastModified=2014-05-12T17:07:04.208, chartConfig=null, tags=[Tag [namespace=tag_pagetype, name=special], Tag [namespace=tag_bookingcenter, name=bc_ch]], resources=[Resource [lang=de, path=someOtherPathDe.html, mimeType=text/html, lastModified=2014-05-02T10:47:22.914], Resource [lang=en, path=someOtherPathEn.html, mimeType=text/html, lastModified=2014-05-12T17:07:04.208]]]]

关于java - 使用 Jackson 与自定义逻辑绑定(bind) JSON 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24202714/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com