Easiest Way to Parse JSON Response

Easiest way to parse JSON response

Follow these steps:

  1. Convert your JSON to C# using json2csharp.com;
  2. Create a class file and put the above generated code in there;
  3. Add the Newtonsoft.Json library to your project using the Nuget Package Manager;
  4. 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:

  1. Default Gson - use Gson class.
  2. Gson Adapter - use JsonReader from Gson library.
  3. Default Jackson - use ObjectMapper from Jackson.
  4. 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: Sample Image

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



Leave a reply



Submit