mmm-marshall
Problem
When you want to do (un)marshalling with Java EE standards the current state is:
As a result you implement your marshalling and unmarshalling code for a single format. If you want to support a different format, you have to start from scratch. Further, the reference implementation for JSON-P is lacking obvious features. E.g. the indentation is hardcoded as you can see here. You can also not configure to include or omit null
values. Also, there is no build in support to skip a value and doing so requires an awful lot of code (in case the value might contain nested arrays and/or objects).
Solution
So instead we define a universal API for (un)marshalling. You can write your mapping code once and then you can benefit from all formats supported by this project or even add custom formats as plugin yourself.
Features
-
Simple but powerful API to marshall and unmarshall your data in a format agnostic way.
-
Works in JVM as well as in the browser using TeaVM or as cloud-native binary using GraalVM.
-
You can even use mmm-bean to get the entire marshalling and unmarshalling for free with many other cool features.
-
You can furhter use mmm-rpc to implement client and/or server for RCP communication with minimum code but maximum benefits (support for different formats, sync/async/reactive support, etc.).
We provide the following implementations:
-
mmm-marshall-json (native implementation for JSON with flexibilty)
-
mmm-marhsall-jsonp (implementation for JSON based on JSON-P)
-
mmm-marshall-stax (implementation for XML based on StAX)
-
mmm-marshall-tvm-xml (implementation for XML using TeaVM and XML API of the browser)
-
mmm-marshall-protobuf (implementation for ProtoBuf/gRPC)
-
mmm-marshall-yaml (implementation for YAML with flexibility)
-
link:impl/snakeyaml/README.adoc[mmm-marshall-snakeyaml (implementation for YAML based on SnakeYaml)
Usage
Maven Dependency:
<dependency>
<groupId>io.github.m-m-m</groupId>
<artifactId>mmm-marshall</artifactId>
<!-- <version>${mmmVersion}</version> -->
</dependency>
Gradle Dependency:
implementation 'io.github.m-m-m:mmm-marshall:${mmmVersion}'
For ${mmmVersion}
please fill in the latest version that you can find in the badge above.
Module Dependency:
requires transitive io.github.mmm.marshall;
Example
To get started we use a very simple example based on a stupid POJO that every vanilla Java developer will immediately understand. Please note that we provide much better beans with build-in marshalling support via mmm-bean. However, here comes our stupid example:
public class Person {
private String name;
private int age;
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public int getAge() { return this.age; }
public void setAge(int age) { this.age = age; }
}
Now, we can marshall a Person
like this:
public void marshall(StructuredWriter writer, Person person) {
writer.writeStartObject();
writer.writeName("name", 1);
writer.writeValue(person.getName());
writer.writeName("age", 2);
writer.writeValue(person.getAge());
writer.writeEnd();
}
Now we run the following code:
Person person = new Person();
person.setName("John Doe");
person.satAge(42);
StringBuilder sb = new StringBuilder();
StructuredWriter writer = JsonFormat.of().writer(sb);
marshall(writer, person);
System.out.println(sb.toString());
This will print the following output:
{
"name": "John Doe",
"age": 42
}
The interesting fact is that you can exchange JsonFormat.of()
with something else to get a different format without changing your implementation of marshal
. So you can also use XmlFormat.of()
to produce XML or you can generate YAML or even gRPC/ProtoBuf.
To unmarhall a Person
you can do something like this:
public void unmarshall(StructuredReader reader, Person person) {
while (!reader.readEnd()) {
if (reader.isName("name", 1)) {
person.setName(reader.readValueAsString());
} else if (reader.isName("age", 2)) {
person.setAge(reader.readValueAsInteger());
} else {
// ignore unknown property for compatibility
// we have dynamic properties support in mmm-bean
// even much better than gRPC generated unknownFields
}
}
}