JSON Schema for the enterprise
This document specifies the JSONx Integration for JAX-RS, which offers facilities for reading and writing JSON documents from a JAX-RS runtime via the JSONx Runtime API.
1 Introduction
1.1 Conventions Used in This Document
2 Purpose
3 Requirements
4 Getting Started
5 Specification
5.1 JxObjectProvider
5.2 BadRequestExceptionMapper
6 Usage
7 Contributing
8 Special Thanks
9 License
This document sets out the structural part of the JSONx Integration for JAX-RS. It also contains a directory of links to related resources.
The JSONx Integration for JAX-RS is implemented to the specification of the JAX-RS API. JSONx Integration for JAX-RS implements the MessageBodyReader
and MessageBodyWriter
interfaces in JxObjectProvider
to integrate with JAX-RS server runtimes.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.
Provide JSONx Integration for JAX-RS for parsing and marshaling Java object instances of binding classes in a JAX-RS runtime.
-
The JSONx Integration for JAX-RS MUST support validation of JSON upon the consumption and production of documents in a JAX-RS runtime.
-
The JSONx Integration for JAX-RS MUST support any JAX-RS application that implements the facets relevant to parsing and marshaling of entity object, as defined in the JAX-RS 2.0 Specification.
-
The JSONx Integration for JAX-RS MUST be automatic and free of any configuration that would couple an application to the JSONx Framework for Java.
The JSONx Integration for JAX-RS sub-project provides a Provider
implementing the MessageBodyReader
and MessageBodyWriter
interfaces that can be registered with a JAX-RS runtime.
The following illustrates example usage.
1. Create account.jsd
or account.jsdx
in src/main/resources/
.
{
"jx:ns": "http://www.jsonx.org/schema-0.4.jsd",
"jx:schemaLocation": "http://www.jsonx.org/schema-0.4.jsd http://www.jsonx.org/schema-0.4.jsd",
"id": { "jx:type": "string", "pattern": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" },
"email": { "jx:type": "string", "pattern": "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}" },
"sha256": {"jx:type": "string", "pattern": "[0-9a-f]{64}" },
"ids": { "jx:type": "array", "elements": [{ "jx:type": "reference", "type": "id" }] },
"credentials": { "jx:type": "object", "properties": {
"email": { "jx:type": "reference", "type": "email", "nullable": false },
"password": { "jx:type": "reference", "type": "sha256", "use": "optional", "nullable": false }}
},
"account": { "jx:type": "object", "extends": "credentials", "properties": {
"id": { "jx:type": "reference", "type": "id", "use": "optional", "nullable": false },
"firstName": { "jx:type": "string", "nullable": false },
"lastName": { "jx:type": "string", "nullable": false }}
},
"accounts": { "jx:type": "array", "elements": [{ "jx:type": "reference", "type": "account" }]}
}
<schema
xmlns="http://www.jsonx.org/schema-0.4.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jsonx.org/schema-0.4.xsd http://www.jsonx.org/schema.xsd">
<string name="id" pattern="[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"/>
<string name="email" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}"/>
<string name="sha256" pattern="[0-9a-f]{64}"/>
<array name="ids">
<reference type="id"/>
</array>
<object name="credentials">
<property name="email" xsi:type="reference" type="email" nullable="false"/>
<property name="password" xsi:type="reference" type="sha256" use="optional" nullable="false"/>
</object>
<object name="account" extends="credentials">
<property name="id" xsi:type="reference" type="id" nullable="false" use="optional"/>
<property name="firstName" xsi:type="string" nullable="false"/>
<property name="lastName" xsi:type="string" nullable="false"/>
</object>
<array name="accounts">
<reference type="account"/>
</array>
</schema>
Note: You can use the [Converter][#converter] utility to automatically convert between JSD and JSDx.
2. Add the [org.jsonx:jsonx-maven-plugin
][jsonx-maven-plugin] to the POM.
<plugin>
<groupId>org.jsonx</groupId>
<artifactId>jsonx-maven-plugin</artifactId>
<version>0.4.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<destDir>${project.build.directory}/generated-sources/jsonx</destDir>
<namespacePackages>
<namespacePackage package="com.example.jsonx."/>
</namespacePackages>
<schemas>
<schema>src/main/resources/account.jsonx</schema>
</schemas>
</configuration>
</execution>
</executions>
</plugin>
3. Upon successful execution of the [jsonx-maven-plugin
][jsonx-maven-plugin] plugin, Java class files will be generated in generated-sources/jsonx
. Add this path to your Build Paths in your IDE to integrate into your project.
The generated classes can be instantiated as any other Java objects. They are strongly typed, and will guide you in proper construction of a JSON message. The following APIs can be used for parsing and marshalling JSONx to and from JSON:
To parse JSON to JSONx Bindings:
String json = "{\"email\":\"john@doe\",\"password\":\"066b91577bc547e21aa329c74d74b0e53e29534d4cc0ad455abba050121a9557\"}";
Credentials credentials = JxDecoder.parseObject(Credentials.class, json);
To marshal JSONx Bindings to JSON:
String json2 = JxEncoder.get().marshal(credentials);
assertEquals(json, json2);
4. Next, register the JxObjectProvider
provider in the JAX-RS appilcation singletons, and implement the AccountService
:
public class MyApplication extends javax.ws.rs.core.Application {
@Override
public Set<Object> getSingletons() {
return Collections.singleton(new JxObjectProvider(JxEncoder._2));
}
}
@Path("account")
@RolesAllowed("registered")
public class AccountService {
@GET
@Produces("application/vnd.example.v1+json")
public Account get(@Context SecurityContext securityContext) {
Account account = new Account();
...
return account;
}
@POST
@Consumes("application/vnd.example.v1+json")
public void post(@Context SecurityContext securityContext, Account account) {
...
}
}
A JAX-RS Provider
that implements MessageBodyReader
and MessageBodyWriter
support for reading and writing JSON documents with the JSONx API.
A JAX-RS Provider
that implements an ExceptionMapper
to present a JSON error body in case of a BadRequestException
.
The JAX-RS API requires Provider
s to be declared as either "singleton" instances, or by providing their class names for per-requests instantiations. The following example illustrates how to specify the JxObjectProvider
and BadRequestExceptionMapper
as singleton instances.
@ApplicationPath("/")
public class MyApplication extends javax.ws.rs.core.Application {
@Override
public Set<Object> getSingletons() {
Set<Object> singletons = new HashSet<>();
singletons.add(new JxObjectProvider(JxEncoder._2));
singletons.add(new BadRequestExceptionMapper());
return singletons;
}
@Override
public Set<Class<?>> getClasses() {
return null;
}
}
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
Special thanks to EJ Technologies for providing their award winning Java Profiler (JProfiler) for development of the JSONx Framework.
This project is licensed under the MIT License - see the LICENSE.txt file for details.