Reputation: 65
I don't have idea how to read file with lots of JSON
-s in Android. I don't even know how many elements are in JSON
. This is a part of JSON
:
{
"distance" : 0.0,
"lat" : 52.297819,
"lon" : 20.937653,
"realTime" : 1553448972482,
"speed" : "NaN",
"time" : 0.0
}{
"pulse" : 77,
"rr" : [ 788 ],
"time" : 1553448976957
}{
"distance" : 0.0,
"lat" : 52.297819,
"lon" : 20.937653,
"realTime" : 1553448977481,
"speed" : "NaN",
"time" : 0.0
}
I created two model DTO
classes:
public class GpsDTO{
double lat;
double lon;
double speed;
double distance;
double time;
long realTime;
}
public class HeartDTO{
long time;
int pulse;
int[] rr;
}
and I tried use library GSON
but it does not work.
Gson gson = new GsonBuilder().setLenient().create();
try {
GpsDTO gpsDTO = gson.fromJson(new FileReader(path),GpsDTO.class);
} catch (Exception e) {
e.printStackTrace();
}
Upvotes: 1
Views: 103
Reputation: 38655
Presented JSON
payload is not valid. Gson
does not read invalid JSON
payloads by default. We need to implement custom deserialiser for it. JSON
structure in this case is list of JSON object
-es. We can use JsonReader
and stream API
. The fastest way is to read it once but much easier it to read it twice:
i - JSON objects
using given i - adapter
To match adapter below implementation uses all properties in JSON
object (findAdapters
method). In case it is not the best algorithm in your case, implement other which fits requirements:
class MultiJsonReader {
// constant list of properties for each class
private final List<String> HEART_PROPS = Arrays.asList("pulse", "rr", "time");
private final List<String> GPS_PROPS = Arrays.asList("lat", "lon", "distance", "speed", "realTime", "time");
private final Gson gson;
public MultiJsonReader(Gson gson) {
this.gson = gson;
}
public List<Object> readAll(File jsonFile) throws IOException {
List<TypeAdapter<?>> adapters;
// read first time for finding types and adapters
try (JsonReader jsonReader = gson.newJsonReader(new FileReader(jsonFile))) {
jsonReader.setLenient(true);
adapters = findAdapters(gson, jsonReader);
}
List<Object> objects = new ArrayList<>();
// read second time for deserialising
try (JsonReader jsonReader = gson.newJsonReader(new FileReader(jsonFile))) {
jsonReader.setLenient(true);
for (TypeAdapter<?> adapter : adapters) {
objects.add(adapter.read(jsonReader));
}
}
return objects;
}
private List<TypeAdapter<?>> findAdapters(Gson gson, JsonReader jsonReader) throws IOException {
List<TypeAdapter<?>> adapters = new ArrayList<>();
while (jsonReader.peek() != JsonToken.END_DOCUMENT) {
List<String> names = new ArrayList<>();
jsonReader.beginObject();
while (jsonReader.peek() != JsonToken.END_OBJECT) {
names.add(jsonReader.nextName());
jsonReader.skipValue();
}
jsonReader.endObject();
Class<?> clazz = getClassForProperties(names);
adapters.add(gson.getAdapter(clazz));
}
return adapters;
}
private Class<?> getClassForProperties(List<String> properties) {
if (HEART_PROPS.containsAll(properties)) {
return HeartDTO.class;
}
if (GPS_PROPS.containsAll(properties)) {
return GpsDTO.class;
}
throw new IllegalArgumentException("Properties are not known " + properties);
}
}
Example usage:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder().create();
MultiJsonReader reader = new MultiJsonReader(gson);
List<Object> objects = reader.readAll(jsonFile);
objects.forEach(System.out::println);
}
}
For your JSON
payload prints:
GpsDTO{lat=52.297819, lon=20.937653, speed=NaN, distance=0.0, time=0.0, realTime=1553448972482}
HeartDTO{time=1553448976957, pulse=77, rr=[788]}
GpsDTO{lat=52.297819, lon=20.937653, speed=NaN, distance=0.0, time=0.0, realTime=1553448977481}
Upvotes: 1