{title:'OpenAPI Serializers', updated:'8.2.0,9.0.0'}

The {@link oaj.oapi.OpenApiSerializer} class is used to convert POJOs to HTTP parts.

The class hierarchy for the builder of this serializer is:

Refer to the builder javadocs for configurable settings.

Later we'll describe how to use HTTP-Part annotations to define OpenAPI schemas for serialization and parsing of HTTP parts. The following example is a preview showing an HTTP body defined as pipe-delimited list of comma-delimited numbers (e.g. "1,2,3|4,5,6|7,8,9"):

| @RestPost("/2dLongArray") | public void post2dLongArray( | @Content( | schema=@Schema( | type="array", | collectionFormat="pipes", | items=@Items( | type="array", | collectionFormat="csv", | items=@SubItems( | type="integer", | format="int64", | minimum="0", | maximum="100" | minLength=1, | maxLength=10 | ) | ) | minLength=1, | maxLength=10 | ) | ) | Long[][] body | ) {...} | | // Alternate shortened format. | @RestPost("/2dLongArray") | public void post2dLongArray( | @Content( | schema=@Schema( | t="array", | cf="pipes", | i=@Items( | t="array", | cf="csv", | i=@SubItems( | t="integer", | f="int64", | min="0", | max="100" | minl=1, | maxl=10 | ) | ) | minl=1, | maxl=10 | ) | ) | Long[][] body | ) {...}

Under-the-covers, this gets converted to the following schema object:

| HttpPartSchema schema = HttpPartSchema.create() | .items( | HttpPartSchema.create() | .type("array") | .collectionFormat("pipes") | .items( | HttpPartSchema.create() | .type("array") | .collectionFormat("csv") | .items( | HttpPartSchema.create() | .type("integer") | .format("int64") | .minimum(0) | .maximum(100) | .minLength(1) | .maxLength(10) | ) | ) | ) | .build();

Various convenience methods exist for shortening this code.

| import static org.apache.juneau.http.HttpPartSchema.*; | | HttpPartSchema schema = tArrayPipes( | tArrayCsv( | tInt64().minimum(0).maximum(100).minLength(1).maxLength(10) | ) | ).build();

The following code shows how the schema above can be used to create our pipe+csv list of numbers:

| // Our POJO being serialized. | Long[][] input = .... | | // Convert POJO to a string. | try { | String httpPart = OpenApi.of(schema, input); | } catch (SchemaValidationException e) { | // Oops, one of the restrictions were not met. | }

As a general rule, any POJO convertible to the intermediate type for the type/format of the schema can be serialized using the OpenAPI serializer. Here are the rules of POJO types allowed for various type/format combinations:

TypeFormatValid parameter types
string or empty byte
binary
binary-spaced
  • byte[] (default)
  • {@link java.io.InputStream}
  • {@link java.io.Reader} - Read into String and then converted using {@link java.lang.String#getBytes()}.
  • {@link java.lang.Object} - Converted to String and then converted using {@link java.lang.String#getBytes()}.
  • Any POJO transformable to a byte[] via the following methods:
    • public byte[] toBytes() {...}
    • public byte[] toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to a byte[] via an {@link oaj.swap.ObjectSwap}.
date
date-time
  • {@link java.util.Calendar} (default)
  • {@link java.util.Date}
  • Any POJO transformable to a {@link java.util.Calendar} via the following methods:
    • public Calendar toCalendar() {...}
    • public Calendar toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to a {@link java.util.Calendar} via an {@link oaj.swap.ObjectSwap}.
uon
empty
  • {@link java.lang.String} (default)
  • Any POJO transformable to a {@link java.lang.String} via the following methods:
    • public String toString() {...}
  • Any POJO transformable to a {@link java.lang.String} via an {@link oaj.swap.ObjectSwap}.
boolean empty
  • {@link java.lang.Boolean} (default)
  • boolean
  • {@link java.lang.String} - Converted to a {@link java.lang.Boolean}.
  • Any POJO transformable to a {@link java.lang.Boolean} via the following methods:
    • public Boolean toBoolean() {...}
    • public Boolean toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to a {@link java.lang.Boolean} via an {@link oaj.swap.ObjectSwap}.
integer int32
  • {@link java.lang.Integer} (default)
  • int
  • {@link java.lang.String} - Converted to an {@link java.lang.String}.
  • Any POJO transformable to an {@link java.lang.Integer} via the following methods:
    • public Integer toInteger() {...}
    • public Integer toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to an {@link java.lang.Integer} via an {@link oaj.swap.ObjectSwap}.
int64
  • {@link java.lang.Long} (default)
  • long
  • {@link java.lang.String} - Converted to a {@link java.lang.Long}.
  • Any POJO transformable to a {@link java.lang.Long} via the following methods:
    • public Long toLong() {...}
    • public Long toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to a {@link java.lang.Long} via an {@link oaj.swap.ObjectSwap}.
number float
  • {@link java.lang.Float} (default)
  • float
  • {@link java.lang.String} - Converted to a {@link java.lang.Float}.
  • Any POJO transformable to a {@link java.lang.Float} via the following methods:
    • public Float toFloat() {...}
    • public Float toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to a {@link java.lang.Float} via an {@link oaj.swap.ObjectSwap}.
double
  • {@link java.lang.Double} (default)
  • double
  • {@link java.lang.String} - Converted to a {@link java.lang.Double}.
  • Any POJO transformable to a {@link java.lang.Double} via the following methods:
    • public Double toDouble() {...}
    • public Double toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to a {@link java.lang.Double} via an {@link oaj.swap.ObjectSwap}.
array empty
  • Arrays or Collections of any defaults on this list.
  • Any POJO transformable to arrays of the default types (e.g. Integer[], Boolean[][], etc...).
    For example:
    • public Boolean[][] toFoo() {...} (any method name starting with "to")
  • Any POJO transformable to arrays of the default types via an {@link oaj.swap.ObjectSwap}
uon
object empty
  • Map<String,Object> (default)
  • Beans with properties of anything on this list.
  • Any POJO transformable to a map via an {@link oaj.swap.ObjectSwap}
uon

For arrays, an example of "Any POJO transformable to arrays of the default types" is:

| // Sample POJO class convertable to a Long[][]. | public class MyPojo { | | // toX method used by serializer. | public Long[][] to2dLongs() {...} | }

In the example above, our POJO class can be used to create our pipe-delimited list of comma-delimited numbers:

| // Our POJO being serialized. | MyPojo input = .... | | // Convert POJO to a string. | try { | String httpPart = OpenApi.of(schema, input); | } catch (SchemaValidationException e) { | // Oops, one of the restrictions were not met. | }

The object type is not officially part of the OpenAPI standard. However, Juneau supports serializing Maps and beans to HTTP parts using UON notation.

The following shows an example of a bean with several properties of various types.

| public class MyBean { | private static byte[] FOOB = "foo".getBytes(); | | public String f1 = "foo"; | public byte[] f2 = FOOB; | public byte[] f3 = FOOB; | public byte[] f4 = FOOB; | public Calendar f5 = parseIsoCalendar("2012-12-21T12:34:56Z"); | public String f6 = "foo"; | public int f7 = 1; | public Long f8 = 2l; | public float f9 = 1.0; | public Double f10 = 1.0; | public Boolean f11 = true; | public Object fExtra = "1"; | }

We define the following schema:

| import static org.apache.juneau.httppart.HttpPartSchema.*; | | HttpPartSchema schema = tObject() | .prop("f1", tString()) | .prop("f2", tByte()) | .prop("f3", tBinary()) | .prop("f4", tBinarySpaced()) | .prop("f5", tDateTime()) | .prop("f6", tUon()) | .prop("f7", tInteger()) | .prop("f8", tInt64()) | .prop("f9", tNumber()) | .prop("f10", tDouble()) | .prop("f11", tBoolean()) | .ap(tInteger()) | .build();

Then we serialize our bean:

| String httpPart = OpenApi.of(schema, new MyBean());

The results of this serialization is shown below:

| ( | f1=foo, | f2=Zm9v, | f3=666F6F, | f4='66 6F 6F', | f5=2012-12-21T12:34:56Z, | f6=foo, | f7=1, | f8=2, | f9=1.0, | f10=1.0, | f11=true, | fExtra=1 | )

The following is an example of a bean with various array property types:

| public class MyBean { | private static byte[] FOOB = "foo".getBytes(); | | public String[] f1 = {"a,b",null}, | public byte[][] f2 = new byte[][]{FOOB,null}, | public byte[][] f3 = new byte[][]{FOOB,null}, | public byte[][] f4 = new byte[][]{FOOB,null}, | public Calendar[] f5 = new Calendar[]{parseIsoCalendar("2012-12-21T12:34:56Z"),null}, | public String[] f6 = {"a","b",null}, | public int[] f7 = new int[]{1,2,null}, | public Integer[] f8 = new Integer[]{3,4,null}, | public float[] f9 = new float[]{1f,2f,null}, | public Float[] f10 = new Float[]{3f,4f,null}, | public Boolean[] f11 = new Boolean[]{true,false,null}, | public Object[] fExtra = new Object[]{1,"2",null}; | }

For this bean, we define the following schema:

| import static org.apache.juneau.httppart.HttpPartSchema.*; | | HttpPartSchema schema = tObject() | .prop("f1", tArray(tString())) | .prop("f2", tArray(tByte())) | .prop("f3", tArray(tBinary())) | .prop("f4", tArray(tBinarySpaced())) | .prop("f5", tArray(tDateTime())) | .prop("f6", tArray(tUon())) | .prop("f7", tArray(tInteger())) | .prop("f8", tArray(tInt64())) | .prop("f9", tArray(tNumber())) | .prop("f10", tArray(tDouble())) | .prop("f11", tArray(tBoolean())) | .ap(tArray(tInteger())) | .build();

Serializing this bean produces the following output:

| ( | f1=@('a,b',null), | f2=@(Zm9v,null), | f4=@(2012-12-21T12:34:56Z,null), | f5=@(666F6F,null), | f6=@('66 6F 6F',null), | f7=@(a,b,null), | f8=@(1,2,null), | f9=@(3,4,null), | f10=@(1.0,2.0,null), | f11=@(3.0,4.0,null), | f12=@(true,false,null), | fExtra=@(1,2,null) | )