![](/img/trans.png)
[英]Deserialize JSON with ObjectId function to Map<String, Object>
[英]Proper way to Deserialize JSon String int List<Map<String, Object>>
我得到的返回結果可能如下所示:
{"rows":[{"ProfileID":"SLappE","CR_ProfileID":"BC1A"},{"ProfileID":"SCRA","CR_ProfileID":"BC15"},{"ProfileID":"SMOKE","CR_ProfileID":"BC15"},{"ProfileID":"Smokey","CR_ProfileID":"BC1F"},{"ProfileID":"WF-LN-OCR","CR_ProfileID":"BC1F"}]}
或像這樣:
{"rows":[{"PARAM":"product_reference_nr","FIELDNAME":"account_nr","EXAMPLE-FIELD":"CHK","EXAMPLE-TABLE":"CHK_DOC","ID":"CHK-ACCT"},{"PARAM":"party_pd_nr","FIELDNAME":"front_image_object_id","EXAMPLE-FIELD":"CHK","EXAMPLE-TABLE":"BACK_CHK_DOC","ID":"CHK-BACK"},{"PARAM":"endDate","FIELDNAME":"document_dt","EXAMPLE-FIELD":"HR","EXAMPLE-TABLE":"SPLAPSTIC_DOC","ID":"HR-DT"},{"PARAM":"startDate","FIELDNAME":"document_dt","EXAMPLE-FIELD":"HR","EXAMPLE-TABLE":"SPLAPSTIC_DOC","ID":"HR-DT-STARTDT"},{"PARAM":"formCode","FIELDNAME":"form_category_cd","EXAMPLE-FIELD":"HR","EXAMPLE-TABLE":"SPLAPSTIC_DOC","ID":"HR-FORM”}]}
因此,我正在調用rest服務,返回結果將始終以行開頭:然后是看起來像Dictionary或Map / HaspMap值的數組。 該詞典的大小將有所不同。 但是在該行列表中,它似乎是鍵值對。
現在,我嘗試將json反序列化為以下數據結構:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlRootElement
public class EResponse {
@JsonProperty("rows")
private final List<Row> rows = new ArrayList<>();
public List<Row> getRows() {
List<Row> retResult = rows;
return retResult;
}
}
和
import com.fasterxml.jackson.annotation.*;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Hashtable;
import java.util.Map;
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlRootElement
public class Row {
private Map<String,Object> column;
@JsonProperty
public Map<String, Object> getColumn(){
return column;
}
}
我這樣調用上面的代碼:
result = mapper.readValue(response.readEntity(String.class), new TypeReference<EResponse>(){});
我已經嘗試了上面的各種配置,但似乎沒有拋出無法識別的字段異常就無法使其返回。 這是有道理的,因為Key值中的第一個元素被視為映射器無法映射的字段,因為它沒有在我要映射到的對象中的任何位置定義。
將此List>映射到對象的適當方法是什么? 有沒有一種簡單的方法可以將值也轉換為適當的類型? 我使用的是jackson-databind,但如果有解決方案,可以說服他使用GSON。
好吧,顯然這是行不通的,因為傑克遜無法將鍵/值對映射到給定的映射。 如果要讓傑克遜進行映射,請在JSON中將屬性定義為DTO中的類字段。 但這似乎違反直覺,因為在給定的兩個不同有效負載中您具有不同的屬性,它們的結構也不同。 因此,這就是您應該做的。 讓我們將每個對象表示為JSON鍵/值對與數組中對象的偏移值的映射。 這樣也可以解決您的有效負載的動態特性。 代碼看起來像這樣。
final String jsonArray = new String(Files.readAllBytes(Paths.get("./src/main/resources/payload.json")));
final TypeReference<Map<String, String>> typeRef = new TypeReference<Map<String, String>>() {
};
Iterator<Map<String, String>> it = new ObjectMapper().readerFor(typeRef)
.readValues(JsonPath.parse(jsonArray).read("rows").toString());
final AtomicInteger counter = new AtomicInteger();
Map<Integer, Map<String, String>> mapByObject = new HashMap<>();
it.forEachRemaining(keyValueMap -> {
mapByObject.putIfAbsent(counter.incrementAndGet(), keyValueMap);
});
System.out.println(mapByObject);
輸出如下:
{1={ProfileID=SLappE, CR_ProfileID=BC1A}, 2={ProfileID=SCRA, CR_ProfileID=BC15}, 3={ProfileID=SMOKE, CR_ProfileID=BC15}, 4={ProfileID=Smokey, CR_ProfileID=BC1F}, 5={ProfileID=WF-LN-OCR, CR_ProfileID=BC1F}}
對於每個對象,將針對該特定對象在數組中的相對偏移量打印鍵/值映射。 如果需要,您可以嘗試使用Gson
,但這是足夠簡單的IMO。
本質上,我指望傑克遜圖書館變得聰明。 我需要遍歷返回的Json的“樹結構”。 將其映射到我的個人Response對象。 有點像這樣:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(response.readEntity(String.class));
JsonNode rowsNode = rootNode.path("rows");
Iterator<JsonNode> elements = rowsNode.elements();
while (elements.hasNext()){
JsonNode columnNodes = elements.next();
System.out.println("All the Column Values: " + columnNodes.asText());
Map<String, Object> values = new HashMap<String, Object>();
values = mapper.treeToValue(columnNodes, HashMap.class);
ERow row = new ERow();
row.setColumn(values);
columns.add(row);
}
result.setRows(columns);
不用擔心,我將其包裝在try catch塊中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.