JSON:
{
"246": {
"test1": "one"
},
"355": {
"test2": "two"
}
}
Java POJO
class POJO{
private HashMap<String, SubPojo> subMap;
@JsonAnySetter
public void addToMap(String key, SubPojo val){ subMap.put(key, value); }
}
class SubPojo{
private HashMap<String, String> map;
@JsonAnySetter
public void addToMap(String key, String val) { map.put(key, value);}
}
In my code I do: (using Jackson )
POJO testing = (new ObjectMapper()).convertValue("path/to/json", POJO.class);
I get an exception saying:
"Unrecognized field `246`..."
Where am I going wrong?
Something like this:
public class Pojo {
private Map<String,Object> map = new HashMap<>();
@JsonAnySetter
public void addToMap(String key, Object value) {
this.map.put(key, value);
}
@JsonAnyGetter
public Map<String,Object> getMap() {
return map;
}
}
There is an article on Baeldung which covers various Jackson annotations, including this one, and some basics on the Jackson wiki .
converValue
method is used to convert objects. See JavaDoc
:
Convenience method for doing two-step conversion from given value, into instance of given value type, if (but only if!) conversion is needed. If given value is already of requested type, value is returned as is. This method is functionally similar to first serializing given value into JSON, and then binding JSON data into value of given type, but should be more efficient since full serialization does not (need to) occur. However, same converters (serializers, deserializers) will be used as for data binding, meaning same object mapper configuration works.
For example, you can "convert" File
to String
like this:
mapper.convertValue(jsonFile, String.class)
Where jsonFile
is an instance of File
class. Example result could be: path/to/json
.
To deserialise JSON
payload use one from readValue
method family.
You can create your POJO
with constructor annotated JsonCreator
:
class Pojo {
private final Map<String, SubPojo> map;
@JsonCreator
public Pojo(Map<String, SubPojo> map) {
this.map = map;
}
public Map<String, SubPojo> getMap() {
return map;
}
@Override
public String toString() {
return "Pojo{" +
"map=" + map +
'}';
}
}
class SubPojo {
private Map<String, String> map;
@JsonCreator
public SubPojo(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "SubPojo{" +
"map=" + map +
'}';
}
}
And simple usage. To read JSON
from file use readValue
method:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
Pojo map = mapper.readValue(jsonFile, Pojo.class);
System.out.println(map);
}
}
Above code prints:
Pojo{map={246=SubPojo{map={test1=one}}, 355=SubPojo{map={test2=two}}}}
If you would like to stay with your data model use JsonAnySetter
annotation. Your data model could look like this:
class Pojo {
private Map<String, SubPojo> subMap = new HashMap<>();
@JsonAnySetter
public void addToMap(String key, SubPojo value) {
subMap.put(key, value);
}
@Override
public String toString() {
return "POJO{" +
"subMap=" + subMap +
'}';
}
}
class SubPojo {
private Map<String, String> map = new HashMap<>();
@JsonAnySetter
public void addToMap(String key, String value) {
map.put(key, value);
}
@Override
public String toString() {
return "SubPojo{" +
"map=" + map +
'}';
}
}
Above usage example prints:
POJO{subMap={355=SubPojo{map={test2=two}}, 246=SubPojo{map={test1=one}}}}
You don't need to create any POJO classes to parse that JSON text, since it can be parsed into a Map<String, Map<String, String>>
.
You will have to use a TypeReference
to prevent loss of the generic type arguments.
Map<String, Map<String, String>> data = new ObjectMapper()
.readValue(new File("test.json"),
new TypeReference<Map<String, Map<String, String>>>() {});
Printing that data
map, using the JSON text in the question, will show:
{246={test1=one}, 355={test2=two}}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.