我需要将java对象转换为Map<String, String>
以获取我正在编写的REST api包装器。任何复杂对象的字段都需要序列化为json。我想出了如何做到这一点:
public static Map<String, String> toContentMap(Object object) throws JsonProcessingException {
Map<String, Object> objectParamMap = MAPPER.convertValue(object, new TypeReference<Map<String, Object>>() {});
Map<String, String> contentMap = new HashMap<>();
for (Entry<String, Object> entry : objectParamMap.entrySet()) {
String key = entry.getKey();
String value = MAPPER.writeValueAsString(entry.getValue());
contentMap.put(key, StringUtils.strip(value, "\""));
}
return contentMap;
}
现在我需要一种方法从这个Map<String, String>
表示回到pojo对象。这可能主要使用jackson apis吗?
编辑:
我想我不清楚。我知道我要来往的POJO。但它应该是通用的,适用于任何基本的POJO。
一个例子:
class MyObject {
String fieldA;
Long fieldB;
MyOtherObject fieldC;
List<String> fieldD;
}
class MyOtherObject {
String fieldA;
String fieldB;
}
MyObject object = new MyObject("valueA", 20L,
new MyOtherObject("valueA", "valueB"),
Lists.newArrayList("array1", "array2"));
Map<String, String> contentMap = toContentMap(object);
/*
"fieldA" -> "valueA"
"fieldB" -> "20"
"fieldC" -> "{\"fieldA\":\"valueA\",\"fieldB\":\"valueB\"}"
"fieldD" -> "[\"array1\",\"array2\"]"
*/
MyObject newObject = fromContentMap(contentMap);
assertEquals(object, newObject)
答案 0 :(得分:1)
您可以使用
ObjectMapper mapper = new ObjectMapper();
String jsonInString = "{'name' : 'rahul'}";
//JSON from String to Object
User user = mapper.readValue(jsonInString, User.class);
或
User user = mapper.convertValue(map, User.class);
如果要从json / map转换为自定义对象。您还可以将类型信息传递给序列化/反序列化过程,以便jackson知道内部。请详细了解here。
答案 1 :(得分:1)
根据您的评论
它应该适用于我要求的任何POJO
我认为您正在寻找@JsonAnyGetter
和@JsonAnySetter
注释,它会将它可以分配给POJO的值(您需要在反序列化时指定...它可以&#39;是通用的),但会将未解析的任何内容粘贴到Map<String, Object>
。
请注意,它不能是Map<String, String>
,因为JSON不仅包含字符串作为其值。
例如,采用JSON
{
"uid": 1,
"username": "steve",
"email": "steve@example.com"
}
你可以generate a Jackson POJO看起来像这样。
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"uid",
"username",
"email"
})
public class User {
@JsonProperty("uid")
private Integer uid;
@JsonProperty("username")
private String username;
@JsonProperty("email")
private String email;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("uid")
public Integer getUid() {
return uid;
}
@JsonProperty("uid")
public void setUid(Integer uid) {
this.uid = uid;
}
@JsonProperty("username")
public String getUsername() {
return username;
}
@JsonProperty("username")
public void setUsername(String username) {
this.username = username;
}
@JsonProperty("email")
public String getEmail() {
return email;
}
@JsonProperty("email")
public void setEmail(String email) {
this.email = email;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
答案 2 :(得分:0)
我害怕,我们无法做到。当object
被序列化为JSON String
时,它会丢失它的类类型。因此,在将字符串反序列化为对象时,解析器不知道要将对象反序列化的类。但是,有几种方法可以做到:
在另一张地图中存储类型信息:
像这样创建一个新的map
:
Map<String, Class> metaData = new HashMap<>();
它将类型名称与Class一起存储。因此,在派生时,我们可以从此地图中查找类类型并将其传递给readValue
方法。
使用@Type
的{{1}}注释:(仅当所有对象都扩展相同的基类时才有用)
Jakson有一个名为ObjectMapper
的功能,如果所有类都继承了公共基类,它将有助于反序列化为对象。请查看文档here。