Moshi is a JSON serialization and deserialization library that can be used in Java and Kotlin, which is mainly written in Kotlin. This article demonstrates the use of this library in Java in the form of sample code.
The sample project is managed using Maven, and the following lists the versions of JDK, Maven and Moshi used when writing this article:
JDK:Amazon Corretto 17.0.8 Maven:3.9.2 Moshi:1.18.30
Before starting, you need toof
<dependencies>
Moshi dependencies are introduced below (moshi
as the core module,moshi-adapters
Modules contain suchDate
Practical Adapters for type processing):
<!-- --> <dependency> <groupId></groupId> <artifactId>moshi</artifactId> <version>1.18.30</version> </dependency> <dependency> <groupId></groupId> <artifactId>moshi-adapters</artifactId> <version>1.18.30</version> </dependency>
To save the cumbersome writingSetters
andGetters
, This sample project also uses Lombok, which depends on the following:
<!-- --> <dependency> <groupId></groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <scope>provided</scope> </dependency>
In addition, we demonstrate the use of Moshi by writing JUnit unit tests, so we need to introducejunit-jupiter
rely:
<!-- --> <dependency> <groupId></groupId> <artifactId>junit-jupiter</artifactId> <version>5.10.0</version> <scope>test</scope> </dependency>
Once you are ready, you are ready to use.
1 Basic use
First, let’s take a look at the most basic usage, that is, how to use Moshi for serialization and deserialization (i.e. convert Java objects to JSON, and convert JSON to Java objects).
Create a new Model class first, this articleUser
For example, this class has three fields:name
、roles
andcreatedAt
, includingString
、List
、Date
and enum types.
// src/main/java/com/example/demo/model/ package ; import ; import ; import ; import ; import ; import ; @ToString @Getter @Setter @NoArgsConstructor public class User { private String name; private List<Role> roles; private Date createdAt; public enum Role { ADMIN, EDITOR, VIEWER } }
The following is a test case to demonstrate the mutual conversion between User objects and JSON:
// src/test/java/com/example/demo/MoshiTest#testBasicUsage @Test public void testBasicUsage() { // Construct Moshi instance Moshi moshi = new () .add(, new Rfc3339DateJsonAdapter()) .build(); // Get the User's JsonAdapter JsonAdapter<User> jsonAdapter = (); // Construct User object User user = new User(); ("Larry"); ((, )); (new Date()); // Serialization String json = (user); (json); // Deserialization try { User userParsed = (json); (userParsed); } catch (IOException e) { (); } }
It should be noted that the above code specifies when constructing the Moshi instanceDate
JSON Adapter corresponding to the typeRfc3339DateJsonAdapter
, otherwise an error will be reported when parsing the field of this type.
The above code runs as follows:
{"createdAt":"2023-10-14T09:47:37.763Z","name":"Larry","roles":["ADMIN","EDITOR"]}
User(name=Larry, roles=[ADMIN, EDITOR], createdAt=Sat Oct 14 17:47:37 CST 2023)
It can be seen that the user object serialized into JSON and the user object deserialized into JSON are correct.
2 Use @Json to customize the field name
In the above example, the field name in JSON is exactly the same as the attribute name in the Java class.
What should I do if a field name needs to be customized? Here is a demonstration:
// src/main/java/com/example/demo/model/ package ; @ToString @Getter @Setter @NoArgsConstructor public class User { // ... @Json(name = "created_at") private Date createdAt; // ... }
You can see that you just need to add the corresponding properties of the Java class@Json
Annotate and customize its name.
Run the above test case again (src/test/java/com/example/demo/MoshiTest#testBasicUsage
), and the following results were obtained:
{"created_at":"2023-10-14T09:55:48.793Z","name":"Larry","roles":["ADMIN","EDITOR"]}
User(name=Larry, roles=[ADMIN, EDITOR], createdAt=Sat Oct 14 17:55:48 CST 2023)
You can see that the User classcreatedAt
Attribute becomescreated_at
;When the JSON is deserialized to a User object again,createdAt
It is also normal to assign attributes.
3 Custom Adapter
In the previous example, weDate
The type specifies the Adapter that comes with MoshiRfc3339DateJsonAdapter
to support its parsing. If you think the date format after the Adapter parsed is not what you want, is there a way to specify it yourself? Of course, it is OK. Moshi supports us to use custom Adapters for a certain type to implement its serialization and deserialization logic.
The following is the enumeration type in the User classRole
Write a custom Adapter to implement its custom parsing:
// src/main/java/com/example/demo/adapter/ package ; import ; import ; import ; public class RoleAdapter { @ToJson public String toJson( role) { return ().substring(0, 1); } @FromJson public fromJson(String role) { switch ((0)) { case 'A': return ; case 'E': return ; case 'V': return ; } return null; } }
You can see that weRole
Type to write a custom AdapterRoleAdapter
. There are two methods in this classtoJson
andfromJson
, and have been annotated separately@ToJson
and@FromJson
These two methods are used respectivelyRole
Logic when converting a type from a Java property to a JSON field and from a JSON field to a Java property (this example only takes the first letter to represent what the User ownsRole
)。
Here is a test case to demonstrate the use of this custom Adapter:
// src/test/java/com/example/demo/MoshiTest#testCustomTypeAdapter @Test public void testCustomTypeAdapter() { // Construct Moshi instance Moshi moshi = new () .add(, new Rfc3339DateJsonAdapter()) .add(new RoleAdapter()) .build(); // Get the User's JsonAdapter JsonAdapter<User> jsonAdapter = (); // Construct User object User user = new User(); ("Larry"); ((, )); (new Date()); // Serialization String json = (user); (json); // Deserialization try { User userParsed = (json); (userParsed); } catch (IOException e) { (); } }
As you can see, just add the Adapter when constructing the Moshi instance.
Run the test case and the results are as follows:
{"created_at":"2023-10-14T10:39:04.174Z","name":"Larry","roles":["A","E"]}
User(name=Larry, roles=[ADMIN, EDITOR], createdAt=Sat Oct 14 18:39:04 CST 2023)
You can see that the User object is serialized into JSON,roles
The value of the field uses our custom logic (only the first letter to represent the Role of the User); the User object deserialized to the JSON again also uses our custom logic, and the deserialization result is also correct.
4 How to deal with JSON arrays?
The above demonstrates all the conversions between Java objects and JSON objects. How does Java List convert with JSON arrays?
The following test cases are demonstrated:
// src/test/java/com/example/demo/MoshiTest#testJSONArrayParsing @Test public void testJSONArrayParsing() { // Create a new type Type type = (, ); // Construct Moshi instance Moshi moshi = new () .add(, new Rfc3339DateJsonAdapter()) .add(new RoleAdapter()) .build(); // Get the User's JsonAdapter JsonAdapter<List<User>> jsonAdapter = (type); // Construct User object User user = new User(); ("Larry"); (new Date()); ((, )); // Serialization String json = ((user)); (json); // Deserialization try { List<User> usersParsed = (json); (usersParsed); } catch (IOException e) { (); } }
As you can see, just create a new Moshi Type, which is just as easy to use.
The above test case runs as follows:
[{"created_at":"2023-10-14T11:22:27.153Z","name":"Larry","roles":["A","E"]}]
[User(name=Larry, roles=[ADMIN, EDITOR], createdAt=Sat Oct 14 19:22:27 CST 2023)]
As you can see, the results of the conversion between User List and JSON Array are correct.
In summary, this article explores various common uses of using Moshi for JSON serialization and deserialization in Java.
This is the end of this article about using the Moshi JSON library method in Java. For more related contents of using the Moshi JSON library in Java, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!