There is a standard Java API for managing JSON, described at Java API for JSON Processing: An Introduction to JSON . Unfortunately, there doesn't appear to be any tool to convert a JSON schema to this particular API. So we won't use it.
There is a JSON Schema to POJO (Plain Old Java) at jsonschema2pojo Paste in the schema, choose the package name and class name, set the source to JSON Schema aand the target to Java, and for convenience, turn on "Generate builder methods". To be able to print the resuoltant Java classes, it may be convenient to also turn on the "toString" option. (Note: the tool doesn't like tabs in the schema file, replace any with spaces). It should look like the figure:
One option concerns Annotations. There is a a specific set of annotations convenient for JSON from Jackson. Annotations in general are discussed in Java Annotations, while the Jackson annotations are discussed in Serialization. The annotations concern the strings that are used in serializing to JSON the Java objects. Without annotations the class name is used, but this can be altered by annotations. If you like that kind of stuff, you can use it. I'm happy enough with plain old Java.
Applying this to the JSON example schema given earlier results in three
classes: Email.java
, Name.java
and
Person.java
in directory person
.
Each class has methods to get/set fileds, but also has "builder"
methods withXYZ()
for each field. This allows a
Name
object to be created for example, by
Name name = new Name()
.withPersonal("Jan")
.withFamily("Newmarch");
The generated classes are compatable with the Jackson JSON API.
The primary class ObjectMapper
is described at
Jackson ObjectMapper
. This has methods to create Java objects from JSON strings given by
strings, file contents, readers and streams.
It can also write a Java object as a JSON string as a byte array, a string or to a
stream.
Jar files for this API are hosted on the Maven site JSON Libraries. The relevant libraries are com.fasterxml.jackson.core , com.fasterxml.jackson.databind and com.fasterxml.jackson.core At the time of writing, the latest version of each is 2.11.0. From each page, select the latest version and download the corresponding jar file.
If you have turned on the option of generating a toString()
method, you will also need the Apache jar file
org-apache-commons-lang.jar
The JSON client creates a Person
Java object from the schema-generated
files, and sends the JSON string as UTF-8 bytes on an output stream.
It also prints to stdout the string JSON form for checking on the client side.
It is
PersonClientJSON.java:
import person.*;
import java.util.List;
import java.util.Vector;
import java.io.*;
import java.net.*;
import com.fasterxml.jackson.databind.ObjectMapper;
public class PersonClientJSON {
public static final int SERVER_PORT = 2002;
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: Client address");
System.exit(1);
}
Name name = new Name()
.withPersonal("Jan")
.withFamily("Newmarch");
Email email1 = new Email()
.withKind("private")
.withAddress("jan@newmarch.name");
Email email2 = new Email()
.withKind("work")
.withAddress("j.newmarch@boxhill.edu.au");
List<Email> allEmails = new Vector<Email>();
allEmails.add(email1);
allEmails.add(email2);
Person person = new Person()
.withName(name)
.withEmail(allEmails);
InetAddress address = null;
try {
address = InetAddress.getByName(args[0]);
} catch(UnknownHostException e) {
e.printStackTrace();
System.exit(2);
}
Socket sock = null;
try {
sock = new Socket(address, SERVER_PORT);
System.out.println("Connected");
} catch(IOException e) {
e.printStackTrace();
System.exit(3);
}
OutputStream out = null;
try {
out = sock.getOutputStream();
} catch(IOException e) {
e.printStackTrace();
System.exit(5);
}
try {
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(person);
System.out.println("JSON is " + str);
mapper.writeValue(out, person);
} catch(Exception e) {
System.err.println(e);
}
}
}
To build the client,
javac -cp jackson-databind-2.11.0.jar:jackson-core-2.11.0.jar:jackson-annotations-2.11.0.jar:org-apache-commons-lang.jar:org-apache-commons-lang.jar person/*java PersonClientJSON.java
and to run it,
java -cp .:jackson-databind-2.11.0.jar:jackson-core-2.11.0.jar:jackson-annotations-2.11.0.jar:org-apache-commons-lang.jar PersonClientJSON localhost
The JSON server listens for a client connection, and then asks the
ObjectMapper
to readValue()
from the socket's
input stream. It then prints the resultant Person
to stdout.
Using the Apache string builder, it will look something like
Person is person.Person@35bbe5e8[name=person.Name@2c8d66b2[personal=Jan,family=Newmarch],email=[person.Email@5a39699c[kind=private,address=jan@newmarch.name], person.Email@3cb5cdba[kind=work,address=j.newmarch@boxhill.edu.au]]]
(with obvious changes in the addresses when you run it).
The server is PersonServer.java:
import person.*;
import java.util.Arrays;
import java.io.*;
import java.net.*;
import com.fasterxml.jackson.databind.ObjectMapper;
public class PersonServer {
public static final int SERVER_PORT = 2002;
public static void main(String[] args){
ServerSocket s = null;
try {
s = new ServerSocket(SERVER_PORT);
} catch(IOException e) {
System.out.println(e);
System.exit(1);
}
while (true) {
Socket incoming = null;
try {
incoming = s.accept();
System.out.println("Connected");
} catch(IOException e) {
System.out.println(e);
continue;
}
handleSocket(incoming);
}
}
public static void handleSocket(Socket incoming) {
InputStream in;
try {
in = incoming.getInputStream();
} catch(IOException e) {
System.err.println(e.toString());
return;
}
try {
ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue(in, Person.class);
System.out.println("Person is " + person.toString());
} catch(Exception e) {
System.err.println(e);
}
}
}
To compile the server,
javac -cp jackson-databind-2.11.0.jar:jackson-core-2.11.0.jar:jackson-annotations-2.11.0.jar:org-apache-commons-lang.jar person/*java PersonServer.java
and to run it,
java -cp .:jackson-databind-2.11.0.jar:jackson-core-2.11.0.jar:jackson-annotations-2.11.0.jar:org-apache-commons-lang.jar PersonServer
Copyright © Jan Newmarch, jan@newmarch.name
" Network Programming using Java, Go, Python, Rust, JavaScript and Julia"
by
Jan Newmarch
is licensed under a
Creative Commons Attribution-ShareAlike 4.0 International License
.
Based on a work at
https://jan.newmarch.name/NetworkProgramming/
.