如何使用Jackson将JSON字段名转换为javabean类属性
我可以访问返回JSON字符串的RESTful API,例如:如何使用Jackson将JSON字段名转换为javabean类属性,java,json,jackson,Java,Json,Jackson,我可以访问返回JSON字符串的RESTful API,例如: { "Container1": { "active": true }, "Container2": { "active": false }, } 问题是RESTful API设计有点不当。字段名已包含数据。使用Jackson库,无法将字段名反序列化为相应javabean类的属性名。我想,JSON规范也不打算这样做。上述JSON字符串需要反序列化为以下类的实例: 公营货柜
{
"Container1": {
"active": true
},
"Container2": {
"active": false
},
}
问题是RESTful API设计有点不当。字段名已包含数据。使用Jackson库,无法将字段名反序列化为相应javabean类的属性名。我想,JSON规范也不打算这样做。上述JSON字符串需要反序列化为以下类的实例:
公营货柜{
私有布尔活动;
私有字符串名称;
}
最后,字段Container1出现无法识别的属性异常
我想配置为忽略未知属性,并为该属性提供JsonDeserializer,如下所示:
@JsonIgnorePropertiesignoreUnknown=true
公营货柜{
私有布尔活动;
私有字符串名称;
@JsonDeserializeusing=fieldnameTropertyDeserializer.class
public void setNameString名称{
this.name=名称;
}
}
和FieldNameTopPropertyDeserializer:
公共类FieldNameTopPropertySerializer扩展了STDESerializer{
公共字段名TopPropertySerializer{
超弦级;
}
@凌驾
公共字符串反序列化JSONParser解析器,反序列化上下文上下文抛出IOException,JsonProcessingException{
返回parser.getCurrentName;
}
}
反序列化的调用如下所示:
String jsonString=response.readEntityString.class;
ObjectMapper ObjectMapper=新的ObjectMapper;
ObjectReader readerFor=objectMapper.readerForContainer.class;
MappingIterator MappingIterator=readerFor.readValuesjsonString;
而mappingIterator.hasNext{
容器容器=容器映射迭代器.next;
containers.addcontainer;
}
但我只接收设置为null的空对象属性,因为我将@JsonIgnorePropertiesignoreUnknown=true,因此跳过了对属性的解析
这可能吗?或者我应该在事后实现类似于后处理的功能吗?这个怎么样。创建一个类ContainerActive,如下所示
public class ContainerActive {
private boolean active;
// constructors, setters, getters
}
你可以这么做
Map<String, ContainerActive> map = mapper.readValue(jsonString, new TypeReference<Map<String, ContainerActive>>() {});
使用此选项,您将Container1、Container2作为键,ContainerActive对象作为具有活动字段的值 这个怎么样。创建一个类ContainerActive,如下所示
public class ContainerActive {
private boolean active;
// constructors, setters, getters
}
你可以这么做
Map<String, ContainerActive> map = mapper.readValue(jsonString, new TypeReference<Map<String, ContainerActive>>() {});
使用此选项,您将Container1、Container2作为键,ContainerActive对象作为具有活动字段的值 这只是一个快速的解决方案,如果对象是这样的,那么它的所有对象都是一个容器对象,您可以在其中接收JSON,您可以在下面的代码中使用JSONObject
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestSO {
public static void main(String[] args) throws JsonParseException, JsonMappingException, JSONException, IOException {
String jsonString = "{\r\n" +
" \"Container1\": {\r\n" +
" \"active\": true\r\n" +
" },\r\n" +
" \"Container2\": {\r\n" +
" \"active\": false\r\n" +
" },\r\n" +
"}";
JSONObject jsonObject = new JSONObject(jsonString);
ObjectMapper mapper = new ObjectMapper();
for (String key : jsonObject.keySet()) {
Container container = mapper.readValue(jsonObject.get(key).toString(), Container.class);
System.out.println(container);
}
}
static class Container{
private String name;
private Boolean active;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
@Override
public String toString() {
return "Container [name=" + name + ", active=" + active + "]";
}
}
}
这只是一个快速的解决方案,如果对象是这样的,那么它的所有对象都是一个容器对象,您可以在其中接收JSON,并且可以在下面的代码中使用JSONObject
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestSO {
public static void main(String[] args) throws JsonParseException, JsonMappingException, JSONException, IOException {
String jsonString = "{\r\n" +
" \"Container1\": {\r\n" +
" \"active\": true\r\n" +
" },\r\n" +
" \"Container2\": {\r\n" +
" \"active\": false\r\n" +
" },\r\n" +
"}";
JSONObject jsonObject = new JSONObject(jsonString);
ObjectMapper mapper = new ObjectMapper();
for (String key : jsonObject.keySet()) {
Container container = mapper.readValue(jsonObject.get(key).toString(), Container.class);
System.out.println(container);
}
}
static class Container{
private String name;
private Boolean active;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
@Override
public String toString() {
return "Container [name=" + name + ", active=" + active + "]";
}
}
}
Jackson–更改字段名称-@ErnstZ是否可能得到更多容器作为响应,例如Container3等?或者后缀是有限的?是的,更多的容器是可能的,它们可以有任何名称。pattern ContainerX只是一个例子。@Dulaj:我不是这个意思。我的问题是我事先不知道字段名。它可能是任何字符串。@ErnstZ Great and ImpressJackson–更改字段名称-@ErnstZ是否可能得到更多容器作为响应,例如Container3等?或者后缀是有限的?是的,更多的容器是可能的,它们可以有任何名称。pattern ContainerX只是一个例子。@Dulaj:我不是这个意思。我的问题是我事先不知道字段名。它可以是任何字符串。@ErnstZ Great和印象派喜欢使用JSONObject,因为字段名和内容在逻辑上是一致的。但您的解决方案不会自动将字段名反序列化为对象的属性。解组容器实例后,需要调用Container.setNamekey。此外,还需要一个依赖项:org.json,但这对我来说没关系。感谢您的贡献。我接受这一贡献作为解决方案,因为它最符合我的期望,因为只有一个添加项需要实现才能获得期望的结果:java container.setNamekey我喜欢使用JSONObject,因为您将字段名和内容逻辑地结合在一起。但您的解决方案不会自动将字段名反序列化为对象的属性。解组容器实例后,需要调用Container.setNamekey。此外,还需要一个依赖项:org.json,但这对我来说没关系。感谢您的贡献。我接受此贡献作为解决方案,因为它最符合我的期望,因为只有一个添加项需要实现才能获得所需的结果:java container.setNamekey是的,这也是将字段名称映射到特定对象的另一种选择。缺点是名称属性
之后必须设置,类似于@Hades.Yes提供的解决方案。你必须这么做。因为您的json实际上并不符合standardYes,所以这也是将字段名映射到特定对象的替代方法。缺点是name属性必须在之后设置,类似于@Hades.Yes提供的解决方案。你必须这么做。因为你的json并不符合标准