Reputation: 57
I know there is a lot of content on this throughout the web but I couldn't find one that will help me solve this (been looking for about two days now...).
I have a json string which looks like this:
[
{
"firstName": "dan",
"lastName": "cohen",
"email": "[email protected]",
"userName": "aaaddd",
"password": "1cczzdddds",
"agentCode": 0
},
{
"firstName": "omer",
"lastName": "sha",
"email": "[email protected]",
"userName": "asdf",
"password": "asdf",
"agentCode": 1
}
]
I am trying to read this json into Set<T>
since I am going to use this function in order to read json files to set of other types. E.g, here I am trying to read into Set<Agent>
while later on I'll try to read another file into Set<Passenger>
.
This is the function which reads the json file:
public Set<T> read() {
try {
return new ObjectMapper().readValue(new File(this.fileName), new TypeReference<Set<Agent>>(){});
}
/* Errors handling */
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
The line Set<T> sample = new ObjectMapper().readValue(jsonString, new TypeReference<Set<Agent>>(){});
is responsible for deserialize the json string into a Set<Agent>
.
But the moment I try to change it from:
Set<T> sample = new ObjectMapper().readValue(jsonString, new TypeReference<Set<Agent>>(){});
To:
Set<T> sample = new ObjectMapper().readValue(jsonString, new TypeReference<Set<T>>(){});
When trying to execute this code (which lies in the main function):
Set<Agent> agents = fileManagerAgent.read();
Iterator<Agent> it = agents.iterator();
while(it.hasNext()){
System.out.println(it.next().getUserName());
}
I am getting an error saying:
Exception in thread "main" java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class model.objects.Agent (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; model.objects.Agent is in unnamed module of loader 'app')
From what I have read, this happens because in run-time, something happens to T
and the compiler addresses it as Object
and so, it is deserializing the json into a LinkedHashMap.
Once it does that, I cannot access the Agent object inside the set.
This is what calls the function to read from a json file into Set<T>
(which is also in the main function):
FileManager<Agent> fileManagerAgent = new FileManager<>("src/data/agents.json");
Set<Agent> agents = fileManagerAgent.read();
Also, this code is written using Jackson
.
Any ideas on how to solve this?
If any more information is needed please inform me and I will update the question.
Upvotes: 2
Views: 3044
Reputation: 1914
Add the Class you want as parameter. In this example the passed Class has to be Agent.class
for a FileManager<Agent>
.
public Set<T> read(Class<T> clazz) {
try {
ObjectMapper = mapper = new ObjectMapper();
return mapper.readValue(new File(fileName), mapper.getTypeFactory().constructCollectionType(Set.class, clazz));
} catch (IOException e) {
// Exception handling
}
}
And then use it like this:
Set<Agent> agents = new FileManager<>("agent.json").read(Agent.class);
or pass the class when you create youre file manager
public class FileManager<T> {
private String fileName;
private Class<T> clazz;
public Set<T> read() {
// Same code.
}
}
Now the code would change to:
Set<Agent> agents = new FileManager<>("agent.json", Agent.class).read();
Upvotes: 3
Reputation: 67
Create VO class which is equivalent to your input file, pass this class to ObjectMapper.
new ObjectMapper().readValue(new File(this.fileName), Object of JsonSetVo);
public class JsonSetVo<T> {
Set<T> inputSet;
public Set<T> getInputSet() {
return inputSet;
}
public void setInputSet(Set<T> inputSet) {
this.inputSet = inputSet;
}
}
Upvotes: -1