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:d...@juneau.apache.org?Subject=Apache%20Juneau%20question'>d...@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:d...@juneau.apache.org?Subject=Apache%20Juneau%20question'>d...@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:'j...@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>