问题
- I am trying to parse the
json
array with same key value which looks something like:
Back End Response:"Countries":[{"state":"Queens Land "state":"Tasmania"}].
2.I have created classes to read back end response and mapping the values with faster XML
, but only the last value in the array is getting copied, instead of entire array. This is how I created my Data Transfer Object
classes.
Now the Test object contains Countries
array, but only one of the State
value is read. i.e
"Countries":["States":"Tasmania"].
Please excuse me for typos. can some one help, can some one suggest whats wrong with the bellow code..
private Class Test{
List<Countries> countries;
}
private class Countries{
private String States;
}
private class Mapper {
}
In my Mapper class reading the value using faster XML
回答1:
Assume that your JSON
payload is:
{
"Countries": [
{
"state": "Queens Land",
"state": "Tasmania"
}
]
}
According to RFC7159:
An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string. A single colon comes after each name, separating the name from the value. A single comma separates a value from a following name. The names within an object SHOULD be unique.
In your example, you have not unique names and most JSON
parsers would skip repeated values and would take only one. So, if you can change backend response, just change it to:
{
"Countries": [
{
"state": "Queens Land"
},
{
"state": "Tasmania"
}
]
}
or
{
"Countries": [
"Queens Land",
"Tasmania"
]
}
But if you can not do that, you need to use Streaming API and implement your custom deserialiser. See below example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
Test test = mapper.readValue(jsonFile, Test.class);
System.out.println(test);
}
}
class CountriesJsonDeserializer extends JsonDeserializer<Countries> {
@Override
public Countries deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
List<String> states = new ArrayList<>();
while (p.nextToken() != JsonToken.END_OBJECT) {
if (p.currentToken() == JsonToken.FIELD_NAME) {
if ("state".equalsIgnoreCase(p.getText())) {
p.nextToken();
states.add(p.getText());
}
}
}
Countries countries = new Countries();
countries.setStates(states);
return countries;
}
}
class Test {
@JsonProperty("Countries")
private List<Countries> countries;
public List<Countries> getCountries() {
return countries;
}
public void setCountries(List<Countries> countries) {
this.countries = countries;
}
@Override
public String toString() {
return "Test{" +
"countries=" + countries +
'}';
}
}
@JsonDeserialize(using = CountriesJsonDeserializer.class)
class Countries {
private List<String> states;
public List<String> getStates() {
return states;
}
public void setStates(List<String> states) {
this.states = states;
}
@Override
public String toString() {
return "Countries{" +
"states=" + states +
'}';
}
}
Above example prints:
Test{countries=[Countries{states=[Queens Land, Tasmania]}]}
See also:
- Intro to the Jackson ObjectMapper
来源:https://stackoverflow.com/questions/58151124/how-to-iterate-through-an-json-array-with-same-keys-but-different-values-using