OpenAPI Parsers
The OpenApiParser class is used to convert HTTP parts back into POJOs.
Class hierarchy
The class hierarchy for the builder of this parser is:
Refer to the builder javadocs for configurable settings.
Parsing with a schema
The following is the previous example of a schema that defines the format of a pipe-delimited list of comma-delimited
numbers (e.g.
"1,2,3|4,5,6|7,8,9"):
import static org.apache.juneau.marshall.httppart.HttpPartSchema.*;
HttpPartSchema schema = tArrayPipes(
tArrayCsv(
tInt64().min(0).max(100)
)
).build();
The following program uses the schema above to parse our input into a POJO:
import static org.apache.juneau.marshall.httppart.HttpPartSchema.*;
import org.apache.juneau.commons.httppart.*;
import org.apache.juneau.marshall.httppart.*;
import org.apache.juneau.marshall.oapi.*;
public class PipeCsvParseExample {
public static void main(String[] args) throws Exception {
HttpPartSchema schema = tArrayPipes(
tArrayCsv(
tInt64().min(0).max(100)
)
).build();
// Our input being parsed.
String input = "1,2,3|4,5,6|7,8,9";
// Convert string to a POJO.
try {
Long[][] pojo = OpenApiParser.DEFAULT.read(HttpPartType.QUERY, schema, input, Long[][].class);
System.out.println(pojo[2][1]);
} catch (SchemaValidationException e) {
// Oops, one of the restrictions were not met.
System.out.println("rejected: " + e.getMessage());
}
}
}
The program prints 8.
Allowed POJO types
As a general rule, any POJO convertible from the intermediate type for the type/format of the schema can be parsed
using the OpenAPI parser.
Here are the rules of POJO types allowed for various type/format combinations:
| Type | Format | Valid parameter types |
|---|---|---|
string or empty | bytebinarybinary-spaced | • |
datedate-time | • Calendar (default) | |
uon | • Any Parsable POJO type | |
| empty | • String (default) | |
boolean | empty | • Boolean (default) |
integer | int32 | • Integer (default) |
int64 | • Long (default) | |
number | float | • Float (default) |
double | • Double (default) | |
array | empty | • Arrays or |
uon | • Any Parsable POJO type | |
object | empty | • |
uon | • Any Parsable POJO type |
Additionally, any of the type above can also be wrapped as Optionals.
Array types
For arrays, an example of "Any POJO transformable from arrays of the default types" is:
// Sample POJO class convertable from a Long[][].
public class MyPojo {
// Constructor used by parser.
public MyPojo(Long[][] from2dLongs) {...}
}
In the example above, our POJO class can be constructed from our pipe-delimited list of comma-delimited numbers:
import static org.apache.juneau.marshall.httppart.HttpPartSchema.*;
import org.apache.juneau.commons.httppart.*;
import org.apache.juneau.marshall.httppart.*;
import org.apache.juneau.marshall.oapi.*;
public class MyPojoParseExample {
// Sample POJO class convertible from a Long[][].
public static class MyPojo {
private final Long[][] values;
// Constructor used by parser.
public MyPojo(Long[][] from2dLongs) {
this.values = from2dLongs;
}
}
public static void main(String[] args) throws Exception {
HttpPartSchema schema = tArrayPipes(
tArrayCsv(
tInt64().min(0).max(100)
)
).build();
// Our input being parsed.
String input = "1,2,3|4,5,6|7,8,9";
// Convert string to a POJO.
try {
MyPojo pojo = OpenApiParser.DEFAULT.read(HttpPartType.QUERY, schema, input, MyPojo.class);
System.out.println(pojo.values[1][1]);
} catch (SchemaValidationException e) {
// Oops, one of the restrictions were not met.
System.out.println("rejected: " + e.getMessage());
}
}
}
The program prints 5.
Object types
Just like serialization, the object type is not officially part of the OpenAPI standard but Juneau supports parsing
HTTP parts written as comma-delimited name=value pairs to Maps and beans.
The following shows an example of a bean with several properties of various types.
import java.util.*;
public class MyBean {
public String f1;
public byte[] f2;
public byte[] f3;
public byte[] f4;
public Calendar f5;
public String f6;
public int f7;
public Long f8;
public float f9;
public Double f10;
public Boolean f11;
public Object fExtra;
}
We define the following schema again:
import static org.apache.juneau.marshall.httppart.HttpPartSchema.*;
HttpPartSchema schema = tObject()
.p("f1", tString())
.p("f2", tByte())
.p("f3", tBinary())
.p("f4", tBinarySpaced())
.p("f5", tDateTime())
.p("f6", tUon())
.p("f7", tInteger())
.p("f8", tInt64())
.p("f9", tNumber())
.p("f10", tDouble())
.p("f11", tBoolean())
.ap(tInteger())
.build();
Then we parse our input into our POJO:
String input =
"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";
MyBean bean = OpenApiParser.DEFAULT.read(HttpPartType.QUERY, schema, input, MyBean.class);
Note that serializing into generic Object properties would have produced similar results:
public class MyBean {
public Object f1;
public Object f2;
public Object f3;
public Object f4;
public Object f5;
public Object f6;
public Object f7;
public Object f8;
public Object f9;
public Object f10;
public Object f11;
public Object fExtra;
}
Parsing into maps
We can also parse into Maps as well:
import static org.apache.juneau.marshall.httppart.HttpPartSchema.*;
import org.apache.juneau.commons.httppart.*;
import org.apache.juneau.marshall.collections.*;
import org.apache.juneau.marshall.httppart.*;
import org.apache.juneau.marshall.oapi.*;
public class MyMapParseExample {
public static void main(String[] args) throws Exception {
HttpPartSchema schema = tObject()
.p("f1", tString())
.p("f2", tByte())
.p("f3", tBinary())
.p("f4", tBinarySpaced())
.p("f5", tDateTime())
.p("f6", tUon())
.p("f7", tInteger())
.p("f8", tInt64())
.p("f9", tNumber())
.p("f10", tDouble())
.p("f11", tBoolean())
.ap(tInteger())
.build();
String input =
"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";
JsonMap map = OpenApiParser.DEFAULT.read(HttpPartType.QUERY, schema, input, JsonMap.class);
System.out.println(map.get("f8") + " " + map.get("f11"));
}
}
The program prints 2 true.
- Array properties can also use CSV/SSV/PIPES for array notation.
- Various notations can be mixed throughout.
- Schemas and POJOs can be defined arbitrarily deep.
- Schemas are optional. They can be skipped or partially defined.
We make our best attempt to convert the output to the matching type.
However, you will get ParseExceptions if you attempt an impossible conversion. (e.g.trying to parse the string "foo"
into a boolean).