You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/09/18 00:09:15 UTC
[50/51] [partial] incubator-juneau-website git commit: Update about
page and javadocs.
http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/7917150f/content/about.html
----------------------------------------------------------------------
diff --git a/content/about.html b/content/about.html
index a3c0976..2e783d0 100644
--- a/content/about.html
+++ b/content/about.html
@@ -7,95 +7,294 @@
</style>
</head>
<body>
- <h5 class='toc'>About</h5>
- <p>
- A single cohesive framework consisting of the following parts:
- </p>
- <ul class='spaced-list'>
- <li>A universal toolkit for marshalling POJOs to a wide variety of content types using a common framework.
- <li>A universal REST server API for creating Swagger-based self-documenting REST interfaces using POJOs, simply deployed as
- one or more top-level servlets in any Servlet 3.1.0+ container.
- <li>A universal REST client API for interacting with Juneau or 3rd-party REST interfaces using POJOs and proxy interfaces.
- <li>A sophisticated configuration file API.
- <li>A REST microservice API that combines all the features above with a simple configurable Jetty server for
- creating lightweight standalone REST interfaces that start up in milliseconds.
- <li>Built on top of Servlet and Apache HttpClient APIs that allow you to use the newest HTTP/2 features
- such as request/response multiplexing and server push.
- </ul>
- <p>
- Questions via email to <a class='doclink' href='mailto:dev@juneau.apache.org?Subject=Apache%20Juneau%20question'>dev@juneau.apache.org</a> are always welcome.
- </p>
- <p>
- Juneau is packed with features that may not be obvious at first.
- Users are encouraged to ask for code reviews by providing links to specific source files such as through GitHub.
- Not only can we help you with feedback, but it helps us understand usage patterns to further improve the product.
- </p>
- <h5 class='toc'>Features</h5>
- <ul class='spaced-list'>
- <li>Marshalling support for:
+
+ <!-- =========================================================================================================== -->
+ <!-- === ABOUT ================================================================================================= -->
+ <!-- =========================================================================================================== -->
+
+ <h5 class='toc'>1 - About</h5>
+ <div>
+ <p>
+ A single cohesive framework consisting of the following parts:
+ </p>
+ <ul class='spaced-list'>
+ <li>A universal toolkit for marshalling POJOs to a wide variety of content types using a common framework.
+ <li>A universal REST server API for creating Swagger-based self-documenting REST interfaces using POJOs, simply deployed as
+ one or more top-level servlets in any Servlet 3.1.0+ container.
+ <li>A universal REST client API for interacting with Juneau or 3rd-party REST interfaces using POJOs and proxy interfaces.
+ <li>A sophisticated configuration file API.
+ <li>A REST microservice API that combines all the features above with a simple configurable Jetty server for
+ creating lightweight standalone REST interfaces that start up in milliseconds.
+ <li>Built on top of Servlet and Apache HttpClient APIs that allow you to use the newest HTTP/2 features
+ such as request/response multiplexing and server push.
+ </ul>
+ <p>
+ Questions via email to <a class='doclink' href='mailto:dev@juneau.apache.org?Subject=Apache%20Juneau%20question'>dev@juneau.apache.org</a> are always welcome.
+ </p>
+ <p>
+ Juneau is packed with features that may not be obvious at first.
+ Users are encouraged to ask for code reviews by providing links to specific source files such as through GitHub.
+ Not only can we help you with feedback, but it helps us understand usage patterns to further improve the product.
+ </p>
+ </div>
+
+ <!-- =========================================================================================================== -->
+ <!-- === FEATURES ============================================================================================== -->
+ <!-- =========================================================================================================== -->
+
+ <h5 class='toc'>2 - Features</h5>
+ <div>
+ <ul class='spaced-list'>
+ <li>KISS is our mantra! No auto-wiring. No code generation. No dependency injection. Just add it to your classpath and use it. Extremely simple unit testing!
+ <li>Tiny - ~1MB
+ <li>Exhaustively tested
+ </ul>
+ </div>
+
+ <!-- =========================================================================================================== -->
+ <!-- === COMPONENTS ============================================================================================ -->
+ <!-- =========================================================================================================== -->
+
+ <h5 class='toc'>3 - Components</h5>
+ <div>
+ <p>
+ We've strived to keep prerequisites to an absolute minimum in order to make adoption as easy as possible.
+ </p>
+ <p>
+ The library consists of the following artifacts found in the Maven group <code>"org.apache.juneau"</code>:
+ </p>
+ <table class='styled' style='min-width:800px;'>
+ <tr>
+ <th>Category</th><th>Maven Artifacts</th><th>Description</th><th>Prereqs</th>
+ </tr>
+ <tr class='dark bb'>
+ <td rowspan="5" style='text-align:center;font-weight:bold;padding:20px;' class='code'><a class='doclink' href='#juneau-core'>juneau-core</a></td>
+ <td class='code'><a class='doclink' href='#juneau-marshall'>juneau-marshall</a></td>
+ <td>Serializers and parsers for:
+ <ul style='margin:0px 10px;'>
+ <li>JSON
+ <li>XML
+ <li>HTML
+ <li>UON
+ <li>URL-Encoding
+ <li>MessagePack
+ <li>SOAP/XML
+ <li>CSV
+ <li>BSON (coming soon)
+ <li>YAML (coming soon)
+ <li>Protobuf (coming soon)
+ </ul>
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 6
+ </ul>
+ </td>
+ </tr>
+ <tr class='dark bb'>
+ <td class='code'><a class='doclink' href='#juneau-marshall-rdf'>juneau-marshall-rdf</a></td>
+ <td>
+ Serializers and parsers for:
+ <ul style='margin:0px 10px;'>
+ <li>RDF/XML
+ <li>RDF/XML-Abbrev
+ <li>N-Triple
+ <li>Turtle
+ <li>N3
+ </ul>
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 6
+ <li>Apache Jena 2.7.1
+ </ul>
+ </td>
+ </tr>
+ <tr class='dark bb'>
+ <td class='code'><a class='doclink' href='#juneau-dto'>juneau-dto</a></td>
+ <td>
+ Data Transfer Objects for:
+ <ul style='margin:0px 10px;'>
+ <li>HTML5
+ <li>Atom
+ <li>Cognos
+ <li>JSON-Schema
+ <li>Swagger 2.0
+ </ul>
+ </td>
+ <td><ul style='margin:0px 10px;'><li>Java 6</li></ul></td>
+ </tr>
+ <tr class='dark bb'>
+ <td class='code'><a class='doclink' href='#juneau-svl'>juneau-svl</a></td>
+ <td>
+ Simple Variable Language API
+ </td>
+ <td><ul style='margin:0px 10px;'><li>Java 6</li></ul></td>
+ </tr>
+ <tr class='dark bb'>
+ <td class='code'><a class='doclink' href='#juneau-config'>juneau-config</a></td>
+ <td>
+ Configuration file API
+ </td>
+ <td><ul style='margin:0px 10px;'><li>Java 6</li></ul></td>
+ </tr>
+ <tr class='light bb'>
+ <td rowspan="3" style='text-align:center;font-weight:bold;padding:20px;' class='code'><a class='doclink' href='#juneau-rest'>juneau-rest</a></td>
+ <td class='code'><a class='doclink' href='#juneau-rest-server'>juneau-rest-server</a></td>
+ <td>
+ REST Servlet API
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 6
+ <li>Servlet 3.1
+ </ul>
+ </td>
+ </tr>
+ <tr class='light bb'>
+ <td class='code'><a class='doclink' href='#juneau-rest-server-jaxrs'>juneau-rest-server-jaxrs</a></td>
+ <td>
+ Optional JAX-RS support
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 6
+ <li>JAX-RS 2.0
+ </ul>
+ </td>
+ </tr>
+ <tr class='light bb'>
+ <td class='code'><a class='doclink' href='#juneau-rest-client'>juneau-rest-client</a></td>
+ <td>
+ REST Client API
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 6
+ <li>Apache HttpClient 4.5
+ </ul>
+ </td>
+ </tr>
+ <tr class='dark bb'>
+ <td rowspan="2" style='text-align:center;font-weight:bold;padding:20px;' class='code'><a class='doclink' href='#juneau-microservice'>juneau-microservice</a></td>
+ <td class='code'><a class='doclink' href='#juneau-microservice-server'>juneau-microservice-server</a></td>
+ <td>
+ REST Microservice Server API
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 8
+ <li>Eclipse Jetty 9.4.3
+ </ul>
+ </td>
+ </tr>
+ <tr class='dark bb'>
+ <td class='code'><a class='doclink' href='#juneau-microservice-template'>juneau-microservice-template</a></td>
+ <td>
+ Developer template project
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 8
+ <li>Eclipse Jetty 9.4.3
+ </ul>
+ </td>
+ </tr>
+ <tr class='light bb'>
+ <td rowspan="2" style='text-align:center;font-weight:bold;padding:20px;' class='code'><a class='doclink' href='#juneau-examples'>juneau-examples</a></td>
+ <td class='code'><code>juneau-examples-core</code></td>
+ <td>
+ Core code examples
+ </td>
+ <td></td>
+ </tr>
+ <tr class='light bb'>
+ <td class='code'><code>juneau-examples-rest</code></td>
+ <td>
+ REST code examples
+ </td>
+ <td></td>
+ </tr>
+ <tr class='dark bb'>
+ <td rowspan="1" style='text-align:center;font-weight:bold;padding:20px;' class='code'><a class='doclink' href='#juneau-all'>juneau-all</a></td>
+ <td class='code'><code>juneau-all</code></td>
+ <td>
+ Combination of the following:
+ <ul style='margin:0px 10px;'>
+ <li>juneau-marshall
+ <li>juneau-dto
+ <li>juneau-svl
+ <li>juneau-config
+ <li>juneau-rest-server
+ <li>juneau-rest-client
+ </ul>
+ </td>
+ <td>
+ <ul style='margin:0px 10px;'>
+ <li>Java 6
+ <li>Servlet 3.1
+ <li>Apache HttpClient 4.5
+ </ul>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <!-- =========================================================================================================== -->
+ <!-- === JUNEAU CORE =========================================================================================== -->
+ <!-- =========================================================================================================== -->
+
+ <h5 class='toc' id='juneau-core'>4 - juneau-core</h5>
+ <div>
+
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-MARSHALL =================================================================================== -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-marshall'>4.1 - juneau-marshall</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-marshall<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-marshall-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The <code>juneau-marshall</code> library includes easy-to-use and highly customizable serializers and parsers
+ based around a common API.
+ They provide support for the following languages:
+ </p>
<ul>
- <li>JSON (including variants, lax syntax, support for comments, fully RFC1759 compliant, plus JSON-Schema)
- <li>XML (including namespace support, plus XML-Schema)
- <li>HTML (plus HTML-Schema)
- <li>URL-Encoding
+ <li>JSON
+ <li>XML
+ <li>HTML
<li>UON (URL-Encoded Object Notation)
+ <li>URL-Encoding
<li>MessagePack
- <li>RDF/XML
- <li>RDF/XML-Abbrev
- <li>N-Triple
- <li>Turtle
- <li>N3
- <li>CSV
<li>SOAP/XML
- <li>Coming soon: Protobuf, YAML, BSON
- </ul>
- <li>Data Transfer Objects for:
- <ul>
- <li>HTML5
- <li>Atom
- <li>Cognos
- <li>JSON-Schema
- <li>Swagger 2.0
- </ul>
- <li>KISS is our mantra! No auto-wiring. No code generation. No dependency injection. Just add it to your classpath and use it. Extremely simple unit testing!
- <li>Tiny - ~1MB
- <li>Exhaustively tested
- </ul>
-
- <h5 class='toc'>Prerequisites</h5>
-
- <p>
- We've strived to keep prerequisites to an absolute minimum.
- </p>
- <ul class='spaced-list'>
- <li>The serializers and parsers require nothing more than Java 6+.
- <li>The RDF serializers and parsers require Apache Jena 2.5.1+.
- <li>The REST server API requires any Servlet 3.1.0+ container.
- <li>The REST client API requires Apache HttpClient 4.5+.
- <li>The REST microservice API uses Eclipse Jetty 9.4.3.
- </ul>
-
- <h5 class='toc'>Components</h5>
- <p>
- The library consists of 4 components/jars and a single uber-jar that contains everything.
- </p>
- <img src='images/Components.png'>
-
- <h5 class='toc'>Juneau Core</h5>
- <p>
- Core library includes easy-to-use and customizable serializers and parsers. The examples here provide a small taste of what's possible.
- </p>
- <p>
- The default serializers can often be used to serialize POJOs in a single line of code:
- </p>
- <p class='bcode'>
+ <li>CSV
+ <li>BSON (coming soon)
+ <li>YAML (coming soon)
+ <li>Protobuf (coming soon)
+ </ul>
+ <p>
+ The default serializers can often be used to serialize POJOs in a single line of code:
+ </p>
+ <p class='bcode'>
<jc>// A simple bean</jc>
<jk>public class</jk> Person {
<jk>public</jk> String name = <js>"John Smith"</js>;
<jk>public int</jk> age = 21;
}
- <jc>// Serialize a bean to JSON, XML, or HTML</jc>
Person p = <jk>new</jk> Person();
<jc>// Produces:
@@ -134,35 +333,15 @@
<jc>// Produces:
// 82 A4 name AA 4A John Smith 68 A3 age 15</jc>
<jk>byte</jk>[] messagePack = MsgPackSerializer.<jsf>DEFAULT</jsf>.serialize(p);
-
- <jc>// Produces:
- // <rdf:RDF
- // xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- // xmlns:jp="http://www.apache.org/juneaubp/"
- // xmlns:j="http://www.apache.org/juneau/">
- // <rdf:Description>
- // <jp:name>John Smith</jp:name>
- // <jp:age>21</jp:age>
- // </rdf:Description>
- // </rdf:RDF></jc>
- String rdfXml = RdfSerializer.<jsf>DEFAULT_XMLABBREV</jsf>.serialize(p);
-
- <jc>// Produces:
- // @prefix jp: <http://www.apache.org/juneaubp/> .
- // @prefix j: <http://www.apache.org/juneau/> .
- // [] jp:age "21" ;
- // jp:name "John Smith" .</jc>
- String rdfN3 = RdfSerializer.<jsf>DEFAULT_N3</jsf>.serialize(p);
-
- <jc>// Produces:
- // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/name> "John Smith" .
- // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/age> "21" .</jc>
- String rdfNTriple = RdfSerializer.<jsf>DEFAULT_NTRIPLE</jsf>.serialize(p);
- </p>
- <p>
- Parsing back into POJOs is equally simple for any of the supported languages shown above (JSON shown here):
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ Parsing back into POJOs is equally simple for any of the supported languages shown above.
+ Language fragments are also supported.
+ </p>
+ <p>
+ JSON parsing shown here:
+ </p>
+ <p class='bcode'>
<jc>// Use one of the predefined parsers.</jc>
ReaderParser parser = JsonParser.<jsf>DEFAULT</jsf>;
@@ -207,19 +386,27 @@
ObjectList l9a = parser.parse(json, ObjectList.<jk>class</jk>);
<jk>boolean</jk> b = l9a.getBoolean(1);
ObjectList l9b = (ObjectList)parser.parse(json, Object.<jk>class</jk>); <jc>// Equivalent.</jc>
- </p>
- <h5 class='toc'>Features</h5>
- <ul class='spaced-list'>
- <li>Serializers can send output directly to Writers, OutputStreams, Files, Strings, or byte arrays.
- <li>Parsers can receive input directly from Readers, InputStreams, Files, Strings, or byte arrays.
- <li>Parsers can reconstruct arbitrarily complex data structures consisting of maps, collections, beans, and other POJOs.
- <li>Serializers and parsers do not use intermediate DOMs! POJOs are serialized directly to streams and parsed back directly to POJOs, making them extremely efficient and fast.
- </ul>
- <br><hr>
- <p>
- Serializers and parsers are builder-based. Build from scratch or clone existing instances. Lots of configuration options available for all the languages.
- </p>
- <p class='bcode'>
+ </p>
+
+ <h6 class='topic'>Features</h6>
+ <ul class='spaced-list'>
+ <li>Serializers can send output directly to Writers, OutputStreams, Files, Strings, or byte arrays.
+ <li>Parsers can receive input directly from Readers, InputStreams, Files, Strings, or byte arrays.
+ <li>Parsers can reconstruct arbitrarily complex data structures consisting of maps, collections, beans, and other POJOs.
+ <li>Serializers and parsers do not use intermediate DOMs! POJOs are serialized directly to streams and parsed back directly to POJOs, making them extremely efficient and fast.
+ <li>Supported languages are highly-customizable and powerful. For example, JSON support includes:
+ <ul>
+ <li>Support for variants such as LAX syntax (unquoted attributes and single quotes).
+ <li>Support for embedded Javascript comments.
+ <li>Fully RFC1759 compliant.
+ <li>20% faster than Jackson.
+ </ul>
+ </ul>
+ <br><hr>
+ <p>
+ Serializers and parsers are builder-based. Build from scratch or clone existing instances. Lots of configuration options available for all the languages.
+ </p>
+ <p class='bcode'>
<jc>// Create a serializer from scratch using a builder</jc>
JsonSerializer serializer = <jk>new</jk> JsonSerializerBuilder()
.simple() <jc>// Simple mode</jc>
@@ -248,46 +435,45 @@
JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.builder()
.sq()
.build();
- </p>
- <br><br><hr>
- <p>
- Many POJOs such as primitives, beans, collections, arrays, and classes with various known constructors and methods are serializable out-of-the-box.
- For other objects, "transforms" allow you to perform various mutations on them before serialization and after parsing.
- </p>
- <ul class='spaced-list'>
- <li>Transforms
- <ul>
- <li>Bean filters - Control how bean properties are handled (naming conventions, ordering, visibility,...).
- <li>POJO swaps - Replace non-serializable POJOs with serializable equivalents.
- <br>Predefined swaps provided for common cases: <code>ByteArrayBase64Swap</code>, 50+ variants of Calendar/Date swaps, <code>Enumeration/Iterator</code> swaps.
+ </p>
+ <br><br><hr>
+ <p>
+ Many POJOs such as primitives, beans, collections, arrays, and classes with various known constructors and methods are serializable out-of-the-box.
+ For other objects, "transforms" allow you to perform various mutations on them before serialization and after parsing.
+ </p>
+ <ul class='spaced-list'>
+ <li>Transforms
+ <ul>
+ <li>Bean filters - Control how bean properties are handled (naming conventions, ordering, visibility,...).
+ <li>POJO swaps - Replace non-serializable POJOs with serializable equivalents.
+ <br>Predefined swaps provided for common cases: <code>ByteArrayBase64Swap</code>, 50+ variants of Calendar/Date swaps, <code>Enumeration/Iterator</code> swaps.
+ </ul>
+ <li>Annotations
+ <br>Various annotations available for your POJO classes that are recognized by ALL serializers and parsers:
+ <br><ja>@Bean</ja>, <ja>@Pojo</ja>, <ja>@BeanIgnore</ja>, <ja>@BeanParam</ja>, <ja>@BeanProperty</ja>, <ja>@NameProperty</ja>, <ja>@ParentProperty</ja>
+ <br>
+ <br>Annotations also provided for language-specific behaviors where it makes sense:
+ <br><ja>@Json</ja>, <ja>@Html</ja>, <ja>@Xml</ja>, <ja>@UrlEncoding</ja>
+ <br>
+ <br>All annotations have programmatic equivalents when you don't have access to POJO source.
+
+ <li>Swap methods
+ <br>By default, various instance and static methods and constructors are automatically detected and supported:
+ <br><code>valueOf(String)</code>, <code>parse(String)</code>, <code>parseString(String)</code>, <code>forName(String)</code>, <code>forString(String)</code>,
+ <code>fromString(String)</code>, <code>T(String)</code>, <code>Object swap(BeanSession)</code>, <code>T unswap(BeanSession, T.class)</code>
</ul>
- <li>Annotations
- <br>Various annotations available for your POJO classes that are recognized by ALL serializers and parsers:
- <br><ja>@Bean</ja>, <ja>@Pojo</ja>, <ja>@BeanIgnore</ja>, <ja>@BeanParam</ja>, <ja>@BeanProperty</ja>, <ja>@NameProperty</ja>, <ja>@ParentProperty</ja>
- <br>
- <br>Annotations also provided for language-specific behaviors:
- <br><ja>@Json</ja>, <ja>@Html</ja>, <ja>@Xml</ja>, <ja>@UrlEncoding</ja>
- <br>
- <br>All annotations have programmatic equivalents when you don't have access to POJO source.
-
- <li>Swap methods
- <br>By default, various instance and static methods and constructors are automatically detected and supported:
- <br><code>valueOf(String)</code>, <code>parse(String)</code>, <code>parseString(String)</code>, <code>forName(String)</code>, <code>forString(String)</code>,
- <code>fromString(String)</code>, <code>T(String)</code>, <code>Object swap(BeanSession)</code>, <code>T unswap(BeanSession, T.class)</code>
- </ul>
-
- <h5 class='topic'>Additional Information</h5>
- <ul class='doctree'>
- <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Core.PojoCategories'>POJO Categories</a> for a definition of supported POJOs.
- </ul>
-
- <br><hr>
- <p>
- UON (URL-Encoded Object Notation) allows JSON-like data structures (OBJECT, ARRAY, NUMBER, BOOLEAN, STRING, NULL) in HTTP constructs (query parameters, form parameters,
- headers, URL parts) without violating RFC2396.
- This allows POJOs to be converted directly into HTTP constructs.
- </p>
- <p class='bcode'>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-marshall.PojoCategories'>POJO Categories</a> for a definition of supported POJOs.
+ </ul>
+
+ <br><hr>
+ <p>
+ UON (URL-Encoded Object Notation) allows JSON-like data structures (OBJECT, ARRAY, NUMBER, BOOLEAN, STRING, NULL) in HTTP constructs (query parameters, form parameters,
+ headers, URL parts) without violating RFC2396.
+ This allows POJOs to be converted directly into these HTTP constructs which is not possible in any other language such as JSON.
+ </p>
+ <p class='bcode'>
(
id=1,
name=<js>'John+Smith'</js>,
@@ -307,12 +493,17 @@
)
)
)
- </p>
- <br><br><hr>
- <p>
- Lots of shortcuts are provided throughout the API to simplify tasks, and the APIs are often useful for debugging and logging purposes as well...
- </p>
- <p class='bcode'>
+ </p>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/org/apache/juneau/uon/package-summary.html#TOC'>org.apache.juneau.uon</a> for more information.
+ </ul>
+
+ <br><hr>
+ <p>
+ Lots of shortcuts are provided throughout the API to simplify tasks, and the APIs are often useful for debugging and logging purposes as well...
+ </p>
+ <p class='bcode'>
<jc>// Create JSON strings from scratch using fluent-style code.</jc>
String jsonObject = <jk>new</jk> ObjectMap().append(<js>"foo"</js>,<js>"bar"</js>).toString();
String jsonArray = <jk>new</jk> ObjectList().append(<js>"foo"</js>).append(123).append(<jk>null</jk>).toString();
@@ -342,13 +533,13 @@
PojoRest pojoRest = <jk>new</jk> PojoRest(myPojo);
pojoRest.get(String.<jk>class</jk>, <js>"addressBook/0/name"</js>);
pojoRest.put(<js>"addressBook/0/name"</js>, <js>"John Smith"</js>);
- </p>
- <br><br><hr>
- <p>
- <code>SerializerGroup</code> and <code>ParserGroup</code> classes allow serializers and parsers
- to be retrieved by W3C-compliant HTTP <code>Accept</code> and <code>Content-Type</code> values:
- </p>
- <p class='bcode'>
+ </p>
+ <br><br><hr>
+ <p>
+ <code>SerializerGroup</code> and <code>ParserGroup</code> classes allow serializers and parsers
+ to be retrieved by W3C-compliant HTTP <code>Accept</code> and <code>Content-Type</code> values:
+ </p>
+ <p class='bcode'>
<jc>// Construct a new serializer group with configuration parameters that get applied to all serializers.</jc>
SerializerGroup sg = <jk>new</jk> SerializerGroupBuilder()
.append(JsonSerializer.<jk>class</jk>, UrlEncodingSerializer.<jk>class</jk>);
@@ -368,24 +559,126 @@
.build();
Person p = pg.getParser(<js>"text/json"</js>).parse(myReader, Person.<jk>class</jk>);
- </p>
+ </p>
+
+ <br><br><hr>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-marshall'>juneau-marshall</a> for more information.
+ </ul>
+ </div>
+
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-MARSHALL-RDF =============================================================================== -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-marshall-rdf'>4.2 - juneau-marshall-rdf</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-marshall-rdf<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-marshall-rdf-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The <code>juneau-marshall-rdf</code> library provides additional serializers and parsers for RDF.
+ These rely on the Apache Jena library to provide support for the following languages:
+ </p>
+ <ul>
+ <li>RDF/XML
+ <li>RDF/XML-Abbrev
+ <li>N-Triple
+ <li>Turtle
+ <li>N3
+ </ul>
+ <p>
+ The serializers and parsers work identically to those in <code>juneau-marshall</code>, but are
+ packaged separately so that you don't need to pull in the Jena dependency unless you need it.
+ </p>
+
+ <p class='bcode'>
+ <jc>// A simple bean</jc>
+ <jk>public class</jk> Person {
+ <jk>public</jk> String name = <js>"John Smith"</js>;
+ <jk>public int</jk> age = 21;
+ }
+
+ <jc>// Serialize a bean to JSON, XML, or HTML</jc>
+ Person p = <jk>new</jk> Person();
+
+ <jc>// Produces:
+ // <rdf:RDF
+ // xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ // xmlns:jp="http://www.apache.org/juneaubp/"
+ // xmlns:j="http://www.apache.org/juneau/">
+ // <rdf:Description>
+ // <jp:name>John Smith</jp:name>
+ // <jp:age>21</jp:age>
+ // </rdf:Description>
+ // </rdf:RDF></jc>
+ String rdfXml = RdfSerializer.<jsf>DEFAULT_XMLABBREV</jsf>.serialize(p);
- <h5 class='topic'>Additional Information</h5>
- <ul class='doctree'>
- <li class='link'><a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Core'>Juneau Core (org.apache.juneau)</a>
- </ul>
+ <jc>// Produces:
+ // @prefix jp: <http://www.apache.org/juneaubp/> .
+ // @prefix j: <http://www.apache.org/juneau/> .
+ // [] jp:age "21" ;
+ // jp:name "John Smith" .</jc>
+ String rdfN3 = RdfSerializer.<jsf>DEFAULT_N3</jsf>.serialize(p);
- <br><hr>
+ <jc>// Produces:
+ // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/name> "John Smith" .
+ // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/age> "21" .</jc>
+ String rdfNTriple = RdfSerializer.<jsf>DEFAULT_NTRIPLE</jsf>.serialize(p);
+ </p>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-marshall-rdf'>juneau-marshall-rdf</a> for more information.
+ </ul>
+ </div>
- <h5 class='toc'>DTO libraries</h5>
- <p>
- Data Transfer Object libraries are provided for a variety of languages that allow you to serialize commonly-used
- documents.
- </p>
- <p>
- HTML5 documents and fragments can be constructed using the HTML5 DTOs and HTML or XML serializers:
- </p>
- <p class='bcode'>
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-DTO ======================================================================================== -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-dto'>4.3 - juneau-dto</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-dto<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-dto-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ Data Transfer Object libraries are provided for a variety of languages that allow you to serialize commonly-used
+ documents.
+ </p>
+ <ul>
+ <li>HTML5
+ <li>Atom
+ <li>Cognos
+ <li>JSON-Schema
+ <li>Swagger 2.0
+ </ul>
+ <p>
+ HTML5 documents and fragments can be constructed using the HTML5 DTOs and HTML or XML serializers:
+ </p>
+ <p class='bcode'>
<jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*;
Object myform =
@@ -398,19 +691,40 @@
);
String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(myform);
- </p>
- <p class='bcode'><xt>
- <form <xa>action</xa>=<xs>'/submit'</xs> <xa>method</xa>=<xs>'POST'</xs>>
- <xv>Position (1-10000):</xv> <input <xa>name</xa>=<xs>'pos'</xs> <xa>type</xa>=<xs>'number'</xs> <xa>value</xa>=<xs>'1'</xs>/><br/>
- <xv>Limit (1-10000):</xv> <input <xa>name</xa>=<xs>'pos'</xs> <xa>type</xa>=<xs>'number'</xs> <xa>value</xa>=<xs>'100'</xs>/><br/>
- <button <xa>type</xa>=<xs>'submit'</xs>><xv>Submit</xv></button>
- <button <xa>type</xa>=<xs>'reset'</xs>><xv>Reset</xv></button>
- </form>
- </xt></p>
- <p>
- ATOM feeds can be constructed using the ATOM DTOs and XML serializer:
- </p>
- <p class='bcode'>
+ </p>
+ <p class='bcode'><xt>
+ <form <xa>action</xa>=<xs>'/submit'</xs> <xa>method</xa>=<xs>'POST'</xs>>
+ <xv>Position (1-10000):</xv> <input <xa>name</xa>=<xs>'pos'</xs> <xa>type</xa>=<xs>'number'</xs> <xa>value</xa>=<xs>'1'</xs>/><br/>
+ <xv>Limit (1-10000):</xv> <input <xa>name</xa>=<xs>'pos'</xs> <xa>type</xa>=<xs>'number'</xs> <xa>value</xa>=<xs>'100'</xs>/><br/>
+ <button <xa>type</xa>=<xs>'submit'</xs>><xv>Submit</xv></button>
+ <button <xa>type</xa>=<xs>'reset'</xs>><xv>Reset</xv></button>
+ </form>
+ </xt></p>
+ <p>
+ And you're not limited to just HTML. The HTML5 beans are POJOs that can be serialized using any
+ of the serializers, such as lax JSON:
+ </p>
+ <p class='bcode'>
+ {
+ <jf>_type</jf>: <js>'form'</js>,
+ <jf>a</jf>: { <jf>action</jf>: <js>'/submit'</js>, <jf>method</jf>: <js>'POST'</js> },
+ <jf>c</jf>: [
+ <js>'Position (1-10000): '</js>,
+ { <jf>_type</jf>: <js>'input'</js>, <jf>a</jf>: { <jf>type</jf>: <js>'number'</js>, <jf>name</jf>: <js>'pos'</js>, <jf>value</jf>: 1 } },
+ { <jf>_type</jf>: <js>'br'</js> },
+ <js>'Limit (1-10000): '</js>,
+ { <jf>_type</jf>: <js>'input'</js>, <jf>a</jf>: { <jf>type</jf>: <js>'number'</js>, <jf>name</jf>: <js>'limit'</js>, <jf>value</jf>: 100 } },
+ { <jf>_type</jf>: <js>'br'</js> },
+ { <jf>_type</jf>: <js>'button'</js>, <jf>a</jf>: { <jf>type</jf>: <js>'submit'</js> }, <jf>c</jf>: [ <js>'Submit'</js> ] },
+ { <jf>_type</jf>: <js>'button'</js>, <jf>a</jf>: { <jf>type</jf>: <js>'reset'</js> }, <jf>c</jf>: [ <js>'Reset'</js> ] }
+ ]
+ }
+ </p>
+
+ <p>
+ ATOM feeds can be constructed using the ATOM DTOs and XML serializer:
+ </p>
+ <p class='bcode'>
<jk>import static</jk> org.apache.juneau.dto.atom.AtomBuilder.*;
Feed feed =
@@ -434,8 +748,8 @@
<jc>// Serialize to ATOM/XML</jc>
String atomXml = XmlSerializer.<jsf>DEFAULT</jsf>.serialize(feed);
- </p>
- <p class='bcode'>
+ </p>
+ <p class='bcode'>
<xt><feed></xt>
<xt><id></xt>
tag:juneau.apache.org
@@ -466,11 +780,11 @@
<xt><published></xt>2016-01-02T03:04:05Z<xt></published></xt>
<xt></entry></xt>
<xt></feed></xt>
- </p>
- <p>
- Swagger documents can be constructed using the Swagger DTOs and JSON serializer:
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ Swagger documents can be constructed using the Swagger DTOs and JSON serializer:
+ </p>
+ <p class='bcode'>
<jk>import static</jk> org.apache.juneau.dto.swagger.SwaggerBuilder.*;
Swagger swagger = <jsm>swagger</jsm>()
@@ -504,8 +818,8 @@
<jc>// Serialize to Swagger/JSON</jc>
String swaggerJson = JsonSerializer.<jsf>DEFAULT_READABLE</jsf>.serialize(swagger);
- </p>
- <p class='bcode'>
+ </p>
+ <p class='bcode'>
{
<jf>"swagger"</jf>: <js>"2.0"</js>,
<jf>"info"</jf>: {
@@ -555,42 +869,271 @@
}
},
}
- </p>
- <p>
- Note that these DTOs can also be serialized to any of the other supported languages such as JSON or MessagePack!
- And they can be parsed back into their original objects!
- </p>
-
- <h5 class='topic'>Additional Information</h5>
- <ul class='doctree'>
- <li class='link'><a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#DTOs'>Juneau Data Transfer Objects (org.apache.juneau.dto)</a>
- </ul>
+ </p>
+ <p>
+ Note that these DTOs can also be serialized to any of the other supported languages such as JSON or MessagePack!
+ And they can be parsed back into their original objects!
+ </p>
+ <p>
+ As a convenience, you can also simply call <code>toString()</code> on any of these DTOs and they will
+ be serialized directly to a string in the typical language (e.g. HTML5 beans to HTML, Swagger to JSON, etc...).
+ </p>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-dto'>juneau-dto</a> for more information.
+ </ul>
+ </div>
+
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-SVL ======================================================================================== -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-svl'>4.4 - juneau-svl</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-svl<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-svl-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The <code>juneau-svl</code> module defines an API for a language called "Simple Variable Language".
+ In a nutshell, Simple Variable Language (or SVL) is text that contains variables of the form
+ <js>"$varName{varKey}"</js>.
+ </p>
+ <p>
+ Variables can be recursively nested within the varKey (e.g. <js>"$FOO{$BAR{xxx},$BAZ{xxx}}"</js>).
+ Variables can also return values that themselves contain more variables.
+ </p>
+ <p class='bcode'>
+ <jc>// Use the default variable resolver to resolve a string that contains $S (system property) variables</jc>
+ String myProperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"The Java home directory is $S{java.home}"</js>);
+ </p>
+ <p>
+ The following shows how variables can be arbitrarily nested...
+ </p>
+ <p class='bcode'>
+ <jc>// Look up a property in the following order:
+ // 1) MYPROPERTY environment variable.
+ // 2) 'my.property' system property if environment variable not found.
+ // 3) 'not found' string if system property not found.</jc>
+ String myproperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"$E{MYPROPERTY,$S{my.property,not found}}"</js>);
+ </p>
+ <p>
+ SVL is a large topic on it's own.
+ It is used extensively in the ConfigFile, REST and Microservice APIs.
+ </p>
+ <p>
+ The following is the default list of supported variables:
+ </p>
+ <ul>
+ <li><code>$ARG{keyOrIndex[,defaultValue]}</code> - Command-line argument.
+ <li><code>$C{key[,defaultValue]}</code> - Config file entry.
+ <li><code>$E{envVar[,defaultValue]}</code> - Environment variable.
+ <li><code>$F{path[,defaultValue]}</code> - File resource.
+ <li><code>$I{name[,defaultValue]}</code> - Servlet init parameter.
+ <li><code>$L{key[,args...]}</code> - Localized message.
+ <li><code>$MF{key[,defaultValue]}</code> - Manifest file entry.
+ <li><code>$R{key[,args...]}</code> - Request variable.
+ <li><code>$S{systemProperty[,defaultValue]}</code> - System property.
+ <li><code>$SA{contentType,key[,defaultValue]}</code> - Serialized request attribute.
+ <li><code>$U{uri}</code> - URI resolver.
+ <li><code>$UE{uriPart}</code> - URL-Encoder.
+ <li><code>$W{widgetName}</code> - HTML widget variable.
+ </ul>
+ <p>
+ Plugging in your own variables is also easy.
+ </p>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-svl'>juneau-svl</a> for more information.
+ </ul>
+ </div>
+
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-CONFIG ===================================================================================== -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-config'>4.5 - juneau-config</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-config<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-config-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The <code>juneau-config</code> module defines an API allows you to interact with INI files using POJOs.
+ It builds upon the marshalling and SVL APIs to provide sophisticated dynamic configuration files.
+ <p>
+ <p class='bcode'>
+ <cc>#--------------------------</cc>
+ <cc># My section</cc>
+ <cc>#--------------------------</cc>
+ <cs>[MySection]</cs>
+
+ <cc># An integer</cc>
+ <ck>anInt</ck> = <cv>1</cv>
+
+ <cc># A boolean</cc>
+ <ck>aBoolean</ck> = <cv>true</cv>
+
+ <cc># An int array</cc>
+ <ck>anIntArray</ck> = <cv>[1,2,3]</cv>
+
+ <cc># A POJO that can be converted from a String</cc>
+ <ck>aURL</ck> = <cv>http://foo </cv>
+
+ <cc># A POJO that can be converted from JSON</cc>
+ <ck>aBean</ck> = <cv>{foo:'bar',baz:123}</cv>
+
+ <cc># A system property</cc>
+ <ck>locale</ck> = <cv>$S{java.locale, en_US}</cv>
+
+ <cc># An environment variable</cc>
+ <ck>path</ck> = <cv>$E{PATH, unknown}</cv>
+
+ <cc># A manifest file entry</cc>
+ <ck>mainClass</ck> = <cv>$MF{Main-Class}</cv>
+
+ <cc># Another value in this config file</cc>
+ <ck>sameAsAnInt</ck> = <cv>$C{MySection/anInt}</cv>
+
+ <cc># A command-line argument in the form "myarg=foo"</cc>
+ <ck>myArg</ck> = <cv>$ARG{myarg}</cv>
+
+ <cc># The first command-line argument</cc>
+ <ck>firstArg</ck> = <cv>$ARG{0}</cv>
+
+ <cc># Look for system property, or env var if that doesn't exist, or command-line arg if that doesn't exist.</cc>
+ <ck>nested</ck> = <cv>$S{mySystemProperty,$E{MY_ENV_VAR,$ARG{0}}}</cv>
- <br><hr>
+ <cc># A POJO with embedded variables</cc>
+ <ck>aBean2</ck> = <cv>{foo:'$ARG{0}',baz:$C{MySection/anInt}}</cv>
+ </p>
+ <p>
+ You're probably wondering "why INI files?"
+ The beauty of these INI files is that they're easy to read and modify, yet sophisticated enough to allow you to
+ store arbitrary-complex data structures and retrieve them as simple values or complex POJOs:
+ </p>
+ <p class='bcode'>
+ <jc>// Load our config file</jc>
+ ConfigFile f = <jk>new</jk> ConfigFileBuilder().build(<js>"MyIniFile.cfg"</js>);
+
+ <jk>int</jk> anInt = cf.getInt(<js>"MySection/anInt"</js>);
+ <jk>boolean</jk> aBoolean = cf.getBoolean(<js>"MySection/aBoolean"</js>);
+ <jk>int</jk>[] anIntArray = cf.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"MySection/anIntArray"</js>);
+ URL aURL = cf.getObject(URL.<jk>class</jk>, <js>"MySection/aURL"</js>);
+ MyBean aBean = cf.getObject(MyBean.<jk>class</jk>, <js>"MySection/aBean"</js>);
+ Locale locale = cf.getObject(Locale.<jk>class</jk>, <js>"MySection/locale"</js>);
+ String path = cf.getString(<js>"MySection/path"</js>);
+ String mainClass = cf.getString(<js>"MySection/mainClass"</js>);
+ <jk>int</jk> sameAsAnInt = cf.getInt(<js>"MySection/sameAsAnInt"</js>);
+ String myArg = cf.getString(<js>"MySection/myArg"</js>);
+ String firstArg = cf.getString(<js>"MySection/firstArg"</js>);
+ </p>
+ <p>
+ By default, values are LAX JSON (i.e. unquoted attributes, single quotes) except for top-level strings which are left unquoted.
+ Any parsable object types are supported as values (e.g. arrays, collections, beans, swappable objects, enums, etc...).
+ </p>
+ <p>
+ One of the more powerful aspects of the REST servlets is that you can pull values directly from
+ config files by using the <js>"$C"</js> variable in annotations.
+ <br>For example, the HTML stylesheet for your REST servlet can be defined in a config file like so:
+ </p>
+ <p class='bcode'>
+ <ja>@RestResource</ja>(
+ path=<js>"/myResource"</js>,
+ config=<js>"$S{my.config.file}"</js>, <jc>// Path to config file (here pulled from a system property)</jc>
+ stylesheet=<js>"$C{MyResourceSettings/myStylesheet}"</js> <jc>// Stylesheet location pulled from config file.</jc>
+ )
+ <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
+ </p>
+ <p>
+ Other features:
+ </p>
+ <ul class='spaced-list'>
+ <li>A listener API that allows you to, for example, reinitialize your REST resource if the config file
+ changes, or listen for changes to particular sections or values.
+ <li>Config files can be modified through the ConfigFile class (e.g. add/remove/modify sections and keys, add/remove comments and whitespace, etc...).
+ <br>When using these APIs, you <b>DO NOT</b> lose formatting in your existing configuration file.
+ All existing whitespace and comments are preserved for you!
+ <li>Config file sections can be used to directly populate beans.
+ <li>Config file sections can be accessed and manipulated through Java interface proxies.
+ </ul>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-config'>juneau-config</a> for more information.
+ </ul>
+ </div>
+
+ </div>
- <h5 class='toc'>Juneau Server</h5>
- <p>
- The REST server API builds upon the <code>SerializerGroup</code> and <code>ParserGroup</code> classes
- to provide annotated REST servlets that automatically negotiate the HTTP media types for you.
- <br>Developers simply work with requests, responses, headers, path variables, query parameters, and form data as POJOs.
- <br>Allows you to create sophisticated REST interfaces using tiny amounts of code.
- </p>
- <p>
- The end goal is to provide simple and flexible yet sophisticated REST interfaces that allow POJOs to be automatically represented as
- different content types depending on whatever the particular need:
- </p>
- <ul class='spaced-list'>
- <li>HTML for viewing POJOs in easy-to-read format in a browser.
- <li>JSON for interacting through Javascript.
- <li>XML for interacting with other applications.
- <li>RDF for interacting with triple stores.
- <li>URL-Encoding for interacting through HTML forms.
- <li>MessagePack for efficiently transmitting large amounts of data.
- </ul>
- <p>
- A simple example that supports all languages:
- </p>
- <p class='bcode'>
+ <!-- =========================================================================================================== -->
+ <!-- === JUNEAU REST =========================================================================================== -->
+ <!-- =========================================================================================================== -->
+
+ <h5 class='toc' id='juneau-rest'>5 - juneau-rest</h5>
+ <div>
+
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-REST-SERVER ================================================================================ -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-rest-server'>5.1 - juneau-rest-server</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-rest-server<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-rest-server-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The REST server API builds upon the <code>SerializerGroup</code> and <code>ParserGroup</code> classes
+ to provide annotated REST servlets that automatically negotiate the HTTP media types for you.
+ <br>Developers simply work with requests, responses, headers, path variables, query parameters, and form data as POJOs.
+ <br>It allows you to create sophisticated REST interfaces using tiny amounts of code.
+ </p>
+ <p>
+ The end goal is to provide simple and flexible yet sophisticated REST interfaces that allow POJOs to be automatically represented as
+ different content types depending on whatever the particular need:
+ </p>
+ <ul class='spaced-list'>
+ <li>HTML for viewing POJOs in easy-to-read format in a browser.
+ <li>JSON for interacting through Javascript.
+ <li>XML for interacting with other applications.
+ <li>RDF for interacting with triple stores.
+ <li>URL-Encoding for interacting through HTML forms.
+ <li>MessagePack for efficiently transmitting large amounts of data.
+ </ul>
+ <p>
+ A simple example that supports all languages:
+ </p>
+ <p class='bcode'>
<ja>@RestResource</ja>(
path=<js>"/systemProperties"</js>,
title=<js>"System properties resource"</js>
@@ -627,18 +1170,19 @@
<jk>return</jk> <js>"OK"</js>;
}
}
- </p>
- <p>
- A more sophisticated example of the same resource using various features, including information
- for fully populating the Swagger documentation, guards for restricting access to particular
- methods, customizing supported content types and serialization options, adding g-zip compression,
- and adding customized branding for the HTML views.
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ A more sophisticated example of the same resource using various features, including information
+ for fully populating the Swagger documentation, guards for restricting access to particular
+ methods, customizing supported content types and serialization options, adding g-zip compression,
+ and adding customized branding for the HTML views.
+ </p>
+ <p class='bcode'>
<ja>@RestResource</ja>(
path=<js>"/systemProperties"</js>,
title=<js>"System properties resource"</js>,
description=<js>"REST interface for performing CRUD operations on system properties."</js>,
+ messages=<js>"nls/SystemPropertiesResource"</js>, <jc>// Location of localized messages.</jc>
<jc>// Widget used for content-type pull-down menu.</jc>
widgets={
@@ -680,7 +1224,7 @@
<jc>// Add compression support.</jc>
encoders=GzipEncoder.<jk>class</jk>,
- <jc>// Augment Swagger information.</jc>
+ <jc>// Augment generated Swagger information.</jc>
swagger=<ja>@ResourceSwagger</ja>(
contact=<js>"{name:'John Smith',email:'john@smith.com'}"</js>,
license=<js>"{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>,
@@ -697,7 +1241,7 @@
summary=<js>"Show all system properties"</js>,
description=<js>"Returns all system properties defined in the JVM."</js>,
- <jc>// Augment Swagger information.</jc>
+ <jc>// Augment generated Swagger information.</jc>
swagger=<ja>@MethodSwagger</ja>(
parameters={
<ja>@Parameter</ja>(in=<js>"query"</js>, name=<js>"sort"</js>, description=<js>"Sort results alphabetically."</js>, _default=<js>"false"</js>)
@@ -715,18 +1259,18 @@
...
}
- </p>
-
- <p>
- In HTML, our resource looks like this:
- </p>
- <img class='bordered' src='images/SystemPropertiesResource.png' width="800px">
-
- <p>
- When combined with the support for HTML5 beans, simple HTML forms can be constructed for easy input and output
- using nothing more than Java:
- </p>
- <p class='bcode'>
+ </p>
+
+ <p>
+ In HTML, our resource looks like this:
+ </p>
+ <img class='bordered' src='images/SystemPropertiesResource.png' width="800px">
+
+ <p>
+ When combined with the support for HTML5 beans, simple HTML forms can be constructed for easy input and output
+ using nothing more than Java:
+ </p>
+ <p class='bcode'>
<jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*;
<ja>@RestMethod</ja>(
@@ -737,10 +1281,18 @@
)
<jk>public</jk> Form getFormPage() {
<jk>return</jk> <jsm>form</jsm>().method(<js>"POST"</js>).action(<js>"formPagePost"</js>).children(
- <jsm>h4</jsm>(<js>"Set system property"</js>),
- <js>"Name: "</js>, <jsm>input</jsm>(<js>"text"</js>).name(<js>"name"</js>), <jsm>br</jsm>(),
- <js>"Value: "</js>, <jsm>input</jsm>(<js>"text"</js>).name(<js>"value"</js>), <jsm>br</jsm>(), <jsm>br</jsm>(),
- <jsm>button</jsm>(<js>"submit","Click me!"</js>).style(<js>"float:right"</js>)
+ <jsm>table</jsm>(
+ <jsm>tr</jsm>(
+ <jsm>th</jsm>(<js>"Set system property"</js>).colspan(2)
+ ),
+ <jsm>tr</jsm>(
+ <jsm>td</jsm>(<js>"Name: "</js>), <jsm>td</jsm>(<jsm>input</jsm>(<js>"text"</js>).name(<js>"name"</js>))
+ ),
+ <jsm>tr</jsm>(
+ <jsm>td</jsm>(<js>"Value: "</js>), <jsm>td</jsm>(<jsm>input</jsm>(<js>"text"</js>).name(<js>"value"</js>))
+ )
+ ),
+ <jsm>button</jsm>(<js>"submit"</js>,<js>"Click me!"</js>).<jsm>style</jsm>(<js>"float:right"</js>)
);
}
@@ -753,44 +1305,44 @@
System.<jsm>setProperty</jsm>(name, value);
<jk>return new</jk> Redirect(<js>"servlet:/"</js>); <jc>// Redirect to the servlet top page.</jc>
}
- </p>
- <img class='bordered' src='images/SystemPropertiesForm.png'>
- <p>
- The REST API is built on top of Servlets, making them easy to deploy in any JEE environment.
- </p>
- <p>
- REST Java methods can return any of the following objects:
- <br>POJOs, <code>Readers</code>, <code>InputStreams</code>, <code>ZipFiles</code>, <code>Redirects</code>, <code>Streamables</code>, and <code>Writables</code>.
- </p>
- <p>
- Or add your own handlers for other types.
- </p>
- <p>
- REST Java methods can be passed any of the following objects in any order:
- </p>
- <ul class='spaced-list'>
- <li>Low-level request/response objects:
- <br><code>HttpServletRequest</code>, <code>HttpServletResponse</code>, <code>RestRequest</code>, <code>RestResponse</code>.
- <li>Intermediate-level objects:
- <br><code>RequestHeaders</code>, <code>RequestQuery</code>, <code>RequestFormData</code>, <code>RequestPathMatch</code>, <code>RequestBody</code>.
- <li>All RFC 2616 request header objects:
- <br><code>Accept</code>, <code>AcceptLanguage</code>, <code>AcceptEncoding</code>...
- <li>Annotated parameters:
- <br><ja>@Header</ja>, <ja>@Query</ja>, <ja>@FormData</ja>, <ja>@Path</ja>, <ja>@PathRemainder</ja>, <ja>@Body</ja>.
- <li>Other objects:
- <br><code>Locale</code>, <code>ResourceBundle</code>, <code>MessageBundle</code>, <code>InputStream</code>, <code>OutputStream</code>, <code>Reader</code>, <code>Writer</code>...
- <li>User-defined parameter types.
- </ul>
- <p>
- It's up to you how you want to define your REST methods.
- As a general rule, there are 3 broad approaches typically used:
- </p>
-
- <h5 class='topic'>Methodology #1 - Annoted parameters</h5>
- <p>
- This approach uses annotated parameters for retrieving input from the request.
- </p>
- <p class='bcode'>
+ </p>
+ <img class='bordered' src='images/SystemPropertiesForm.png' width="800px">
+ <p>
+ The REST API is built on top of Servlets, making them easy to deploy in any JEE environment.
+ </p>
+ <p>
+ REST Java methods can return any of the following objects:
+ <br>POJOs, <code>Readers</code>, <code>InputStreams</code>, <code>ZipFiles</code>, <code>Redirects</code>, <code>Streamables</code>, and <code>Writables</code>.
+ </p>
+ <p>
+ Or add your own handlers for other types.
+ </p>
+ <p>
+ REST Java methods can be passed any of the following objects in any order:
+ </p>
+ <ul class='spaced-list'>
+ <li>Low-level request/response objects:
+ <br><code>HttpServletRequest</code>, <code>HttpServletResponse</code>, <code>RestRequest</code>, <code>RestResponse</code>.
+ <li>Intermediate-level objects:
+ <br><code>RequestHeaders</code>, <code>RequestQuery</code>, <code>RequestFormData</code>, <code>RequestPathMatch</code>, <code>RequestBody</code>.
+ <li>All RFC 2616 request header objects:
+ <br><code>Accept</code>, <code>AcceptLanguage</code>, <code>AcceptEncoding</code>...
+ <li>Annotated parameters:
+ <br><ja>@Header</ja>, <ja>@Query</ja>, <ja>@FormData</ja>, <ja>@Path</ja>, <ja>@PathRemainder</ja>, <ja>@Body</ja>.
+ <li>Other objects:
+ <br><code>Locale</code>, <code>ResourceBundle</code>, <code>MessageBundle</code>, <code>InputStream</code>, <code>OutputStream</code>, <code>Reader</code>, <code>Writer</code>...
+ <li>User-defined parameter types.
+ </ul>
+ <p>
+ It's up to you how you want to define your REST methods.
+ As a general rule, there are 3 broad approaches typically used:
+ </p>
+
+ <h5 class='topic'>Methodology #1 - Annotated parameters</h5>
+ <p>
+ This approach uses annotated parameters for retrieving input from the request.
+ </p>
+ <p class='bcode'>
<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example1/{p1}/{p2}/{p3}/*"</js>)
<jk>public</jk> String example1(
<ja>@Method</ja> String method, <jc>// HTTP method.</jc>
@@ -812,13 +1364,13 @@
method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack);
<jk>return</jk> output;
}
- </p>
-
- <h5 class='topic'>Methodology #2 - Low-level request/response objects</h5>
- <p>
- This approach uses low-level request/response objects to perform the same as above.
- </p>
- <p class='bcode'>
+ </p>
+
+ <h5 class='topic'>Methodology #2 - Low-level request/response objects</h5>
+ <p>
+ This approach uses low-level request/response objects to perform the same as above.
+ </p>
+ <p class='bcode'>
<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example2/{p1}/{p2}/{p3}/*"</js>)
<jk>public</jk> String example2(
RestRequest req, <jc>// A direct subclass of HttpServletRequest.</jc>
@@ -854,13 +1406,13 @@
method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack);
res.setOutput(output); <jc>// Or use getWriter().</jc>
}
- </p>
-
- <h5 class='topic'>Methodology #3 - Intermediate-level API objects</h5>
- <p>
- This approach is sort of the middle ground where you get access functional area APIs.
- </p>
- <p class='bcode'>
+ </p>
+
+ <h5 class='topic'>Methodology #3 - Intermediate-level API objects</h5>
+ <p>
+ This approach is sort of the middle ground where you get access functional area APIs.
+ </p>
+ <p class='bcode'>
<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example3/{p1}/{p2}/{p3}/*"</js>)
<jk>public</jk> String example3(
HttpMethod method, <jc>// HTTP method.</jc>
@@ -893,19 +1445,19 @@
method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack);
res.setOutput(output);
}
- </p>
- <p>
- All three are completely equivalent. It's up to your own coding preferences which methodology you use.
- </p>
- <br><hr>
- <p>
- Lifecycle hooks allow you to hook into lifecycle events of the servlet or REST call.
- Like <ja>@RestMethod</ja> methods, the list of parameters are specified by the developer.
- </p>
- <p>
- For example, if you want to add an initialization method to your resource:
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ All three are completely equivalent. It's up to your own coding preferences which methodology you use.
+ </p>
+ <br><hr>
+ <p>
+ Lifecycle hooks allow you to hook into lifecycle events of the servlet or REST call.
+ Like <ja>@RestMethod</ja> methods, the list of parameters are specified by the developer.
+ </p>
+ <p>
+ For example, if you want to add an initialization method to your resource:
+ </p>
+ <p class='bcode'>
<ja>@RestResource</ja>(...)
<jk>public class</jk> MyResource {
@@ -917,11 +1469,11 @@
<jf>myDatabase</jf> = <jk>new</jk> LinkedHashMap<>();
}
}
- </p>
- <p>
- Or if you want to intercept REST calls:
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ Or if you want to intercept REST calls:
+ </p>
+ <p class='bcode'>
<ja>@RestResource</ja>(...)
<jk>public class</jk> MyResource {
@@ -931,52 +1483,52 @@
req.setAttribute(<js>"foo"</js>, <js>"bar"</js>);
}
}
- </p>
- <p>
- The hook events can be broken down into two categories:
- </p>
- <ul class='spaced-list'>
- <li>Resource lifecycle events:
- <ul>
- <li><jsf>INIT</jsf> - Right before initialization.
- <li><jsf>POST_INIT</jsf> - Right after initialization.
- <li><jsf>POST_INIT_CHILD_FIRST</jsf> - Right after initialization, but run child methods first.
- <li><jsf>DESTROY</jsf> - Right before servlet destroy.
- </ul>
- <li>REST call lifecycle events:
- <ul>
- <li><jsf>START_CALL</jsf> - At the beginning of a REST call.
- <li><jsf>PRE_CALL</jsf> - Right before the <ja>@RestMethod</ja> method is invoked.
- <li><jsf>POST_CALL</jsf> - Right after the <ja>@RestMethod</ja> method is invoked.
- <li><jsf>END_CALL</jsf> - At the end of the REST call after the response has been flushed.
+ </p>
+ <p>
+ The hook events can be broken down into two categories:
+ </p>
+ <ul class='spaced-list'>
+ <li>Resource lifecycle events:
+ <ul>
+ <li><jsf>INIT</jsf> - Right before initialization.
+ <li><jsf>POST_INIT</jsf> - Right after initialization.
+ <li><jsf>POST_INIT_CHILD_FIRST</jsf> - Right after initialization, but run child methods first.
+ <li><jsf>DESTROY</jsf> - Right before servlet destroy.
+ </ul>
+ <li>REST call lifecycle events:
+ <ul>
+ <li><jsf>START_CALL</jsf> - At the beginning of a REST call.
+ <li><jsf>PRE_CALL</jsf> - Right before the <ja>@RestMethod</ja> method is invoked.
+ <li><jsf>POST_CALL</jsf> - Right after the <ja>@RestMethod</ja> method is invoked.
+ <li><jsf>END_CALL</jsf> - At the end of the REST call after the response has been flushed.
+ </ul>
</ul>
- </ul>
- <br><hr>
- <p>
- Auto-generated OPTIONS pages are constructed from Swagger DTO beans, here shown serialized as HTML:
- </p>
- <img class='bordered' src='images/Swagger.png'>
- <p>
- Swagger documentation can be populated from annotations (as above), resource bundles, or Swagger JSON files.
- </p>
- <p>
- The page shown above is implemented on the RestServletDefault class in the method below which shows that it's doing nothing more than
- serializing a Swagger bean which is constructed in the RestRequest object:
- </p>
- <p class='bcode'>
+ <br><hr>
+ <p>
+ Auto-generated OPTIONS pages are constructed from Swagger DTO beans, here shown serialized as HTML:
+ </p>
+ <img class='bordered' src='images/Swagger.png' width="800px">
+ <p>
+ Swagger documentation can be populated from annotations (as above), resource bundles, or Swagger JSON files.
+ </p>
+ <p>
+ The page shown above is implemented on the RestServletDefault class in the method below which shows that it's doing nothing more than
+ serializing a Swagger bean which is constructed in the RestRequest object:
+ </p>
+ <p class='bcode'>
<ja>@RestMethod</ja>(name=<js>"OPTIONS"</js>, path=<js>"/*"</js>)
<jk>public</jk> Swagger getOptions(RestRequest req) {
<jk>return</jk> req.getSwagger();
}
- </p>
- <br><br><hr>
- <p>
- Navigatable hierarchies of REST resources are easy to set up either programmatically or through annotations.
- <br>
- The following example is the <code>RootResources</code> class from the REST examples showing how to construct
- a grouping of resources using the <code>children()</code> annotation:
- </p>
- <p class='bcode'>
+ </p>
+ <br><br><hr>
+ <p>
+ Navigable hierarchies of REST resources are easy to set up either programmatically or through annotations.
+ <br>
+ The following example is the <code>RootResources</code> class from the REST examples showing how to construct
+ a grouping of resources using the <code>children()</code> annotation:
+ </p>
+ <p class='bcode'>
<ja>@RestResource</ja>(
path=<js>"/"</js>,
title=<js>"Root resources"</js>,
@@ -1026,31 +1578,31 @@
}
)
<jk>public class</jk> RootResources <jk>extends</jk> RestServletGroupDefault { <jc>/* No code needed! */</jc> }
- </p>
- <p>
- The above resource when rendered in HTML shows how easy it is to discover and navigate to child resources using a browser:
- </p>
- <img class='bordered' src='images/Samples_RootResources.png'>
- <p>
- Resources can be nested arbitrarily deep.
- The <ja>@RestResource</ja> and <ja>@RestMethod</ja> annotations can be applied to any classes, not just
- servlets. The only requirement is that the top-level resource be a subclass of <code>RestServlet</code> as a hook into
- the servlet container.
- </p>
-
- <p>
- The <code>juneau-examples-rest</code> project includes various other examples that highlight some of the
- capabilities of the REST servlet API.
- <br>
- For example, the <code>PetStoreResource</code> class shows some advanced features such as using POJO renders
- and converters, and HTML widgets.
- </p>
- <img class='bordered' src='images/PetStore.png'>
-
- <p>
- The beans being serialized are shown here:
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ The above resource when rendered in HTML shows how easy it is to discover and navigate to child resources using a browser:
+ </p>
+ <img class='bordered' src='images/Samples_RootResources.png' width="800px">
+ <p>
+ Resources can be nested arbitrarily deep.
+ The <ja>@RestResource</ja> and <ja>@RestMethod</ja> annotations can be applied to any classes, not just
+ servlets. The only requirement is that the top-level resource be a subclass of <code>RestServlet</code> as a hook into
+ the servlet container.
+ </p>
+
+ <p>
+ The <code>juneau-examples-rest</code> project includes various other examples that highlight some of the
+ capabilities of the REST servlet API.
+ <br>
+ For example, the <code>PetStoreResource</code> class shows some advanced features such as using POJO renders
+ and converters, and HTML widgets.
+ </p>
+ <img class='bordered' src='images/PetStore.png' width="1000px">
+
+ <p>
+ The beans being serialized are shown here:
+ </p>
+ <p class='bcode'>
<jc>// Our bean class.</jc>
<jk>public class</jk> Pet {
@@ -1089,22 +1641,22 @@
<jk>return</jk> <js>"background-color:#FDF2E9"</js>;
}
}
- </p>
-
- <p>
- The <code>QUERY</code> menu item shows the capabilities of Converters which are post-processors that
- work to filter POJOs after they've been returned by your Java method.
- <br>
- In this case, we're using the <code>Queryable</code> converter that allows us to perform search/view/sort/paging
- against collections of beans:
- </p>
- <img class='bordered' src='images/PetStore_Query.png'>
-
- <p>
- The drop-down menu items are implemented through "widgets" which allow you to embed arbitrary HTML, Javascript,
- and CSS in the HTML view of the page.
- </p>
- <p class='bcode'>
+ </p>
+
+ <p>
+ The <code>QUERY</code> menu item shows the capabilities of Converters which are post-processors that
+ work to filter POJOs after they've been returned by your Java method.
+ <br>
+ In this case, we're using the <code>Queryable</code> converter that allows us to perform search/view/sort/paging
+ against collections of beans:
+ </p>
+ <img class='bordered' src='images/PetStore_Query.png' width="1000px">
+
+ <p>
+ The drop-down menu items are implemented through "widgets" which allow you to embed arbitrary HTML, Javascript,
+ and CSS in the HTML view of the page.
+ </p>
+ <p class='bcode'>
<ja>@RestMethod</ja>(
name=<js>"GET"</js>,
path=<js>"/"</js>,
@@ -1133,56 +1685,116 @@
)
)
<jk>public</jk> Collection<Pet> getPets() {
- </p>
-
- <p>
- HTML views are highly customizable with abilities such as defining your own look-and-feel and even allowing
- you to define your own templates.
- </p>
- <p>
- For example, the PetStore page above rendered in one of the other predefined stylesheets:
- </p>
- <img class='bordered' src='images/PetStore_light.png'>
- <br><hr>
- <p>
- Automatic error handling is provided for a variety of conditions:
- </p>
- <ul>
- <li>Automatic 401 errors (Unauthorized) on failed guards.
- <li>Automatic 404 errors (Not Found) on unmatched path patterns.
- <li>Automatic 405 errors (Method Not Implemented) on unimplemented methods.
- <li>Automatic 406 errors (Not Acceptable) when no matching serializer was found to handle the <l>Accept</l> header.
- <li>Automatic 412 errors (Precondition Failed) when all matchers failed to match.
- <li>Automatic 415 errors (Unsupported Media Type) when no matching parser was found was found to handle the <l>Content-Type</l> header.
- <li>Automatic 500 errors on uncaught exceptions.
- <li>Throw your own runtime RestException with HTTP status and response object.
- </ul>
- <p>
- Other features include:
- </p>
- <ul>
- <li>Extremely simple debuggability using nothing more than your browser.
- <li>Simplified localization support.
- <li>Configurability through external INI files.
- <li>Client-versioned responses (and other customizable heuristic matching APIs).
- <li>Define and use your own HTML stylesheets.
- <li>Optional JAX-RS integration.
- <li>Lots of up-to-date documentation and examples.
- <li>MUCH MORE!....
- </ul>
+ </p>
+
+ <p>
+ HTML views are highly customizable with abilities such as defining your own look-and-feel and even allowing
+ you to define your own templates.
+ </p>
+ <p>
+ For example, the PetStore page above rendered in one of the other predefined stylesheets:
+ </p>
+ <img class='bordered' src='images/PetStore_light.png'>
+ <br><hr>
+ <p>
+ Automatic error handling is provided for a variety of conditions:
+ </p>
+ <ul>
+ <li>Automatic 401 errors (Unauthorized) on failed guards.
+ <li>Automatic 404 errors (Not Found) on unmatched path patterns.
+ <li>Automatic 405 errors (Method Not Implemented) on unimplemented methods.
+ <li>Automatic 406 errors (Not Acceptable) when no matching serializer was found to handle the <l>Accept</l> header.
+ <li>Automatic 412 errors (Precondition Failed) when all matchers failed to match.
+ <li>Automatic 415 errors (Unsupported Media Type) when no matching parser was found was found to handle the <l>Content-Type</l> header.
+ <li>Automatic 500 errors on uncaught exceptions.
+ <li>Throw your own runtime RestException with HTTP status and response object.
+ </ul>
+ <p>
+ Other features include:
+ </p>
+ <ul class='spaced-list'>
+ <li>Extremely simple debuggability using nothing more than your browser.
+ <li>Simplified localization support.
+ <li>Configurability through external INI files.
+ <li>Client-versioned responses (and other customizable heuristic matching APIs).
+ <li>Define and use your own HTML stylesheets.
+ <li>Lots of up-to-date documentation and examples.
+ <li>MUCH MORE!....
+ </ul>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Server'>Juneau Server</a> for more information.
+ </ul>
+ </div>
- <h5 class='topic'>Additional Information</h5>
- <ul class='doctree'>
- <li class='link'><a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Server'>Juneau Server (org.apache.juneau.rest)</a>
- </ul>
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-REST-SERVER-JAXRS ========================================================================== -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-rest-server-jaxrs'>5.2 - juneau-rest-server-jaxrs</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-rest-server-jaxrs<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-rest-server-jaxrs-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The <code>juneau-rest-server-jaxrs</code> module defines predefined <code>MessageBodyReader</code> and
+ <code>MessageBodyWriter</code> implementations for using Juneau serializers and parsers in JAX-RS environments.
+ It consists of the following classes:
+ </p>
+ <ul class='spaced-list'>
+ <li>
+ <code>org.apache.juneau.rest.jaxrs.BaseProvider</code> - The base provider class that implements the JAX-RS
+ <code>MessageBodyReader</code> and <code>MessageBodyWriter</code> interfaces.
+ <li>
+ <code>org.apache.juneau.rest.jaxrs.JuneauProvider</code> - Annotation that is applied to subclasses of <code>BaseProvider</code>
+ to specify the serializers/parsers associated with a provider, and optionally filters and properties to
+ apply to those serializers and parsers.
+ <li>
+ <code>org.apache.juneau.rest.jaxrs.DefaultProvider</code> - A default provider that provides the same level
+ of media type support as the <code>RestServletDefault</code> class.
+ </ul>
- <br><hr>
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-rest-server-jaxrs'>juneau-rest-server-jaxrs</a> for more information.
+ </ul>
- <h5 class='toc'>Juneau Client</h5>
- <p>
- The REST client API allows you to access REST interfaces using POJOs as well:
- </p>
- <p class='bcode'>
+ </div>
+
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-REST-CLIENT ================================================================================ -->
+ <!-- ======================================================================================================= -->
+
+ <h6 class='toc' id='juneau-rest-client'>5.3 - juneau-rest-client</h6>
+ <div>
+ <h6 class='figure'>Maven Dependency</h6>
+ <p class='bcode'>
+ <<xt>dependency</xt>>
+ <<xt>groupId</xt>>org.apache.juneau<<xt>/groupId</xt>>
+ <<xt>artifactId</xt>>juneau-rest-client<<xt>/artifactId</xt>>
+ <<xt>version</xt>>6.4.0-incubating<<xt>/version</xt>>
+ <<xt>/dependency</xt>>
+ </p>
+
+ <h6 class='figure'>OSGi Module</h6>
+ <p class='bcode'>
+ juneau-rest-client-6.4.0-incubating.jar
+ </p>
+
+ <p>
+ The REST client API allows you to access REST interfaces using POJOs:
+ </p>
+ <p class='bcode'>
<jc>// Create a reusable JSON client.</jc>
RestClient client = <jk>new</jk> RestClientBuilder().build();
@@ -1199,15 +1811,15 @@
Properties p = <jk>new</jk> Properties();
p.load(reader);
<jk>int</jk> returnCode = client.doPost(url + <js>"/systemProperties"</js>, p).execute();
- </p>
- <p>
- The client API uses the same serializers and parsers (and subsequently their flexibilty and configurability) as the server side to marshall POJOs back and forth.
- </p>
- <br><hr>
- <p>
- The remote proxy interface API allows you to invoke server-side POJO methods on the client side using REST (i.e. RPC over REST):
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ The client API uses the same serializers and parsers (and subsequently their flexibility and configurability) as the server side to marshall POJOs back and forth.
+ </p>
+ <br><hr>
+ <p>
+ The remote proxy interface API allows you to invoke server-side POJO methods on the client side using REST (i.e. RPC over REST):
+ </p>
+ <p class='bcode'>
<jc>// Get an interface proxy.</jc>
IAddressBook ab = restClient.getRemoteableProxy(IAddressBook.<jk>class</jk>);
@@ -1219,19 +1831,20 @@
<jk>new</jk> Address(<js>"My street"</js>, <js>"My city"</js>, <js>"My state"</js>, 12345, <jk>true</jk>)
)
);
- </p>
- <p>
- There are two ways to expose remoteable proxies on the server side:
- </p>
- <ol>
- <li>Extending from <code>RemoteableServlet</code>.
- <li>Using a <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code> annotation on a Java method.
- </ol>
- <p>
- The <code>RemoteableServlet</code> class is a simple specialized servlet with an abstract <code>getServiceMap()</code>
- method to define the server-side POJOs:
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ Although the client API is not dependent on the <code>juneau-rest-server</code> module, the server
+ module provides some convenience APIs for exposing remoteable proxies on the server side:
+ </p>
+ <ol>
+ <li>Extending from <code>RemoteableServlet</code>.
+ <li>Using a <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code> annotation on a Java method.
+ </ol>
+ <p>
+ The <code>RemoteableServlet</code> class is a simple specialized servlet with an abstract <code>getServiceMap()</code>
+ method to define the server-side POJOs:
+ </p>
+ <p class='bcode'>
<ja>@RestResource</ja>(
path=<js>"/remote"</js>
)
@@ -1252,203 +1865,121 @@
<jk>return</jk> m;
}
}
- </p>
- <p>
- The <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code> approach is easier if you only have a single interface you want to expose.
- You simply define a Java method whose return type is an interface, and return the implementation of that interface:
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ The <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code> approach is easier if you only have a single interface you want to expose.
+ You simply define a Java method whose return type is an interface, and return the implementation of that interface:
+ </p>
+ <p class='bcode'>
<jc>// Our exposed proxy object.</jc>
<ja>@RestMethod</ja>(name=<js>"PROXY"</js>, path=<js>"/addressbookproxy/*"</js>)
<jk>public</jk> IAddressBook getProxy() {
<jk>return</jk> addressBook;
}
- </p>
- <p>
- In either case, the proxy communications layer is pure REST.
- Parameters passed in on the client side are serialized as an HTTP POST, parsed on the
- server side, and then passed to the invocation method. The returned POJO is then marshalled back as an HTTP response.
- </p>
- <p>
- In most cases, you'll want to use JSON or MessagePack as your communications layer since these are the most efficent.
- Although remoteable proxies work perfectly well for any of the other supported languages. For example, RPC over Turtle!
- </p>
- <p>
- The parameters and return types of the Java methods can be any of the supported serializable and parsable types in <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Core.PojoCategories'>POJO Categories</a>.
- This ends up being WAY more flexible than other proxy interfaces since Juneau can handle so may POJO types out-of-the-box.
- Most of the time you don't even need to modify your existing Java implementation code.
- </p>
- <p>
- The RemoteableServlet class itself shows how sophisticated REST interfaces can be built on the Juneau RestServlet
- API using very little code. The RemoteableServlet class itself consists of only 53 lines of code, yet is
- a sophisticated discoverable and self-documenting REST interface. And since the remote proxy API is built on top
- of REST, it can be debugged using just a browser.
- </p>
- <br><hr>
- <p>
- Remoteable proxies can also be used to define interface proxies against 3rd-party REST interfaces.
- This is an extremely powerful feature that allows you to quickly define easy-to-use interfaces against virtually any REST interface.
- </p>
- <p>
- Similar in concept to remoteable services defined above, but in this case we simply define our interface with
- special annotations that tell us how to convert input and output to HTTP headers, query parameters, form post parameters, or request/response bodies.
- </p>
- <p class='bcode'>
+ </p>
+ <p>
+ In either case, the proxy communications layer is pure REST.
+ Parameters passed in on the client side are serialized as an HTTP POST, parsed on the
+ server side, and then passed to the invocation method. The returned POJO is then marshalled back as an HTTP response.
+ </p>
+ <p>
+ In most cases, you'll want to use JSON or MessagePack as your communications layer since these are the most efficient.
+ Although remoteable proxies work perfectly well for any of the other supported languages. For example, RPC over Turtle!
+ </p>
+ <p>
+ The parameters and return types of the Java methods can be any of the supported serializable and parsable types in <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-marshall.PojoCategories'>POJO Categories</a>.
+ This ends up being WAY more flexible than other proxy interfaces since Juneau can handle so may POJO types out-of-the-box.
+ Most of the time you don't even need to modify your existing Java implementation code.
+ </p>
+ <p>
+ The <code>RemoteableServlet</code> class itself shows how sophisticated REST interfaces can be built on the Juneau REST Servlet
+ API using very little code.
+ The class consists of only 53 lines of code, yet is a sophisticated discoverable and self-documenting REST interface.
+ And since the remote proxy API is built on top of REST, it can be debugged using just a browser.
+ </p>
+ <br><hr>
+ <p>
+ Remoteable proxies can also be used to define interface proxies against 3rd-party REST interfaces.
+ This is an extremely powerful feature that allows you to quickly define easy-to-use interfaces against virtually any REST interface.
+ </p>
+ <p>
+ Similar in concept to remoteable services defined above, but in this case we simply define our interface with
+ special annotations that tell us how to convert input and output to HTTP headers, query parameters, form post parameters, or request/response bodies.
+ </p>
+ <p class='bcode'>
<ja>@Remoteable</ja>
<jk>public interface</jk> MyProxyInterface {
<ja>@RemoteMethod</ja>(httpMethod=<js>"POST"</js>, path=<js>"/method"</js>)
- String doMethod(<ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag, <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug, <ja>@Body</ja> MyPojo pojo);
+ String doSomething(<ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag, <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug, <ja>@Body</ja> MyPojo pojo);
}
- RestClient client = <jk>new</jk> RestClientBuilder().build();
+ RestClient client = <jk>new</jk> RestClientBuilder().build(); <jc>// Default is JSON</jc>
MyProxyInterface p = client.getRemoteableProxy(MyProxyInterface.<jk>class</jk>, <js>"http://hostname/some/rest/interface"</js>);
- String response = p.doMethod(UUID.<jsm>generate</jsm>(), <jk>true</jk>, <jk>new</jk> MyPojo());
- </p>
-
- <h5 class='topic'>Additional Information</h5>
- <ul class='doctree'>
- <li class='link'><a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Client'>Juneau Client (org.apache.juneau.rest.client)</a>
- </ul>
-
- <br><hr>
+ String response = p.doSomething(UUID.<jsm>generate</jsm>(), <jk>true</jk>, <jk>new</jk> MyPojo());
+ </p>
+
+ <ul class='doctree'>
+ <li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-rest-client'>juneau-rest-client</a> for more information.
+ </ul>
+ </div>
+ </div>
- <h5 class='toc'>Config</h5>
- <p>
- The config file API allows you to interact with INI files using POJOs.
- A sophisticated variable language is provided for referencing environment variables, system properties, other config file entries, and a host of other types.
- <p>
- <p class='bcode'>
- <cc>#--------------------------</cc>
- <cc># My section</cc>
- <cc>#--------------------------</cc>
- <cs>[MySection]</cs>
-
- <cc># An integer</cc>
- <ck>anInt</ck> = <cv>1</cv>
-
- <cc># A boolean</cc>
- <ck>aBoolean</ck> = <cv>true</cv>
-
- <cc># An int array</cc>
- <ck>anIntArray</ck> = <cv>[1,2,3]</cv>
-
- <cc># A POJO that can be converted from a String</cc>
- <ck>aURL</ck> = <cv>http://foo </cv>
-
- <cc># A POJO that can be converted from JSON</cc>
- <ck>aBean</ck> = <cv>{foo:'bar',baz:123}</cv>
-
- <cc># A system property</cc>
- <ck>locale</ck> = <cv>$S{java.locale, en_US}</cv>
-
- <cc># An environment variable</cc>
- <ck>path</ck> = <cv>$E{PATH, unknown}</cv>
-
- <cc># A manifest file entry</cc>
- <ck>mainClass</ck> = <cv>$MF{Main-Class}</cv>
+ <!-- =========================================================================================================== -->
+ <!-- === JUNEAU MICROSERVICE =================================================================================== -->
+ <!-- =========================================================================================================== -->
- <cc># Another value in this config file</cc>
- <ck>sameAsAnInt</ck> = <cv>$C{MySection/anInt}</cv>
-
- <cc># A command-line argument in the form "myarg=foo"</cc>
- <ck>myArg</ck> = <cv>$ARG{myarg}</cv>
-
- <cc># The first command-line argument</cc>
- <ck>firstArg</ck> = <cv>$ARG{0}</cv>
-
- <cc># Look for system property, or env var if that doesn't exist, or command-line arg if that doesn't exist.</cc>
- <ck>nested</ck> = <cv>$S{mySystemProperty,$E{MY_ENV_VAR,$ARG{0}}}</cv>
+ <h5 class='toc' id='juneau-microservice'>6 - juneau-microservice</h5>
+ <div>
- <cc># A POJO with embedded variables</cc>
- <ck>aBean2</ck> = <cv>{foo:'$ARG{0}',baz:$C{MySection/anInt}}</cv>
- </p>
- <p>
- You're probably wondering "why INI files?"
- The beauty of these INI files is that they're easy to read and modify, yet sophisticated enough to allow you to
- store arbitrary-complex data structures and retrieve them as simple values or complex POJOs:
- </p>
- <p class='bcode'>
- <jc>// Load our config file</jc>
- ConfigFile f = <jk>new</jk> ConfigFileBuilder().build(<js>"MyIniFile.cfg"</js>);
+ <!-- ======================================================================================================= -->
+ <!-- === JUNEAU-MICROSERVICE-SERVER ======================================================================== -->
+ <!-- ======================================================================================================= -->
- <jk>int</jk> anInt = cf.getInt(<js>"MySection/anInt"</js>);
- <jk>boolean</jk> aBoolean = cf.getBoolean(<js>"MySection/aBoolean"</js>);
- <jk>int</jk>[] anIntArray = cf.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"MySection/anIntArray"</js>);
- URL aURL = cf.getObject(URL.<jk>class</jk>, <js>"MySection/aURL"</js>);
- MyBean aBean = cf.getObject(MyBean.<jk>class</jk>, <js>"MySection/aBean"</js>);
- Locale locale = cf.getObject(Locale.<jk>class</jk>, <js>"MySection/locale"</js>);
- String path = cf.getString(<js>"MySection/path"</js>);
- String mainClass = cf.getString(<js>"MySection/mainClass"</js>);
- <jk>int</jk> sameAsAnInt = cf.getInt(<js>"MySection/sameAsAnInt"</js>);
- String myArg = cf.getString(<js>"MySection/myArg"</js>);
- String firstArg = cf.getString(<js>"MySection/firstArg"</js>);
- </p>
- <p>
- Values are LAX JSON (i.e. unquoted attributes, single quotes) except for top-level strings which are left unquoted.
- Any parsable object types are supported as values (e.g. arrays, collections, beans, swappable objects, enums, etc...).
- </p>
- <p>
- One of the more powerful aspects of the REST servlets is that you can pull values directly from
- config files by using the <js>"$C"</js> variable in annotations.
- <br>For example, the HTML stylesheet for your REST servlet can be defined in a config file like so:
- </p>
- <p class='bcode'>
- <ja>@RestResource</ja>(
- path=<js>"/myResource"</js>,
- config=<js>"$S{my.config.file}"</js>, <jc>// Path to config file (here pulled from a system property)</jc>
- stylesheet=<js>"$C{MyResourceSettings/myStylesheet}"</js> <jc>// Stylesheet location pulled from config file.</jc>
- )
- <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
- </p>
- <p>
- Other features:
- </p>
- <ul>
- <li>A listener API that allows you to, for example, reinitialize your REST resource if the config file
- changes, or listen for changes to particular sections or values.
- <li>Config files can be modified through the ConfigFile class (e.g. add/remove/modify sections and keys, add/remove comments and whitespace, etc...).
- <br>When using these APIs, you <b>DO NOT</b> lose formatting in your existing configuration file.
- All existing whitespace and comments are preserved for you!
- <li>Config file sections can be used to directly populate beans.
- <li>Config file sections can be accessed and manipulated through Java interface proxies.
- </ul>
-
- <h5 class='topic'>Additional Information</h5>
- <ul class='doctree'>
- <li class='link'><a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#Core.ConfigFile'>Configuration Files</a>
- </ul>
-
- <br><hr>
-
- <h5 class='toc'>Juneau Microservice</h5>
- <p>
- The microservice API combines all the features above with a built-in Jetty server to produce a lightweight
- REST service packaged as three simple files:
- </p>
- <ul>
- <li>An executable jar file that starts up a REST interface in milliseconds.
- <li>A configurable <code>jetty.xml</code> file.
- <li>An external INI file that can be used to configure your REST resources on the fly.
- </ul>
- <p>
- The microservice API was originally designed for and particularly suited for use in Docker containers.
- </p>
- <p>
- REST microservices can also be started programmatically in existing code:
- </p>
- <p class='bcode'>
+ <h6 class='toc' id='juneau-microservice-server'>6.1 - juneau-microservice-server</h6>
+ <div>
+
+ <h6 class='figure'>Maven Dependency</h6>
+ <p
<TRUNCATED>