Easiest way to parse JSON response
Follow these steps:
- Convert your JSON to C# using json2csharp.com;
- Create a class file and put the above generated code in there;
- Add the
Newtonsoft.Json
library to your project using the Nuget Package Manager; Convert the JSON received from your service using this code:
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
(Feel free to rename RootObject
to something more meaningful to you. The other classes should remain unchanged.)
What's the best way to parse a JSON response from the requests library?
You can use json.loads
:
import json
import requests
response = requests.get(...)
json_data = json.loads(response.text)
This converts a given string into a dictionary which allows you to access your JSON data easily within your code.
Or you can use @Martijn's helpful suggestion, and the higher voted answer, response.json()
.
Flutter - The best way to parse a JSON
Compare this with things like quicktype: (1) If you do not have a model class, then try to use things like quicktype to get that class from a sample json string. (2) However, I suggest not to use the toJson
and fromJson
given by quicktype. The reason is that, when your model changes (say add a field / change a field), you must also change your toJson/fromJson accordingly (which is time-consuming and error-prone). Otherwise you get a bug.
If you already have your model class and only need the toJson
and fromJson
methods: Then the very famous json_serializable package suits you. It will happily generate the toJson
and fromJson
.
For example, say you have
class Person {
final String firstName;
final String lastName;
final DateTime dateOfBirth;
}
Then with a bit of boilerplate code, it will auto give you
Person _$PersonFromJson(Map<String, dynamic> json) {
return Person(
firstName: json['firstName'] as String,
lastName: json['lastName'] as String,
dateOfBirth: DateTime.parse(json['dateOfBirth'] as String),
);
}
Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
'firstName': instance.firstName,
'lastName': instance.lastName,
'dateOfBirth': instance.dateOfBirth.toIso8601String(),
};
Actually that package is more powerful than that. Check out the link for more details.
Fastest way to parse JSON from String when format is known
If you know a JSON
payload structure you can use Streaming API
to read data. I created 4 different methods to read given JSON
payload:
- Default Gson - use
Gson
class. - Gson Adapter - use
JsonReader
from Gson library. - Default Jackson - use
ObjectMapper
from Jackson. - Jackson streaming API - use
JsonParser
class.
To make it comparable all these methods take JSON
payload as String
and return Pojo
object which represents A
and B
properties. Below graph represents differences:
As you can notice, Jackson
's Streaming API
is the fastest way to deserialise your JSON
payload from these 4 approaches.
To generate above graph, below data were used:
1113 547 540 546 544 552 547 549 547 548 avg 603.3
940 455 452 456 465 459 457 458 455 455 avg 505.2
422 266 257 262 260 267 259 262 257 259 avg 277.1
202 186 184 189 185 188 182 186 187 183 avg 187.2
Benchmark code:
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public class JsonApp {
private static final String json = "{\"A\" : 1.0 ,\"B\" : \"X\"}";
private static final int MAX = 1_000_000;
private static List<List<Duration>> values = new ArrayList<>();
static {
IntStream.range(0, 4).forEach(i -> values.add(new ArrayList<>()));
}
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
int v = 0;
values.get(v++).add(defaultGson());
values.get(v++).add(gsonAdapter());
values.get(v++).add(defaultJackson());
values.get(v).add(jacksonJsonFactory());
}
values.forEach(list -> {
list.forEach(d -> System.out.print(d.toMillis() + " "));
System.out.println(" avg " + list.stream()
.mapToLong(Duration::toMillis)
.average().getAsDouble());
});
}
static Duration defaultGson() {
Gson gson = new Gson();
long start = System.nanoTime();
for (int i = MAX; i > 0; i--) {
gson.fromJson(json, Pojo.class);
}
return Duration.ofNanos(System.nanoTime() - start);
}
static Duration gsonAdapter() throws IOException {
PojoTypeAdapter adapter = new PojoTypeAdapter();
long start = System.nanoTime();
for (int i = MAX; i > 0; i--) {
adapter.fromJson(json);
}
return Duration.ofNanos(System.nanoTime() - start);
}
static Duration defaultJackson() throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
long start = System.nanoTime();
for (int i = MAX; i > 0; i--) {
mapper.readValue(json, Pojo.class);
}
return Duration.ofNanos(System.nanoTime() - start);
}
static Duration jacksonJsonFactory() throws IOException {
JsonFactory jfactory = new JsonFactory();
long start = System.nanoTime();
for (int i = MAX; i > 0; i--) {
readPartially(jfactory);
}
return Duration.ofNanos(System.nanoTime() - start);
}
static Pojo readPartially(JsonFactory jfactory) throws IOException {
try (JsonParser parser = jfactory.createParser(json)) {
Pojo pojo = new Pojo();
parser.nextToken(); // skip START_OBJECT - {
parser.nextToken(); // skip A name
parser.nextToken();
pojo.A = parser.getDoubleValue();
parser.nextToken(); // skip B name
parser.nextToken();
pojo.B = parser.getValueAsString();
return pojo;
}
}
}
class PojoTypeAdapter extends TypeAdapter<Pojo> {
@Override
public void write(JsonWriter out, Pojo value) {
throw new IllegalStateException("Implement me!");
}
@Override
public Pojo read(JsonReader in) throws IOException {
if (in.peek() == com.google.gson.stream.JsonToken.NULL) {
in.nextNull();
return null;
}
Pojo pojo = new Pojo();
in.beginObject();
in.nextName();
pojo.A = in.nextDouble();
in.nextName();
pojo.B = in.nextString();
return pojo;
}
}
class Pojo {
double A;
String B;
@Override
public String toString() {
return "Pojo{" +
"A=" + A +
", B='" + B + '\'' +
'}';
}
}
Note: if you need really precise data try to create benchmark tests using excellent JMH package.
Fastest way to parse JSON
Your problem isn't parsing the JSON. You can't speed that up. Using a different library (probably) isn't going to make that faster either. (I'm talking about load times, not development time).
It comes down to how you make the request as well as your internet speed.
For example, this is not how you use an AsyncTask.
resualt = task.execute("MY_JSON_FILE_URL").get();
Because you just made an asynchronous call into a synchronous one. In other words, the get()
method will block and wait for a result, therefore taking time and cause the data to load slowly.
Now, sure, libraries reduce the complexity of AsyncTask and make development "faster and easier", but the quick answer here is to actually use onPostExecute
of the AsyncTask class to load the data asynchronously, off the main thread.
The best example I can give is Using a callback to return the data
Update
private JSONArray array;
private void parseJSON(JSONArray array) {
this.array = array;
// TODO: something
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
LoadJson asyncTask = (LoadJson) new LoadJson (new LoadJson.AsyncResponse(){
@Override
public void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
try {
JSONObject jsonObject = new JSONObject(output);
JSONArray jsonArray = jsonObject.getJSONArray("marcadores");
for (int i = 0; i < jsonArray.length; i++) {
// TODO: Parse the array, fill an arraylist
}
// TODO: Set / notify an adapter
// Or....
parseJSON(jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
}
}).execute();
How to Parse this JSON Response in JAVA
public static void main(String[] args) throws JSONException {
String jsonString = "{" +
" \"MyResponse\": {" +
" \"count\": 3," +
" \"listTsm\": [{" +
" \"id\": \"b90c6218-73c8-30bd-b532-5ccf435da766\"," +
" \"simpleid\": 1," +
" \"name\": \"vignesh1\"" +
" }," +
" {" +
" \"id\": \"b90c6218-73c8-30bd-b532-5ccf435da766\"," +
" \"simpleid\": 2," +
" \"name\": \"vignesh2\"" +
" }," +
" {" +
" \"id\": \"b90c6218-73c8-30bd-b532-5ccf435da766\"," +
" \"simpleid\": 3," +
" \"name\": \"vignesh3\"" +
" }]" +
" }" +
"}";
JSONObject jsonObject = new JSONObject(jsonString);
JSONObject myResponse = jsonObject.getJSONObject("MyResponse");
JSONArray tsmresponse = (JSONArray) myResponse.get("listTsm");
ArrayList<String> list = new ArrayList<String>();
for(int i=0; i<tsmresponse.length(); i++){
list.add(tsmresponse.getJSONObject(i).getString("name"));
}
System.out.println(list);
}
}
Output:
[vignesh1, vignesh2, vignesh3]
Comment: I didn't add validation
[EDIT]
other way to load json String
JSONObject obj= new JSONObject();
JSONObject jsonObject = obj.fromObject(jsonString);
....
Related Topics
C# - Faster Alternatives to Setpixel and Getpixel for Bitmaps for Windows Forms App
When to Use Ref and When It Is Not Necessary in C#
How to Parse Huge JSON File as Stream in JSON.Net
Call Asynchronous Method in Constructor
How to Delete All Files and Folders in a Directory
Lifetime of ASP.NET Static Variable
How to Protect My .Net Assemblies from Decompilation
How to Check for Nulls in an '==' Operator Overload Without Infinite Recursion
How to Tell a Lambda Function to Capture a Copy Instead of a Reference in C#
How to Get the Full Path of Running Process
Creating a Copy of an Object in C#
Get Name of Property as a String