Ason


Source link: https://github.com/afollestad/ason

Ason

This library intends to make JSON very easy to interact with in Java; it also makes (de)serialization painless.

It wraps around the well-known org.json classes ( JSONObject, JSONArray, etc.) which also happen to be included in the Android SDK. As we all know, those stock classes tend to be a pain. They feel bulky, and make you try/catch way too many Exceptions.


Table of Contents

  1. Dependency
    1. Gradle (Java)
    2. Gradle (Android)
    3. Gradle (Kotlin)
    4. Maven
  2. Parsing and Building Objects
  3. Retrieving Values from Objects
  4. Parsing and Building Arrays
  5. Pretty Print
  6. Paths
    1. Dot Notation
    2. Index Notation
    3. Escaping Periods and Dollar Signs
  7. Serialization
    1. Serializing Objects
    2. Serializing Arrays
    3. Serializing Lists
    4. Automatic Serialization
  8. Deserialization
    1. Deserializing Objects
    2. Deserializing Arrays
    3. Deserializing Lists
    4. Automatic Deserialization
  9. Annotations
    1. @AsonName
    2. @AsonIgnore
  10. Retrofit

Dependency

The dependency is available via jCenter.

Gradle (Java)

dependencies {

  ...
  compile 'com.afollestad:ason:[latest-version]' 
}

Gradle (Android)

Since Android includes org.json classes, you'll want to exclude the copies provided by this library:

dependencies {

  ...
  compile('com.afollestad:ason:[latest-version]') {

exclude group: 'org.json', module: 'json'
  
}
 
}

Gradle (Kotlin)

In Kotlin, you'll want to exclude IntelliJ's annotations library to avoid a DexException. If you are using Kotlin with Android, make sure you also exclude org.json as shown in the section above.

dependencies {

  ...
  compile('com.afollestad:ason:[latest-version]') {

exclude group: 'com.intellij', module: 'annotations'
  
}
 
}

Maven

<dependency>
<groupId>com.afollestad</groupId>
<artifactId>ason</artifactId>
<version>[latest-version]</version>
<type>pom</type> </dependency>

Parsing and Building Objects

There are various ways that this library allows you to construct JSON objects...

Parsing strings is the first, just use the constructor which accepts a String:

String input = // ... Ason ason = new Ason(input);

Second, you can build objects using Java fields:

// Translates to {
"id":1,"name":"Aidan","born":1995
}
 Ason ason = new Ason() {

  int id = 1;
  String name = "Aidan";
  int born = 1995; 
}
;

Third, you can add values with the put() method:

Ason ason = new Ason()
  .put("_id", 1)
  .put("name", "Aidan")
  .put("born", 1995);

You can quickly put in arrays just by passing multiple values to put():

// Translates to {
"greetings":["Hello","World"]
}
 Ason ason = new Ason();
 // The first parameter is a key, you can pass any type for the rest of the varargs parameters ason.put("greetings", "Hello", "World");

Retrieving Values from Objects

Various methods exist for retrieving existing values (default values are returned if they don't exist). The one parameter version uses whatever the usual default of a type is (0 for number types, null for everything else), if the no value is found for the key. The two parameter version lets you specify a custom default.

Ason ason = // ...  String str = ason.getString("name");
 String strWithDefault = ason.getString("name", null);
  Character chr = ason.getChar("name");
 Character chrWithDefault = ason.getChar("name", null);
  boolean bool = ason.getBool("name");
 boolean boolWithDefault = ason.getBool("name", true);
  short shrt = ason.getShort("name");
 short shrtWithDefault = ason.getShort("name", (short)0);
  int integer = ason.getInt("name");
 int integerWithDefault = ason.getInt("name", 0);
  long lng = ason.getLong("name");
 long lngWithDefault = ason.getLong("name", 0L);
  float flt = ason.getFloat("name");
 float fltWithDefault = ason.getFloat("name", 0f);
  double doub = ason.getDouble("name");
 double doubWithDefault = ason.getDouble("name", 0d);
  byte byt = ason.getByte("name");
 byte bytWithDefault = ason.getByte("name", 0d);
  Ason obj = ason.getAsonObject("name");
 AsonArray ary = ason.getAsonArray("name");

Further, the get(String) method will actually automatically cast its return value to whatever variable you're setting it to:

String str = ason.get("name");
 long lng = ason.get("name");

It will also infer its type if you pass a default value, removing the need to use explicit get[Type] methods:

if (ason.get("name", false)) {

  // do something 
}

You can check if values exist, are null, equal another value, or even remove them by key:

Ason ason = // ...  boolean exists = ason.has("name");
 boolean isNull = ason.isNull("name");
 boolean valueEqual = ason.equal("key-name", value);
 ason.remove("name");

Parsing and Building Arrays

Like objects, you can parse arrays from Strings:

String input = // ... AsonArray<Ason> array = new AsonArray<Ason>(input);

You can add new objects with .add():

AsonArray<String> array = new AsonArray<String>();
 // You can add multiple items with a single .put() call, you could use multiple if necessary too array.add("Hello", "World!");

You can retrieve and remove objects by index:

AsonArray<Ason> array = // ...  Ason firstItem = array.get(0);
 array.remove(0);

Some other utility methods exist, also:

AsonArray<String> array = // ...  int size = array.size();
 boolean empty = array.isEmpty();
 boolean itemEqual = array.equal(0, "Does index 0 equal this value?")

Pretty Print

Objects and arrays can both be converted to strings simply with the toString() method:

Ason ason = // ...  String value = ason.toString();
 // all on one line, no formatting String formatted = ason.toString(4);
 // 4 spaces being the indent size

Paths

Paths use periods and dollar signs to let you quickly add, retrieve, or remove items which are deeper down in your JSON hierarchy without manually traversing.

Dot Notation

Lets create an object using a few dot notation keys:

Ason ason = new Ason()
  .put("id", 1)
  .put("name", "Aidan")
  .put("birthday.month", "July")
  .put("birthday.day", 28)
  .put("birthday.year", 1995);

The above would construct this:

{

  "id": 1,
  "name": "Aidan",
  "birthday": {

"month": "July",

"day": 28,

"year": 1995
  
}
 
}

As you can see, a child object is automatically created for you. We only use two levels, but you could create many more just by using more periods to separate child names.


You can retrieve values from objects using dot notation:

Ason ason = // ...  String name = ason.get("name");
 String month = ason.get("birthday.month");
 int day = ason.get("birthday.day");
 int year = ason.get("birthday.year");

If you wanted to remove the inner "year" value:

Ason ason = // ... ason.remove("birthday.year");

You can use dot notation with arrays too, but you need to specify the index of the object to pull from:

AsonArray ason = // ... String name = ason.get(1, "birthday.month");

As a bonus, you can check equality without doing a manual value comparison:

Ason ason = // ... boolean birthYearCheck = ason.equal("birthday.year", 1995);
  AsonArray ason2 = // ... boolean birthYearCheck2 = ason2.equal(2, "birthday.year", 1995);

Index Notation

To extend on dot notations in paths, you can use this notation to perform operations on array children.

Take this JSON:

{

  "group_id": 1,
  "title": "Hello, world!",
  "participants": [

{

 "name": "Aidan",

 "id": 2

}
,

{

 "name": "Nina",

 "id": 1

}

  ] 
}

You could create this using index notation as such:

Ason ason = new Ason()
  .put("group_id", 1)
  .put("title", "Hello, world!")
  .put("participants.$0.name", "Aidan")
  .put("participants.$0.id", 2)
  .put("participants.$1.name", "Nina")
  .put("participants.$1.id", 1);

The dollar sign followed by the number 0 indicates that you want the item at index 0 (position 1) within an array called "participants".


You can retrieve the value of "name" in the second participant like this:

Ason object = // ... String name = object.get("participants.$1.name");

If you wanted to remove the first item from the inner array, you can do that with index notation. This avoids the need to first retrieve the "participants" object:

Ason object = // ... object.remove("participants.$0");

Escaping Periods and Dollar Signs

If your keys have literal periods in them, you can escape the periods so that they aren't used when following a path.

Take this JSON:

{

  "files": {

"test.txt": "Hello, world!"
  
}
 
}

You can retrieve the value if the inner test.txt string like this:

Ason ason = // ... String value = ason.get("files.test\\.txt");

We use two forward slashes since Java requires that you escape slashes. The literal string is just "files.test.txt".


You can also escape dollar signs which are normally used with index notation.

Take this JSON:

{

  "participants": {

"$1": {

 "name": "Nina"

}

  
}
 
}

To retrieve the inner string called "name":

Ason ason = // ... String value = ason.get("participants.\\$1.name");

We use an escaped forward slash (\) in front of the dollar sign to indicate that the dollar sign is literal, and actually used in the name of a key.


Serialization

This library allows very easy serialization and deserialization. Serialization is converting a Java class instance to JSON.

Take this class for the coming set of examples:

public class Person {

public int id;
  public String name;
  public Person spouse;

 public Person(int id, String name) {

this.id = id;

this.name = name;
  
}
 
}

Serializing Objects

We can serialize an instance as follows:

Person aidan = new Person(1, "Aidan");
 aidan.spouse = new Person(2, "Nina");
  Ason ason = Ason.serialize(aidan);

The resulting Ason object is:

{

  "id": 1,
  "name": "Aidan",
  "spouse": {

"id": 2,

"name": "Nina"
  
}
 
}

Serializing Arrays

Serializing arrays is very similar to serializing objects, it uses the serializeArray method:

Person[] people = // ... AsonArray<Person> array = Ason.serializeArray(people);

Don't forget, you can serialize primitive arrays:

int[] ids = new int[] {
 1, 2, 3, 4 
}
; AsonArray<Integer> array = Ason.serializeArray(ids);

Serializing Lists

Serializing lists uses the serializeList method:

List<Person> people2 = // ... AsonArray<Person> array2 = AsonArray.serializeList(people2);

Automatic Serialization

If you already have a Ason instance, you can add Java class instances into the object and serialize them automatically:

Ason ason = new Ason();
 Person person1 = new Person(1, "Aidan");
 Person person2 = new Person(2, "Nina");
  ason.put("person1", person);
 ason.put("person2", person2);

This would result in:

{

  "person1": {

"id": 1,

"name": "Aidan"
  
}
,
  "person2": {

"id": 2,

"name": "Nina"
  
}
 
}

This automatic serialization works with AsonArray's too:

AsonArray<Person> array = new AsonArray<Person>();
 Person person1 = new Person(1, "Aidan");
 Person person2 = new Person(2, "Nina");
  array.add(person1, person2);

This would result in:

[
  {

"id": 1,

"name": "Aidan"
  
}
,
  {

"id": 2,

"name": "Nina"
  
}
 ]

Deserialization

This library allows very easy serialization and deserialization. Deserialization is converting JSON to a Java class instance.

Again, take this class for the coming set of examples:

public class Person {

public int id;
  public String name;
  public Person spouse;

 public Person(int id, String name) {

this.id = id;

this.name = name;
  
}
 
}

Deserializing Objects

We can deserialize an object as follows:

String input = "{
\"id\":1,\"name\":\"Aidan\",\"spouse\":{
\"id\":2,\"name\":\"Nina\"
}

}
"; Ason ason = new Ason(input);
  Person person = ason.deserialize(Person.class);

There is also a static method which has the same effect:

String input = "{
\"id\":1,\"name\":\"Aidan\",\"spouse\":{
\"id\":2,\"name\":\"Nina\"
}

}
"; Ason ason = new Ason(input);
  Person person = Ason.deserialize(ason, Person.class);

Lastly, you can directly deserialize JSON strings:

String input = "{
\"id\":1,\"name\":\"Aidan\",\"spouse\":{
\"id\":2,\"name\":\"Nina\"
}

}
"; Person person = Ason.deserialize(input, Person.class);

Deserializing Arrays

You can deserialize JSON arrays to Java lists and arrays too:

String input = "[{
\"name\":\"Aidan\",\"_id\":1
}
,{
\"name\":\"Nina\",\"_id\":2
}
]"; AsonArray<Person> array = new AsonArray<>(input);
  Person[] peopleArray = array.deserialize(Person[].class);

There is also static methods which have the same effect:

String input = "[{
\"name\":\"Aidan\",\"_id\":1
}
,{
\"name\":\"Nina\",\"_id\":2
}
]"; AsonArray<Person> array = new AsonArray<>(input);
  Person[] peopleArray = Ason.deserialize(array, Person[].class);

Lastly, you can directly deserialize JSON strings:

String input = "[{
\"name\":\"Aidan\",\"_id\":1
}
,{
\"name\":\"Nina\",\"_id\":2
}
]"; Person[] peopleArray = Ason.deserialize(input, Person[].class);

One more thing, you can deserialize arrays containing primitive types:

String input = "[1,2,3,4]"; int[] primitiveArray = Ason.deserialize(input, int[].class);

Deserializing Lists

Unlike objects and arrays, deserializing lists requires a separate method:

String input = "[{
\"name\":\"Aidan\",\"_id\":1
}
,{
\"name\":\"Nina\",\"_id\":2
}
]"; AsonArray<Person> array = new AsonArray<>(input);
  List<Person> peopleList = array.deserializeList(Person.class);

There is also a static method which has the same effect:

String input = "[{
\"name\":\"Aidan\",\"_id\":1
}
,{
\"name\":\"Nina\",\"_id\":2
}
]"; AsonArray<Person> array = new AsonArray<>(input);
  List<Person> peopleList = Ason.deserializeList(array, Person.class);

You can deserialize strings directly:

String input = "[{
\"name\":\"Aidan\",\"_id\":1
}
,{
\"name\":\"Nina\",\"_id\":2
}
]"; List<Person> peopleList = Ason.deserializeList(input, Person.class);

Automatic Deserialization

If you already have a Ason instance, you can automatically pull out and deserialize Java class instances without using the AsonSerializer directly:

Ason ason = // ... // The JSON object needs to contain a child object with the key "person" representing the Person class. Person person = ason.get("person", Person.class);

The same works for AsonArray's:

AsonArray<Person> array = // ... // The JSON array needs to contain a list of objects representing the Person class. Person person = array.get(0, Person.class);

For Lists, you need to use a separate method since it requires that you specific the type held by the list:

Ason ason = // ... // The JSON object needs to contain a child array with the key "people" representing an array of Person classes. List<Person> people = array.getList("people", Person.class);
 

Annotations

This library comes with a two annotations that have their own special use cases.

@AsonName

This annotation allows you to assign a custom name to fields.

It's used with Ason field construction:

Ason ason = new Ason() {

  @AsonName(name = "_id") int id = 1;
  String name = "Aidan";
  int born = 1995; 
}
;

And of course during serialization and deserialization:

public class Person {

 @AsonName(name = "_id") int id;
  String name;
  int born;

 public Person(int id, String name, int born) {

this.id = id;

this.name = name;

this.born = born;
  
}
 
}

@AsonIgnore

This annotation tells the library to ignore and fields it's used to mark. That means the field is not serialized, deserialized, or used with field construction:

public class Person {

 @AsonIgnore String invisibleField = "Hello, world!";
  int id;
  String name;
  int born;

 public Person(int id, String name, int born) {

this.id = id;

this.name = name;

this.born = born;
  
}
 
}

Retrofit

Ason's built in Retrofit converters let you send and receive objects with Retrofit, they are automatically serialized or deserialized. Just add the converter factory to your Retrofit instances:

Retrofit retrofit =
new Retrofit.Builder()

 ...

 .addConverterFactory(new AsonConverterFactory())

 .build();

AsonConverterFactory exists in a separate dependency:

dependencies {

  ...
  compile 'com.afollestad:ason-retrofit:[latest-version]' 
}

Resources

A RecyclerView with support of addHeaderView and addFooterView features.

Demo app for Deep dive into Android Data Binding talk.

Don't write a RecyclerView adapter again. Not even a ViewHolder!

  • Based on Android Data Binding
  • Written in Kotlin
  • No need to write the adapter
  • No need to write the viewholders
  • No need to modify your model classes
  • No need to notify the adapter when data set changed
  • Supports multiple view types
  • Manage item click/long-click in layout or builder
  • Optional OnBindListener's
  • Very fast -- no reflection
  • Super easy API
  • Tiny size: 31 KB
  • Minimum Android SDK: 9

Helper class to configure cache behaviour of OkHttp client, also works with Retrofit for Android.

A simple Firebase chat application for Android.

Pop animation with circular dust effect for any view update.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes