http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d89c8737/juneau-core/src/main/java/overview.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/overview.html b/juneau-core/src/main/java/overview.html deleted file mode 100644 index f68b543..0000000 --- a/juneau-core/src/main/java/overview.html +++ /dev/null @@ -1,7673 +0,0 @@ -<!DOCTYPE HTML> -<!-- -/*************************************************************************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - ***************************************************************************************************************************/ - --> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <style type="text/css"> - /* For viewing in file system and page designer */ - @IMPORT url("../../../../juneau-releng/javadoc.css"); - @IMPORT url("../../../../juneau-releng/juneau-doc.css"); - @IMPORT url("../../../../juneau-releng/juneau-code.css"); - - body { - margin: 20px; - } - .spaced-list li { padding:5px; } - .footer .spaced-list ul { margin:0 } - </style> - <script type="text/javascript"> - /* Replace all @code and @link tags. */ - window.onload = function() { - document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1<\/code>'); - document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3<\/code>'); - } - </script> -</head> -<body> -<p>Apache Juneau Overview</p> -<script type="text/javascript"> - function toggle(x) { - var div = x.nextSibling; - while (div != null && div.nodeType != 1) - div = div.nextSibling; - if (div != null) { - var d = div.style.display; - if (d == 'block' || d == '') { - div.style.display = 'none'; - x.className += " closed"; - } else { - div.style.display = 'block'; - x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' ); - } - } - } -</script> -<p> - A generalized toolkit for converting POJOs to and from a variety of content types (JSON, XML, HTML, URLs, RDF/XML, N-Tuple, Turtle, N3, SOAP, Cognos, ATOM), and a REST toolkit for building up REST interfaces using simple POJOs. -</p> - -<a id='TOC'></a><h5 class='toc'>Table of Contents</h5> -<ol class='toc'> - <li><p><a class='doclink' href='#Intro'>Juneau - What is it?</a></p> - <li><p><a class='doclink' href='#Core'>Juneau Core (juneau.jar)</a></p> - <ol> - <li><p><a class='doclink' href='#Core.PojoCategories'>POJO Categories</a></p> - <li><p><a class='doclink' href='#Core.Serializers'>Serializers</a></p> - <li><p><a class='doclink' href='#Core.Parsers'>Parsers</a></p> - <li><p><a class='doclink' href='#Core.ObjectMap'>ObjectMap and ObjectList</a></p> - <li><p><a class='doclink' href='#Core.ConfigurableProperties'>Configurable Properties</a></p> - <li><p><a class='doclink' href='#Core.Annotations'>Annotations</a></p> - <li><p><a class='doclink' href='#Core.Transforms'>Transforms</a></p> - <li><p><a class='doclink' href='#Core.SimpleVarLanguage'>Simple Variable Language</a></p> - <li><p><a class='doclink' href='#Core.ConfigFile'>Configuration Files</a></p> - <li><p><a class='doclink' href='#Core.SupportedLanguages'>Supported Languages</a></p> - </ol> - <li><p><a class='doclink' href='#Server'>Juneau Server (juneau-server.jar)</a></p> - <li><p><a class='doclink' href='#Client'>Juneau Client (juneau-client.jar)</a></p> - <li><p><a class='doclink' href='#Remoteable'>Remoteable services</a></p> - <li><p><a class='doclink' href='#Microservices'>Juneau Microservices (juneau-microservice.jar)</a></p> - <li><p><a class='doclink' href='#Samples'>Samples</a></p> - <ol> - <li><p><a class='doclink' href='#Samples.Installing'>Installing in Eclipse</a></p> - <li><p><a class='doclink' href='#Samples.Running'>Running in Eclipse</a></p> - <li><p><a class='doclink' href='#Samples.Building'>Building and Running from Command-Line</a></p> - <li><p><a class='doclink' href='#Samples.RestResource'>MANIFEST.MF</a></p> - <li><p><a class='doclink' href='#Samples.RootResources'>RootResources</a></p> - <li><p><a class='doclink' href='#Samples.HelloWorldResource'>HelloWorldResource</a></p> - <li><p><a class='doclink' href='#Samples.MethodExampleResource'>MethodExampleResource</a></p> - <li><p><a class='doclink' href='#Samples.UrlEncodedFormResource'>UrlEncodedFormResource</a></p> - <li><p><a class='doclink' href='#Samples.RequestEchoResource'>RequestEchoResource</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource'>AddressBookResource</a></p> - <ol> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Classes'>Classes</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Demo'>Demo</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Traversable'>Traversable</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Queryable'>Queryable</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Introspectable'>Introspectable</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.RestClient'>ClientTest</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Browser'>Browser Tips</a></p> - </ol> - <li><p><a class='doclink' href='#Samples.SampleRemoteableServlet'>SampleRemoteableServlet</a></p> - <li><p><a class='doclink' href='#Samples.TempDirResource'>TempDirResource</a></p> - <li><p><a class='doclink' href='#Samples.AtomFeedResource'>AtomFeedResource</a></p> - <li><p><a class='doclink' href='#Samples.DockerRegistryResource'>DockerRegistryResource</a></p> - <li><p><a class='doclink' href='#Samples.TumblrParserResource'>TumblrParserResource</a></p> - <li><p><a class='doclink' href='#Samples.PhotosResource'>PhotosResource</a></p> - <li><p><a class='doclink' href='#Samples.JsonSchemaResource'>JsonSchemaResource</a></p> - <li><p><a class='doclink' href='#Samples.SqlQueryResource'>SqlQueryResource</a></p> - <li><p><a class='doclink' href='#Samples.ConfigResource'>ConfigResource</a></p> - <li><p><a class='doclink' href='#Samples.LogsResource'>LogsResource</a></p> - </ol> - <li><p><a class='doclink' href='#Cookbook'>Cookbook Examples</a></p> - <ol> - <li><p><a class='doclink' href='#Cookbook.Core'>Core API</a></p> - <li><p><a class='doclink' href='#Cookbook.Server'>Server API</a></p> - <ol> - <li><p><a class='doclink' href='#Cookbook.Server.applyDoubletransform'>Apply a transform that changes the format of doubles</a></p> - <li><p><a class='doclink' href='#Cookbook.Server.applyTransformsSubset'>Apply transforms to a subset of serializers or parsers</a></p> - </ol> - <li><p><a class='doclink' href='#Cookbook.Client'>Client API</a></p> - <ol> - </ol> - <li><p><a class='doclink' href='#Cookbook.Microservice'>Microservice API</a></p> - <ol> - </ol> - </ol> - <li><p><a class='doclink' href='#BestPractices'>Best Practices</a></p> - <li><p><a class='doclink' href='#ImportantLinks'>Important Documentation Links</a></p> - <li><p><a class='doclink' href='#ReleaseNotes'>Release Notes</a></p> -</ol> - -<!-- ======================================================================================================== --> -<a id="Intro"></a> -<h2 class='topic' onclick='toggle(this)'>1 - Juneau - What is it?</h2> -<div class='topic'> - <p> - Juneau started off as a simple library for serializing and parsing POJOs to and from JSON. - Since then, it has expanded into serializing and parsing a variety of other content types. - Later, entire REST client, server, and microservice APIs were developed that utilized the power of these serializers and parsers. - Together, these features allow the construction of powerful REST interfaces wrapped around existing POJOs using very little code. - </p> - - <h5 class='toc'>Features</h5> - <ol class='toc'> - <li> - <p>Extensive and extensible support for a large variety of POJOs, including structured data (beans) and unstructured data (<l>Maps</l> and <l>Collections</l>).</p> - <li> - <p>Support for serializing POJO models to:</p> - <ul> - <li>JSON (including variants) - <li>XML - <li>HTML - <li>URL-Encoding - <li>UON (URL-Encoded Object Notation) - <li>MessagePack - <li>RDF/XML (including abbreviated) - <li>N-Triple - <li>Turtle - <li>N3 - <li>SOAP/XML - </ul> - <li> - <p>Support for parsing the following into POJO models:</p> - <ul> - <li>JSON (including lax syntax, comments, concatenated strings) - <li>XML - <li>HTML - <li>URL-Encoding - <li>UON (URL-Encoded Object Notation) - <li>MessagePack - <li>RDF/XML (including abbreviated) - <li>N-Triple - <li>Turtle - <li>N3 - </ul> - <li> - <p>Data Transfer Objects for the following:</p> - <ul> - <li>ATOM - <li>Cognos - <li>JSON-Schema - </ul> - <p>DTOs can be used with any serializers and parsers. - <li> - <p>Support for serializing POJO meta-models (specifically the POJO class structure itself) to:</p> - <ul> - <li>JSON-Schema - <li>XML-Schema - <li>HTML-Schema - </ul> - <li> - <p>Easy-to-understand naming conventions such as {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} to represent generic {@code Maps} and {@code Lists}.</p> - <li> - <p>Serializers have many options for tweaking output (such as whitespace options, XML namespace options, strict/non-strict syntax options, and so forth).</p> - <li> - <div> - JSON parser supports ALL valid JSON, such as: - <ul class='normal'> - <li>Javascript comments. - <li>Single or double quoted values. - <li>Quoted (strict) or unquoted (non-strict) attributes. - <li>JSON fragments (such as string, numeric, or boolean primitive values). - <li>Concatenated strings. - </ul> - </div> - <li> - <div> - REST server interface that allows POJOs to be accessed through REST calls. - <ul class='normal'> - <li>Serialization and parsing layer is completely transparent to developer. - Simply pass a POJO to the toolkit, and all serialization and parsing is taken care of. - <li>Extensible / customizable design. - Ability to define support for additional content types, or to handle requests manually at many different levels. - <li>Default built-in support for serializing output to all supported languages. - <li>Default built-in support for parsing input from all supported languages. - <li>Ability to easily design self-documenting interfaces (specifically REST interfaces described entirely through OPTIONS requests). - <li>Ability to debug interface using nothing more than a browser, including the ability to specify any HTTP headers as GET parameters. - </ul> - </div> - <li> - <p>REST client interface that allows clients to parse POJOs from the REST server, typically in a single line of code.</p> - <li> - <p>No code generators required. Can be used against existing POJO models, unlike other APIs like Java Web Services.</p> - <li> - <p> - Serializers/parsers require only Java 1.6+. - (RDF support requires Jena 2.7.1+) - </p> - <li> - <p> - REST APIs require only Java 1.6+ and JEE 1.3+. - (JAX/RS integration component requires JAX/RS provider) - </p> - <li> - <p>All code is 100% IBM developer written cleanroom code.</p> - <li> - <p>Extensive and up-to-date Javadocs with color-coded code examples.</p> - <li> - <p> - APIs use a Fluent Interface that allows complex tasks to be performed in a single line of code. - </p> - <li> - <p> - Code written for high-performance/high-concurrency/low-memory consumption.<br> - Caching of POJO metadata speeds execution of serialization and parsing.<br> - JSON parser is written using a state-machine architecture.<br> - XML and HTML parsers are written using StAX.<br> - POJOs are serialized/parsed directly from POJOs without a DOM layer, reducing object creation. - </p> - <li> - <p>A simple-to-use JAX-RS / Wink provider for using the existing Juneau serializers and parsers in a JAX-RS environment.</p> - <li> - <p>An external INI-style configuration file API.</p> - <li> - <p>An API for defining REST resource microservices as simple executable jars.</p> - </ol> - - <h5 class='topic'>Components</h5> - <p> - Juneau consists of the following libraries: - </p> - <ul class='spaced-list'> - <li><l>juneau.jar</l> - Core library that contains the serializers, parsers, and bean map support.<br> - Prereqs Java 1.6+.<br> - This package can be used by itself if you only need to serialize or parse from any of the supported languages, or use the Bean Map support separately.<br> - See the following subtopic <a class='doclink' href='#Core'>Juneau Core (juneau.jar)</a> for details on this library.<br> - <li><l>juneau-server.jar</l> - Contains the REST server APIs.<br> - Prereqs Java 1.6+, JEE 1.3+.<br> - This package can be used to create servlet-based REST interfaces.<br> - See <a class='doclink' href="#Server">Juneau Server (juneau-server.jar)</a> for details on this library.<br> - <li><l>juneau-client.jar</l> - Contains the REST client APIs.<br> - Prereqs Java 1.6+.<br> - This package can be used to easily communicate with Juneau REST servlets.<br> - See <a class='doclink' href="#Client">Juneau Client (juneau-client.jar)</a> for details on this library.<br> - <li><l>juneau-microservice.jar</l> - An API for defining REST services as executable jars.<br> - See <a class='doclink' href="#Microservices">Juneau Microservices (juneau-microservice.jar)</a> for details on this package.<br> - <li><l>juneau-all.jar</l> - Combines all the jars above into a single library. - </ul> - <p> - Typically, you want to simply pick up and use <l>juneau-all.jar</l> as this contains everything and is not very large (< 1MB). - </p> - <p> - The following zip files are also provided: - </p> - <ul class='spaced-list'> - <li><l>microservice-project.zip</l> - Contains a template Eclipse project for quickly creating REST resources as executable jars. - <li><l>microservice-samples-project.zip</l> - Contains sample code demonstrating various aspects of the Juneau Cloud Tools.<br> - These are discussed in detail in the <a class='doclink' href="#Samples">Samples</a> section. - </ul> - <p class='info'> - Many of the examples below use beans with public field properties. - While the toolkit allows for public bean properties, it's standard practice to use getters and setters for bean properties. - However, the examples below use public fields simply to reduce their verbosity. - </p> -</div> - -<!-- ======================================================================================================== --> -<a id="Core"></a> -<h2 class='topic' onclick='toggle(this)'>2 - Juneau Core (juneau.jar)</h2> -<div class='topic'> - <p> - The Juneau core library <l>juneau.jar</l> contains serializers and parsers for converting POJOs to and from - a wide variety of content types: - </p> - <ul> - <li>JSON - <li>XML - <li>HTML - <li>URL-Encoding - <li>UON - <li>MessagePack - <li>RDF-XML - <li>RDF-XML-Abbrev - <li>Turtle - <li>N3 - <li>N-Triple - <li>Plain text - <li>Cognos XML - </ul> - - <!-- ======================================================================================================== --> - <a id="Core.PojoCategories"></a> - <h3 class='topic' onclick='toggle(this)'>2.1 - POJO Categories</h3> - <div class='topic'> - <p> - The Juneau serializers and parsers can handle a wide variety of POJOs. - </p> - <p> - The following chart shows POJOs categorized into groups and whether they can be serialized or parsed: - </p> - <table class='styled' style='border-collapse: collapse;'> - <tr><th>Group</th><th>Description</th><th>Examples</th><th>Can<br>serialize?</th><th>Can<br>parse?</th></tr> - <tr class='dark bb' style='background-color:lightyellow;'> - <td style='text-align:center'>1</td> - <td><b>Java primitive objects</b></td> - <td> - <ul class='normal'> - <li>{@code String} - <li>{@code Integer} - <li>{@code Float} - <li>{@code Boolean} - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>2</td> - <td><b>Java Collections Framework objects and Java arrays</b></td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>2a</td> - <td> - <b>With standard keys/values</b><br> - Map keys are group [1, 4a, 5] objects.<br> - Map, Collection, and array values are group [1, 2, 3a, 4a, 5] objects. - </td> - <td> - <ul class='normal'> - <li>{@code HashSet<String,Integer>} - <li>{@code TreeMap<Integer,Bean>} - <li><code>List<<jk>int</jk>[][]></code> - <li>{@code Bean[]} - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>2b</td> - <td> - <b>With non-standard keys/values</b><br> - Map keys are group [2, 3, 4b, 5, 6] objects.<br> - Map, Collection, and array values are group [3b, 4, 5, 6] objects. - </td> - <td> - <ul class='normal'> - <li>{@code HashSet<Bean,Integer>} - <li>{@code TreeMap<Integer,Reader>} - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>3</td> - <td><b>Java Beans</b></td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>3a</td> - <td> - <b>With standard properties</b><br> - These are beans that have no-arg constructors and one or more properties defined by public getter and setter methods or public fields.<br> - Property values are group [1, 2, 3a, 4a, 5] objects. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>3b</td> - <td> - <b>With non-standard properties or not true beans</b><br> - These include true beans that have no-arg constructors and one or more properties defined by getter and setter methods or properties, - but property types include group [3b, 4b, 5, 6] objects.<br> - This also includes classes that look like beans but aren't true beans. - For example, classes that have getters but not setters, or classes without no-arg constructors. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>4</td> - <td> - <b>Swapped objects</b><br> - These are objects that are not directly serializable, but have {@link org.apache.juneau.transform.PojoSwap PojoSwaps} associated with them. - The purpose of a POJO swap is to convert an object to another object that is easier to serialize and parse. - For example, the {@link org.apache.juneau.transforms.DateSwap.ISO8601DT} class can be used to serialize {@link java.util.Date} objects - to ISO8601 strings, and parse them back into {@link java.util.Date} objects. - </td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>4a</td> - <td> - <b>2-way swapped to group [1, 2a, 3a] objects</b><br> - For example, a swap that converts a {@code Date} to a {@code String}. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>4b</td> - <td> - <b>1-way swapped to group [1, 2, 3] objects</b><br> - For example, a swap that converts an {@code Iterator} to a {@code List}. - This would be one way, since you cannot reconstruct an {@code Iterator}. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>5</td> - <td> - <b>Objects with standardized <code>static T valueOf(String)</code>/<code>static T fromString(String)</code> methods, or constructors with a <code>String</code> argument.</b><br> - During serialization, objects are converted to strings using the <code>toString()</code> method. - During parsing, strings are converted to objects using one of these static methods or constructors. - </td> - <td><code>java.util.UUID</code></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='dark' style='background-color:lightyellow'> - <td style='text-align:center'>6</td> - <td> - <b>All other objects</b><br> - Anything that doesn't fall into one of the groups above are simply converted to {@code Strings} using the {@code toString()} method. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - </table> - <p> - One other important note is that the serializers are designed to work on tree-shaped POJO models. - These are models where there are no referential loops (e.g. leaves with references to nodes, or nodes in one branch referencing nodes in another branch). - There is a serializer setting {@code detectRecursions} to look for and handle these kinds of loops (by setting these references to <jk>null</jk>), - but it is not enabled by default since it introduces a moderate performance penalty. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.Serializers"></a> - <h3 class='topic' onclick='toggle(this)'>2.2 - Serializers</h3> - <div class='topic'> - <p> - The built-in serializers in Juneau are fast and efficient, and are highly customizable, for example, allowing you to produce strict or non-strict syntax, - various whitespace options, and automatic detection of recursions. - </p> - <p> - The serializers work by serializing POJOs directly to streams instead of using intermediate Document Object Model objects. - This allows serialization with minimal memory use. - </p> - <p> - Default serialization support is provided for Java primitives, <l>Maps</l>, <l>Collections</l>, beans, and arrays. <br> - Extensible support for other data types such as <l>Calendars</l>, <l>Dates</l>, <l>Iterators</l> is available through the use of POJO swaps. - </p> - <p> - In most cases, you can serialize objects in one line of code by using one of the default serializers: - </p> - <p class='bcode'> - <jc>// A simple POJO class</jc> - <jk>public class</jk> Person { - <jk>public</jk> String <jf>name</jf> = <js>"John Smith"</js>; - <jk>public int</jk> <jf>age</jf> = 21; - } - - <jc>// Serialize a bean to JSON, XML, or HTML</jc> - Person p = <jk>new</jk> Person(); - - <jc>// Produces: - // "{name:'John Smith',age:21}"</jc> - String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // <object> - // <name>John Smith</name> - // <age>21</age> - // </object></jc> - String xml = XmlSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // <table> - // <tr><th>key</th><th>value</th></tr> - // <tr><td>name</td><td>John Smith</td></tr> - // <tr><td>age</td><td>21</td></tr> - // </table></jc> - String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // 82 A4 6E 61 6D 65 AA 4A 6F 68 6E 20 53 6D 69 74 68 A3 61 67 65 15 </jc> - <jk>byte</jk>[] b = MsgPackSerializer.<jsf>DEFAULT</jsf>.serialize(p); - </p> - - <p> - In addition to the default serializers, customized serializers can be created using various built-in options: - </p> - - <p class='bcode'> - <jc>// Use one of the default serializers to serialize a POJO</jc> - String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(someObject); - - <jc>// Create a custom serializer for lax syntax using single quote characters</jc> - JsonSerializer serializer = <jk>new</jk> JsonSerializer() - .setProperty(JsonSerializerContext.<jsf>JSON_simpleMode</jsf>, <jk>true</jk>) - .setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, <js>'\''</js>); - - <jc>// Clone an existing serializer and modify it to use single-quotes</jc> - JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.clone() - .setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, <js>'\''</js>); - - <jc>// Serialize a POJO to JSON</jc> - String json = serializer.serialize(someObject); - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/serializer/package-summary.html#TOC'>org.apache.juneau.serializer</a> - Serializer API Javadoc - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.Parsers"></a> - <h3 class='topic' onclick='toggle(this)'>2.3 - Parsers</h3> - <div class='topic'> - <p> - Parsers work by parsing input directly into POJOs instead of having to create intermediate Document Object Models. - This allows them to parse input with minimal object creation. - </p> - <p> - The JSON parser can handle any valid JSON syntax (such as quoted or unquoted attributes, single or double quotes).<br> - It can also handle JSON fragements and embedded Javascript comments. - </p> - <p class='bcode'> - <jc>// Use one of the predefined parsers.</jc> - Parser parser = JsonParser.<jsf>DEFAULT</jsf>; - - <jc>// Parse a JSON object (creates a generic ObjectMap).</jc> - String json = <js>"{name:'John Smith',age:21}"</js>; - Map m1 = parser.parse(json, Map.<jk>class</jk>); - - <jc>// Parse a JSON string.</jc> - json = <js>"'foobar'"</js>; - String s2 = parser.parse(json, String.<jk>class</jk>); - - <jc>// Parse a JSON number as a Long or Float.</jc> - json = <js>"123"</js>; - Long l3 = parser.parse(json, Long.<jk>class</jk>); - Float f3 = parser.parse(json, Float.<jk>class</jk>); - - <jc>// Parse a JSON object as a bean.</jc> - json = <js>"{name:'John Smith',age:21}"</js>; - Person p4 = parser.parse(json, Person.<jk>class</jk>); - - <jc>// Parse a JSON object as a HashMap<String,Person>.</jc> - json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"</js>; - Map<String,Person> m5 = parser.parseMap(json, HashMap.<jk>class</jk>, String.<jk>class</jk>, Person.<jk>class</jk>) - - <jc>// Parse a JSON array of integers as a Collection of Integers or int[] array.</jc> - json = <js>"[1,2,3]"</js>; - List<Integer> l6 = parser.parseCollection(json, LinkedList.<jk>class</jk>, Integer.<jk>class</jk>); - <jk>int</jk>[] i6 = parser.parse(json, <jk>int</jk>[].<jk>class</jk>); - </p> - <p> - The parsers can also be used to populating existing bean and collection objects: - </p> - <p class='bcode'> - <jc>// Use one of the predefined parsers.</jc> - Parser parser = JsonParser.<jsf>DEFAULT</jsf>; - - <jc>// Populate the properties on an existing bean from a JSON object.</jc> - String json = <js>"{name:'John Smith',age:21}"</js>; - Person p = <jk>new</jk> Person(); - parser.parseIntoBean(json, p); - - <jc>// Populate an existing list from a JSON array of numbers.</jc> - json = <js>"[1,2,3]"</js>; - List<Integer> l2 = <jk>new</jk> LinkedList<Integer>(); - parser.parseIntoCollection(json, l2, Integer.<jk>class</jk>); - - <jc>// Populate an existing map from a JSON object containing beans.</jc> - json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"</js>; - Map<String,Person> m3 = <jk>new</jk> TreeMap<String,Person>(); - parser.parseIntoMap(json, m3, String.<jk>class</jk>, Person.<jk>class</jk>); - </p> - <p> - Juneau can parse both structured models (composed of serialized beans) and unstructured models (composed of generic maps, collections, primitives, and so on). - Any valid JSON can be parsed into an unstructured model consisting of generic {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} objects. - </p> - <p class='bcode'> - <jc>// Parse an arbitrary JSON document into an unstructered data model - // consisting of ObjectMaps, ObjectLists, and java primitive objects.</jc> - Parser parser = JsonParser.<jsf>DEFAULT</jsf>; - String json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"</js>; - ObjectMap m = parser.parse(json, ObjectMap.<jk>class</jk>); - - <jc>// Use ObjectMap API to extract data from the unstructured model.</jc> - <jk>int</jk> johnSmithAge = m.getObjectMap(<js>"a"</js>).getInt(<js>"age"</js>); - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/parser/package-summary.html#TOC'>org.apache.juneau.parser</a> - Parser API Javadoc - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.ObjectMap"></a> - <h3 class='topic' onclick='toggle(this)'>2.4 - ObjectMap and ObjectList</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} classes are generic Java representations of JSON objects and arrays. - These classes can be used to create "unstructured" models for serialization (as opposed to "structured" models consisting of beans). - If you want to quickly generate JSON/XML/HTML from generic maps/collections, or parse JSON/XML/HTML into generic maps/collections, these objects work well. - </p> - <p> - These classes extend directly from JCF classes: - </p> - <ul class='javahierarchy'> - <li class='c'> {@link java.util.LinkedHashMap java.util.LinkedHashMap} - <ul> - <li class='c'> {@link org.apache.juneau.ObjectMap org.apache.juneau.ObjectMap} - </ul> - <li class='c'> {@link java.util.LinkedList java.util.LinkedList} - <ul> - <li class='c'> {@link org.apache.juneau.ObjectMap org.apache.juneau.ObjectList} - </ul> - </ul> - <p> - The <l>ObjectMap</l> and <l>ObjectList</l> are very similar to the <l>JSONObject</l> and <l>JSONArray</l> - classes found in other libraries. However, the names were chosen - because the concepts of <l>Maps</l> and <l>Lists</l> are already familiar to - Java programmers, and these classes can be used with any of the serialzers or parsers. - </p> - <p> - These object can be serialized in one of two ways: - </p> - <ol class='spaced-list'> - <li>Using the provided {@link org.apache.juneau.ObjectMap#serializeTo(java.io.Writer)} or {@link org.apache.juneau.ObjectList#serializeTo(java.io.Writer)} methods. - <li>Passing them to one of the {@link org.apache.juneau.serializer.Serializer} serialize methods. - </ol> - <p class='info'> - As a general rule, if you do not specify a target type during parsing, or if the target type cannot be determined - through reflection, the parsers automatically generate <l>ObjectMaps</l> and <l>ObjectLists</l>. - </p> - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='c'>{@link org.apache.juneau.ObjectMap} - <li class='c'>{@link org.apache.juneau.ObjectList} - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.ConfigurableProperties"></a> - <h3 class='topic' onclick='toggle(this)'>2.5 - Configurable Properties</h3> - <div class='topic'> - <p> - Serializers and parsers have a wide variety of configurable properties that can be set on them.<br> - For example, the following code shows how to set configurable properties on the JSON serializerclass: - </p> - <p class='bcode'> - JsonSerializer s = <jk>new</jk> JsonSerializer() - .setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>, <jk>true</jk>) - .setProperty(JsonSerializerContext.<jsf>JSON_useWhitespace</jsf>, <jk>true</jk>) - .setProperty(JsonSerializerContext.<jsf>JSON_simpleMode</jsf>, <jk>true</jk>) - .setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, <js>'\''</js>); - </p> - <p> - Each of the serializers and parsers contain common reusable instances with common configuration properties.<br> - For example, JSON has the following predefined reusable serializers and parsers: - </p> - <ul class='javahierarchy'> - <li class='c'>{@link org.apache.juneau.json.JsonSerializer} - <ul> - <li class='f'>{@link org.apache.juneau.json.JsonSerializer#DEFAULT DEFAULT} - <li class='f'>{@link org.apache.juneau.json.JsonSerializer#DEFAULT_LAX DEFAULT_LAX} - <li class='f'>{@link org.apache.juneau.json.JsonSerializer#DEFAULT_READABLE DEFAULT_READABLE} - <li class='f'>{@link org.apache.juneau.json.JsonSerializer#DEFAULT_LAX_READABLE DEFAULT_LAX_READABLE} - </ul> - <li class='c'>{@link org.apache.juneau.json.JsonParser} - <ul> - <li class='f'>{@link org.apache.juneau.json.JsonParser#DEFAULT DEFAULT} - <li class='f'>{@link org.apache.juneau.json.JsonParser#DEFAULT_STRICT DEFAULT_STRICT} - </ul> - </ul> - <p> - These can be used directly, as follows: - </p> - <p class='bcode'> - <jc>// Serialize a POJO to LAX JSON.</jc> - String json = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.serialize(myPojo); - </p> - <p> - Properties can be set using the following methods: - </p> - <ul class='javahierarchy'> - <li class='m'>{@link org.apache.juneau.serializer.Serializer#setProperty(String,Object)} - On any serializers. - <li class='m'>{@link org.apache.juneau.serializer.SerializerGroup#setProperty(String,Object)} - On groups of serializers. - <li class='m'>{@link org.apache.juneau.parser.Parser#setProperty(String,Object)} - On any parsers. - <li class='m'>{@link org.apache.juneau.parser.ParserGroup#setProperty(String,Object)} - On groups of parsers. - </ul> - <p> - The REST server API also provides various ways of setting properties: - </p> - <ul class='javahierarchy'> - <li class='n'>{@link org.apache.juneau.server.annotation.RestResource#properties() @RestResource.properties()} - Annotation on instances of {@link org.apache.juneau.server.RestServlet}. - <li class='n'>{@link org.apache.juneau.server.annotation.RestMethod#properties() @RestMethod.properties()} - Annotation on java methods in instances of {@link org.apache.juneau.server.RestServlet}. - <li class='m'>{@link org.apache.juneau.server.RestServlet#createSerializers(ObjectMap,Class[],Class[])} - Properties can be set programmatically on serializers by overriding this method. - <li class='m'>{@link org.apache.juneau.server.RestServlet#createParsers(ObjectMap,Class[],Class[])} - Properties can be set programmatically on parsers by overriding this method. - </ul> - <p> - Similarly, the REST client API provides ways of setting properties: - </p> - <ul class='javahierarchy'> - <li class='m'>{@link org.apache.juneau.client.RestClient#setProperty(String,Object)} - Set property on the serializer and parser associated with a REST client. - </ul> - <p> - The {@link org.apache.juneau.serializer.Serializer#lock()} and {@link org.apache.juneau.parser.Parser#lock()} - methods can be used to make serializer and parser properties read only. - All the common reusable serializers and parsers are read only. - If you attempt to modify any properties on those instances, a {@link org.apache.juneau.LockedException} is thrown. - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='c'>{@link org.apache.juneau.BeanContext} - Properties associated with handling beans on serializers and parsers. - <li class='c'>{@link org.apache.juneau.serializer.SerializerContext} - Configurable properties common to all serializers. - <li class='c'>{@link org.apache.juneau.parser.ParserContext} - Configurable properties common to all parsers. - <li class='c'>{@link org.apache.juneau.html.HtmlSerializerContext} - Configurable properties on the HTML serializer. - <li class='c'>{@link org.apache.juneau.html.HtmlDocSerializerContext} - Configurable properties on the HTML document serializer. - <li class='c'>{@link org.apache.juneau.html.HtmlParserContext} - Configurable properties on the HTML parser. - <li class='c'>{@link org.apache.juneau.jena.RdfCommonContext} - Configurable properties common to the RDF serializers and parsers. - <li class='c'>{@link org.apache.juneau.jena.RdfSerializerContext} - Configurable properties on the RDF serializer. - <li class='c'>{@link org.apache.juneau.jena.RdfParserContext} - Configurable properties on the RDF parsers. - <li class='c'>{@link org.apache.juneau.json.JsonSerializerContext} - Configurable properties on the JSON serializer. - <li class='c'>{@link org.apache.juneau.json.JsonParserContext} - Configurable properties on the JSON parser. - <li class='c'>{@link org.apache.juneau.soap.SoapXmlSerializerContext} - Configurable properties on the SOAP/XML serializer. - <li class='c'>{@link org.apache.juneau.urlencoding.UonSerializerContext} - Configurable properties on the URL-Encoding and UON serializers. - <li class='c'>{@link org.apache.juneau.urlencoding.UonParserContext} - Configurable properties on the URL-Encoding and UON parsers. - <li class='c'>{@link org.apache.juneau.xml.XmlSerializerContext} - Configurable properties on the XML serializer. - <li class='c'>{@link org.apache.juneau.xml.XmlParserContext} - Configurable properties on the XML parser. - <li class='c'>{@link org.apache.juneau.server.RestServletContext} - Configurable properties on the REST servlet. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.Annotations"></a> - <h3 class='topic' onclick='toggle(this)'>2.6 - Annotations</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.annotation} package contains several annotations that can be applied to classes to alter how they're - handled by the serializers and parsers. - </p> - <p> - For example, the {@link org.apache.juneau.annotation.Bean @Bean} annotation can be used to limit which getters and setters get - interpreted as bean properties: - </p> - <p class='bcode'> - <jc>// Address class with only street/city/state properties (in that order).</jc> - <jc>// All other properties are ignored.</jc> - <ja>@Bean</ja>(properties={<js>"street"</js>,<js>"city"</js>,<js>"state"</js>}) - <jk>public class</jk> Address { - ... - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='n'>{@link org.apache.juneau.annotation.Pojo @Pojo} - Used to tailor how non-bean POJOs get interpreted by the framework. - <li class='n'>{@link org.apache.juneau.annotation.Bean @Bean} - Used to tailor how beans get interpreted by the framework. - <li class='n'>{@link org.apache.juneau.annotation.BeanConstructor @BeanConstructor} - Maps constructor arguments to property names on beans with read-only properties. - <li class='n'>{@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} - Ignore classes, fields, and methods from being interpreted as bean or bean components. - <li class='n'>{@link org.apache.juneau.annotation.BeanProperty @BeanProperty} - Used to tailor how bean properties get interpreted by the framework. - <li class='n'>{@link org.apache.juneau.annotation.NameProperty @NameProperty} - Identifies a setter as a method for setting the name of a POJO as it's known by its parent object. - <li class='n'>{@link org.apache.juneau.annotation.ParentProperty @ParentProperty} - Identifies a setter as a method for adding a parent reference to a child object. - <li class='n'>{@link org.apache.juneau.annotation.URI @URI} - Used to identify a class or bean property as a URI. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.Transforms"></a> - <h4 class='topic' onclick='toggle(this)'>2.7 - Transforms</h4> - <div class='topic'> - <p> - The programmatic equivalent to the annotations are the {@link org.apache.juneau.transform.BeanFilter} and - {@link org.apache.juneau.transform.PojoSwap} classes. - </p> - <p> - The following example is equivalent to specifying the <l>@Bean</l> annotation in the previous example using a bean filter: - </p> - <p class='bcode'> - <jc>// Define bean filter that returns properties in the following order: "street", "city", "state"</jc> - <jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilter<Address> { - <jk>public</jk> AddressFilter() { - setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>); - } - } - - WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(AddressFilter.<jk>class</jk>); - Address a = getAddress(); - String json = s.serialize(a); <jc>// Prints "{street:'...',city:'...',state;'...'}"</jc> - </p> - <p> - The {@link org.apache.juneau.transform.PojoSwap} class is a critical component of Juneau that allows serializers and parsers to - be able to handle virtually any Java object. - Simply put, they can be thought of as 'transformers' that convert non-serializable objects to serializable objects and vice versa. - </p> - <p> - For example, <l>Date</l> objects are not normally serializable. - (Technically, they look like beans with getters/setters and so get serialized as such, which typically is not the desired result.) - The following POJO swap can be used to represent dates in ISO8601 format: - </p> - <p class='bcode'> - <jc>// Sample swap for converting Dates to ISO8601 strings.</jc> - <jk>public class</jk> MyDateSwap <jk>extends</jk> PojoSwap<Date,String> { - - <jc>// ISO8601 formatter.</jc> - <jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk> SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>); - - <jd>/** Converts a Date object to an ISO8601 string. */</jd> - <ja>@Override</ja> - <jk>public</jk> String swap(Date o) { - <jk>return</jk> <jf>format</jf>.format(o); - } - - <jd>/** Converts an ISO8601 string to a Date object. */</jd> - <ja>@Override</ja> - <jk>public</jk> Date unswap(String o) <jk>throws</jk> ParseException { - <jk>try</jk> { - <jk>return</jk> <jf>format</jf>.parse(o); - } <jk>catch</jk> (java.text.ParseException e) { - <jk>throw new</jk> ParseException(e); - } - } - } - </p> - <p> - The swap above can then be associated with serializers and parsers as the following example shows: - </p> - <p class='bcode'> - <jc>// Sample bean with a Date field.</jc> - <jk>public class</jk> MyBean { - <jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2, 3, 4, 5, 6); - } - - <jc>// Create a new JSON serializer, associate our date swap with it, and serialize a sample bean.</jc> - Serializer serializer = <jk>new</jk> JsonSerializer().addPojoSwaps(MyDateSwap.<jk>class</jk>); - String json = serializer.serialize(<jk>new</jk> MyBean()); <jc>// == "{date:'2012-03-03T04:05:06-0500'}"</jc> - - <jc>// Create a JSON parser, associate our date swap with it, and reconstruct our bean (including the date).</jc> - ReaderParser parser = <jk>new</jk> JsonParser().addPojoSwaps(MyDateSwap.<jk>class</jk>); - MyBean bean = parser.parse(json, MyBean.<jk>class</jk>); - <jk>int</jk> day = bean.<jf>date</jf>.getDay(); <jc>// == 3</jc> - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/transform/package-summary.html#TOC'>org.apache.juneau.transform</a> - Transform API Javadocs. - <li class='p'><a class='doclink' href='org/apache/juneau/transforms/package-summary.html#TOC'>org.apache.juneau.transforms</a> - Predefined reusable transform classes. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SVL"></a> - <h4 class='topic' onclick='toggle(this)'>2.8 - Simple Variable Language</h4> - <div class='topic'> - <p> - The {@link org.apache.juneau.svl} package 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> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/svl/package-summary.html#TOC'>org.apache.juneau.svl</a> - Simple Variable Language Javadocs. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.ConfigFile"></a> - <h3 class='topic' onclick='toggle(this)'>2.9 - Configuration Files</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.ini} package contains a powerful API for creating and using INI-style config files. - </p> - <p> - An example of an INI file: - </p> - <p class='bcode'> - <cc># Default section</cc> - <ck>key1</ck> = <cv>1</cv> - <ck>key2</ck> = <cv>true</cv> - <ck>key3</ck> = <cv>1,2,3</cv> - <ck>key4</ck> = <cv>http://foo</cv> - - <cc># Section 1</cc> - <cs>[Section1]</cs> - <ck>key1</ck> = <cv>2</cv> - <ck>key2</ck> = <cv>false</cv> - <ck>key3</ck> = <cv>4,5,6</cv> - <ck>key4</ck> = <cv>http://bar</cv> - </p> - <p> - This class can be used to easily access contents of this file, using the various capabilities of the {@link org.apache.juneau.ObjectMap} class, as follows: - </p> - <p class='bcode'> - <jk>int</jk> key1; - <jk>boolean</jk> key2; - <jk>int</jk>[] key3; - URL key4; - - <jc>// Load our config file</jc> - ConfigFile f = ConfigMgr.<jsf>DEFAULT</jsf>.get(<js>"MyIniFile.cfg"</js>); - - <jc>// Read values from default section</jc> - key1 = f.getInt(<js>"key1"</js>); - key2 = f.getBoolean(<js>"key2"</js>); - key3 = f.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"key3"</js>); - key4 = f.getObject(URL.<jk>class</jk>, <js>"key4"</js>); - - <jc>// Read values from section #1</jc> - key1 = f.getInt(<js>"Section1/key1"</js>); - key2 = f.getBoolean(<js>"Section1/key2"</js>); - key3 = f.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"Section1/key3"</js>); - key4 = f.getObject(URL.<jk>class</jk>, <js>"Section1/key4"</js>); - </p> - <p> - The interface also allows a config file to be easily constructed programmatically: - </p> - <p class='bcode'> - <jc>// Construct the sample INI file programmatically</jc> - ConfigFile cf = ConfigMgr.<jsf>DEFAULT</jsf>.create(<js>"MyIniFile.cfg"</js>) - .addLines(<jk>null</jk>, - <js>"# Default section"</js>, - <js>"key1 = 1"</js>, - <js>"key2 = true"</js>, - <js>"key3 = 1,2,3"</js>, - <js>"key4 = http://foo"</js>, - <js>""</js>) - .addHeaderComments(<js>"Section1"</js>, - <js>"# Section 1"</js>) - .addLines(<js>"Section1"</js>, - <js>"key1 = 2"</js>, - <js>"key2 = false"</js>, - <js>"key3 = 4,5,6"</js>, - <js>"key4 = http://bar"</js>) - .save(); - </p> - <p> - The following is equivalent, except that it uses {@link org.apache.juneau.ini.ConfigFile#put(String, Object)} to set values: - </p> - <p class='bcode'> - <jc>// Construct the sample INI file programmatically</jc> - ConfigFile cf = ConfigMgr.<jsf>DEFAULT</jsf>.create(<js>"MyIniFile.cfg"</js>) - .addLines(<jk>null</jk>, - <js>"# Default section"</js>) - .addHeaderComments(<js>"section1"</js>, - <js>"# Section 1"</js>); - cf.put(<js>"key1"</js>, 1); - cf.put(<js>"key2"</js>, <jk>true</jk>); - cf.put(<js>"key3"</js>, <jk>new int</jk>[]{1,2,3}); - cf.put(<js>"key4"</js>, <jk>new</jk> URL(<js>"http://foo"</js>)); - cf.put(<js>"Section1/key1"</js>, 2); - cf.put(<js>"Section1/key2"</js>, <jk>false</jk>); - cf.put(<js>"Section1/key3"</js>, <jk>new int</jk>[]{4,5,6}); - cf.put(<js>"Section1/key4"</js>, <jk>new</jk> URL(<js>"http://bar"</js>)); - cf.save(); - </p> - <p> - The config file looks deceptively simple, the config file API is a very powerful feature with many capabilities, including: - </p> - <ul class='spaced-list'> - <li>The ability to use variables to reference environment variables, system properties, other config file entries, and a host of other types. - <li>The ability to store and retrieve POJOs as JSON. - <li>APIs for updating, modifying, and saving configuration files without losing comments or formatting. - <li>Extensive listener APIs. - </ul> - <h6 class='topic'>Examples</h6> - <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> - - <cc># A POJO with embedded variables</cc> - <ck>aBean2</ck> = <cv>{foo:'$ARG{0}',baz:$C{MySection/anInt}}</cv> - - </p> - <p class='bcode'> - <jc>// Java code for accessing config entries above.</jc> - ConfigFile cf = Microservice.<jsm>getConfig</jsm>(); - - <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> - - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/ini/package-summary.html#TOC'>org.apache.juneau.ini</a> - Config API Javadocs. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SupportedLanguages"></a> - <h3 class='topic' onclick='toggle(this)'>2.10 - Supported Languages</h3> - <div class='topic'> - <p> - Extensive javadocs exist for individual language support. - Refer to these docs for language-specific information. - </p> - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/html/package-summary.html#TOC'>org.apache.juneau.html</a> - HTML support. - <li class='p'><a class='doclink' href='org/apache/juneau/jena/package-summary.html#TOC'>org.apache.juneau.jena</a> - RDF support. - <li class='p'><a class='doclink' href='org/apache/juneau/jso/package-summary.html#TOC'>org.apache.juneau.jso</a> - Java Serialized Object support. - <li class='p'><a class='doclink' href='org/apache/juneau/json/package-summary.html#TOC'>org.apache.juneau.json</a> - JSON support. - <li class='p'><a class='doclink' href='org/apache/juneau/plaintext/package-summary.html#TOC'>org.apache.juneau.plaintext</a> - Plain-text support. - <li class='p'><a class='doclink' href='org/apache/juneau/soap/package-summary.html#TOC'>org.apache.juneau.soap</a> - SOAP support. - <li class='p'><a class='doclink' href='org/apache/juneau/urlencoding/package-summary.html#TOC'>org.apache.juneau.urlencoding</a> - URL-Encoding and UON support. - <li class='p'><a class='doclink' href='org/apache/juneau/xml/package-summary.html#TOC'>org.apache.juneau.xml</a> - XML support. - <li class='p'><a class='doclink' href='org/apache/juneau/dto/atom/package-summary.html#TOC'>org.apache.juneau.dto.atom</a> - ATOM support. - <li class='p'><a class='doclink' href='org/apache/juneau/dto/cognos/package-summary.html#TOC'>org.apache.juneau.dto.cognos</a> - Cognos support. - </ul> - </div> -</div> - -<!-- ======================================================================================================== --> -<a id="Server"></a> -<h2 class='topic' onclick='toggle(this)'>3 - Juneau Server (juneau-server.jar)</h2> -<div class='topic'> - <p> - The Juneau REST Server API provides a variety of servlet-based REST resource classes that provides REST interfaces on top of existing POJOs, - allowing manipulation of those models using familiar GET, PUT, POST, and DELETE operations. - </p> - <p> - The API automatically detects <l>Accept</l> header of requests and converts POJOs to any of the supported languages. - The toolkit is extensible and also allows for support of user-defined content types. - </p> - <p> - Automatic built-in support is provided for negotiation of response charsets and gzip encoding. - </p> - <p> - The following is an example of a REST API used to view and set JVM system properties. - </p> - <p class='bcode'> - <ja>@RestResource</ja>( - messages=<js>"nls/messages"</js>, - properties={ - <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{label}"</js>), - <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>), - <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>), - <ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>PROPERTY_NAME</jsf>) - } - ) - <jk>public class</jk> SystemPropertiesService <jk>extends</jk> RestServletJenaDefault { - - <jd>/** [OPTIONS /*] - Show resource options. */</jd> - <ja>@RestMethod</ja>(name=<js>"OPTIONS"</js>, path=<js>"/*"</js>) - <jk>public</jk> ResourceOptions getOptions(RestRequest req) { - <jk>return new</jk> ResourceOptions(<jk>this</jk>, req); - } - - <jd>/** [GET /] - Get all system properties. */</jd> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/"</js>) - <jk>public</jk> TreeMap<String,String> getSystemProperties() <jk>throws</jk> Throwable { - <jk>return new</jk> TreeMap(System.<jsm>getProperties()</jsm>); - } - - <jd>/** [GET /{propertyName}] - Get system property with specified name. */</jd> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/{propertyName}"</js>) - <jk>public</jk> String getSystemProperty(<ja>@Attr</ja> String propertyName) <jk>throws</jk> Throwable { - <jk>return</jk> System.<jsm>getProperty</jsm>(propertyName); - } - - <jd>/** [PUT /{propertyName}] - Set system property with specified name. */</jd> - <ja>@RestMethod</ja>(name=<js>"PUT"</js>, path=<js>"/{propertyName}"</js>, guards=AdminGuard.<jk>class</jk>) - <jk>public</jk> Redirect setSystemProperty(<ja>@Attr</ja> String propertyName, <ja>@Content</ja> String value) { - System.<jsm>setProperty</jsm>(propertyName, value); - <jk>return new</jk> Redirect(); - } - - <jd>/** [DELETE /{propertyName}] - Delete system property with specified name. */</jd> - <ja>@RestMethod</ja>(name=<js>"DELETE"</js>, path=<js>"/{propertyName}"</js>, guards=AdminGuard.<jk>class</jk>) - <jk>public</jk> Redirect deleteSystemProperty(<ja>@Attr</ja> String propertyName) { - System.<jsm>clearProperty</jsm>(propertyName); - <jk>return new</jk> Redirect(); - } - } - </p> - <p> - The resource above is deployed like any other servlet, in this way: - </p> - <p class='bcode'> - <xt><?xml</xt> <xa>version</xa>=<xs>"1.0"</xs> <xa>encoding</xa>=<xs>"UTF-8"</xs><xt>?></xt> - <xt><web-app</xt> <xa>version</xa>=<xs>"2.3"</xs><xt>></xt> - <xt><servlet></xt> - <xt><servlet-name></xt>SystemPropertiesService<xt></servlet-name></xt> - <xt><servlet-class></xt>com.ibm.sample.SystemPropertiesService<xt></servlet-class></xt> - <xt></servlet></xt> - <xt><servlet-mapping></xt> - <xt><servlet-name></xt>SystemPropertiesService<xt></servlet-name></xt> - <xt><url-pattern></xt>/systemProperties<xt></url-pattern></xt> - <xt></servlet-mapping></xt> - <xt></web-app></xt> - </p> - <p> - One of the most useful aspects of using this API is the self-discovering, self-documenting OPTIONS pages that describe how to use the resource using labels pulled from the associated resource bundle: - </p> - <img class='bordered' src="doc-files/Server.Options.png"> - - <p> - Arbitrarily complex POJO models can be serialized using any of the supported serializers, and content can be parsed using any of the supported parsers. - </p> - <p> - The <l>com.ibm.team.juneau.samples</l> project contains various REST resource examples in an easy-to-use REST microservice. - One of these is <l>AddressBookResource</l> which serializes <l>AddressBook</l> objects defined below (some code omitted): - </p> - <p class='bcode'> - <jd>/** package-info.java */</jd> - <ja>@XmlSchema</ja>( - prefix=<js>"ab"</js>, - xmlNs={ - <ja>@XmlNs</ja>(prefix=<js>"ab"</js>, namespaceURI=<js>"http://www.ibm.com/addressBook/"</js>), - <ja>@XmlNs</ja>(prefix=<js>"per"</js>, namespaceURI=<js>"http://www.ibm.com/person/"</js>), - <ja>@XmlNs</ja>(prefix=<js>"addr"</js>, namespaceURI=<js>"http://www.ibm.com/address/"</js>), - <ja>@XmlNs</ja>(prefix=<js>"mail"</js>, namespaceURI=<js>"http://www.ibm.com/mail/"</js>) - } - ) - <jk>package</jk> com.ibm.sample.addressbook; - <jk>import</jk> org.apache.juneau.xml.annotation.*; - - <jd>/** Address book bean */</jd> - <ja>@Xml</ja>(name=<js>"addressBook"</js>) - <jk>public class</jk> AddressBook <jk>extends</jk> !LinkedList<Person> {} - - <jd>/** Person bean */</jd> - <ja>@Xml</ja>(prefix=<js>"per"</js>,name=<js>"person"</js>) - <jk>public class</jk> Person { - <jc>// Bean properties</jc> - <ja>@BeanProperty</ja>(beanUri=<jk>true</jk>) <jk>public</jk> URI <jf>uri</jf>; - <jk>public</jk> URI <jf>addressBookUri</jf>; - <jk>public int</jk> <jf>id</jf>; - <jk>public</jk> String <jf>name</jf>; - <ja>@BeanProperty</ja>(pojoSwaps=CalendarSwap.Medium.<jk>class</jk>) <jk>public</jk> Calendar <jf>birthDate</jf>; - <jk>public</jk> LinkedList<Address> <jf>addresses</jf>; - } - - <jd>/** Address bean */</jd> - <ja>@Xml</ja>(prefix=<js>"addr"</js>,name=<js>"address"</js>) - <jk>public class</jk> Address { - <jc>// Bean properties</jc> - <ja>@BeanProperty</ja>(beanUri=<jk>true</jk>) <jk>public</jk> URI <jf>uri</jf>; - <jk>public</jk> URI <jf>personUri</jf>; - <jk>public int</jk> <jf>id</jf>; - <ja>@Xml</ja>(prefix=<js>"mail"</js>) <jk>public</jk> String <jf>street</jf>, <jf>city</jf>, <jf>state</jf>; - <ja>@Xml</ja>(prefix=<js>"mail"</js>) <jk>public int</jk> <jf>zip</jf>; - <jk>public boolean</jk> <jf>isCurrent</jf>; - } - </p> - <p> - The framework allows you to override header values through GET parameters, so that you can specify the <l>ACCEPT</l> header to see each type. - Adding <l>&plainText=true</l> forces the response <l>Content-Type</l> to be <l>text/plain.</l> - <h6 class='figure'>HTML</h6> - <img class='bordered' src="doc-files/Server.Html.png"> - <h6 class='figure'>JSON</h6> - <img class='bordered' src="doc-files/Server.Json.png"> - <h6 class='figure'>XML</h6> - <img class='bordered' src="doc-files/Server.Xml.png"> - <h6 class='figure'>Simple XML</h6> - <img class='bordered' src="doc-files/Server.SimpleXml.png"> - <h6 class='figure'>URL-Encoding</h6> - <img class='bordered' src="doc-files/Server.UrlEncoding.png"> - <h6 class='figure'>UON</h6> - <img class='bordered' src="doc-files/Server.Uon.png"> - <h6 class='figure'>RDF/XML</h6> - <img class='bordered' src="doc-files/Server.RdfXml.png"> - <h6 class='figure'>RDF/N3</h6> - <img class='bordered' src="doc-files/Server.N3.png"> - <h6 class='figure'>RDF/N-Tuple</h6> - <img class='bordered' src="doc-files/Server.NTuple.png"> - <h6 class='figure'>RDF/Turtle</h6> - <img class='bordered' src="doc-files/Server.Turtle.png"> - - <p> - The Server API is an exhaustive topic on its own. - Refer to the additional information for an in-depth examination of the API. - </p> - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/server/package-summary.html#TOC'>org.apache.juneau.server</a> - Juneau Server API Javadocs. - </ul> -</div> - -<!-- ======================================================================================================== --> -<a id="Client"></a> -<h2 class='topic' onclick='toggle(this)'>4 - Juneau Client (juneau-client.jar)</h2> -<div class='topic'> - <p> - The REST client API provides the ability to access remote REST interfaces and transparently convert the input and output to and from POJOs using any - of the provided serializers and parsers. - </p> - <p> - Built upon the Apache HttpClient libraries, it extends that API and provides specialized APIs for working with REST interfaces while - maintaining all the functionality available in the HttpClient API. - </p> - <p class='bcode'> - <jc>// Create a reusable JSON client.</jc> - RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>); - - <jc>// The address of the root resource.</jc> - String url = <js>"http://localhost:9080/sample/addressBook"</js>; - - <jc>// Do a REST GET against a remote REST interface and convert - // the response to an unstructured ObjectMap object.</jc> - ObjectMap m1 = client.doGet(url).getResponse(ObjectMap.<jk>class</jk>); - - <jc>// Same as above, except parse the JSON as a bean.</jc> - AddressBook a2 = client.doGet(url).getResponse(AddressBook.<jk>class</jk>); - - <jc>// Add a person to the address book. - // Use XML as the transport medium.</jc> - client = <jk>new</jk> RestClient(XmlSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>); - Person p = <jk>new</jk> Person(<js>"Joe Smith"</js>, 21); - <jk>int</jk> returnCode = client.doPost(url + <js>"/entries"</js>, p).run(); - </p> - - <p> - The Client API is also an exhaustive topic on its own. - Refer to the additional information for an in-depth examination of the API. - </p> - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/client/package-summary.html#TOC'>org.apache.juneau.client</a> - Juneau Client API Javadocs. - </ul> -</div> - -<!-- ======================================================================================================== --> -<a id="Remoteable"></a> -<h2 class='topic' onclick='toggle(this)'>5 - Remoteable Services</h2> -<div class='topic'> - <p> - Juneau provides the capability of calling methods on POJOs on a server through client-side proxy interfaces. - It offers a number of advantages over other similar remote proxy interfaces, such as being much simpler to - use and allowing much more flexibility. - </p> - <p> - Remoteable Services are implemented through a combination of the Server and Client libraries. - </p> - <ul class='spaced-list'> - <li>Proxy interfaces are retrieved using the {@link org.apache.juneau.client.RestClient#getRemoteableProxy(Class)} method. - <li>The {@link org.apache.juneau.client.RestClient#setRemoteableServletUri(String)} method is used to specify the location - of the remoteable services servlet running on the server. - <li>The {@link org.apache.juneau.server.remoteable.RemoteableServlet} class is a specialized subclass of {@link org.apache.juneau.server.RestServlet} that provides a full-blown - REST interface for calling interfaces remotely. - </ul> - <p> - In this example, you have the following interface defined that you want to call from the client side against - a POJO on the server side (i.e. a Remoteable Service): - <p class='bcode'> - <jk>public interface</jk> IAddressBook { - Person createPerson(CreatePerson cp) <jk>throws</jk> Exception; - } - </p> - <p> - The client side code for invoking this method is shown below: - </p> - <p class='bcode'> - <jc>// Create a RestClient using JSON for serialization, and point to the server-side remoteable servlet.</jc> - RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>,JsonParser.<jk>class</jk>) - .setRemoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>); - - <jc>// Create a proxy interface.</jc> - IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>); - - <jc>// Invoke a method on the server side and get the returned result.</jc> - Person p = ab.createPerson( - <jk>new</jk> CreatePerson(<js>"Test Person"</js>, - AddressBook.<jsm>toCalendar</jsm>(<js>"Aug 1, 1999"</js>), - <jk>new</jk> CreateAddress(<js>"Test street"</js>, <js>"Test city"</js>, <js>"Test state"</js>, 12345, <jk>true</jk>)) - ); - </p> - <p> - The requirements for a method to be callable through a remoteable service are: - </p> - <ul class='spaced-list'> - <li>The method must be public. - <li>The parameter and return types must be <a href='#Core.PojoCategories'>serializable and parsable</a>. - </ul> - <p> - One significant feature is that the remoteable services servlet is a full-blown REST interface. - Therefore, in cases where the interface classes are not available on the client side, - the same method calls can be made through pure REST calls. - This can also aid significantly in debugging, since calls to the remoteable service - can be made directly from a browser with no coding involved. - </p> - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/server/remoteable/package-summary.html#TOC'>org.apache.juneau.server.remoteable</a> - Juneau Remoteable API Javadocs. - </ul> -</div> - -<!-- ======================================================================================================== --> -<a id="Microservices"></a> -<h2 class='topic' onclick='toggle(this)'>6 - Microservices</h2> -<div class='topic'> - <p> - <b>WARNING - The microservice API is still in beta. It may be replaced with an OSGi-based architecture.</b> - </p> - <p> - The <l>microservice-project.zip</l> file contains a standalone Eclipse project that can be used - to quickly create REST microservices as standalone executable jars without the need of an application server. - They start almost instantly and are started through a simple java command: - </p> - <p> - <code class='snippet'>java -jar microservice.jar</code> - </p> - <p> - When you execute this command, you can point your browser to <l>http://localhost:10000</l> to bring up the REST interface: - </p> - <img class='bordered' src="doc-files/Microservices.1.png"> - <p> - Microservices combine all the functionality of the core, server, and client APIs to provide truly powerful - and easy-to-use REST interfaces with minimal overhead. - </p> - <h6 class='topic'>Additional Information</h6> - <ul class='javahierarchy'> - <li class='p'><a class='doclink' href='org/apache/juneau/microservice/package-summary.html#TOC'>org.apache.juneau.microservice</a> - Juneau Microservice API Javadocs. - </ul> -</div> - -<!-- ======================================================================================================== --> -<a id="Samples"></a> -<h2 class='topic' onclick='toggle(this)'>7 - Samples</h2> -<div class='topic'> - <p> - The <l>microservice-samples-project.zip</l> file is a zipped eclipse project that includes everything you - need to start the Samples REST microservice in an Eclipse workspace. - </p> - <p> - This project is packaged as a Juneau Microservice project that allows REST resources to be started - using embedded Jetty. - </p> - - <!-- ======================================================================================================== --> - <a id="Samples.Installing"></a> - <h3 class='topic' onclick='toggle(this)'>7.1 - Installing in Eclipse</h3> - <div class='topic'> - <p> - Follow these instructions to create the Samples project in Eclipse: - </p> - <ol class='spaced-list'> - <li>Download the latest microservice-samples-project .zip file (e.g. <l>microservice-samples-project-5.2.zip</l>). - <li>In your Eclipse workspace, go to <b>File->Import->General->Existing Projects into Workspace</b> and click <b>Next</b>.<br><br> - <img class='bordered' src="doc-files/Samples.Installing.1.png"> - <li>Select the .zip file and click <b>Finish</b>.<br><br> - <img class='bordered' src="doc-files/Samples.Installing.2.png"> - <li>In your workspace, you can now see the following project:<br><br> - <img class='bordered' src="doc-files/Samples.Installing.3.png"> - </ol> - <p> - The important elements in this project are: - </p> - <ul class='spaced-list'> - <li><l>META-INF/MANIFEST.MF</l> - The manifest file. <br> - This defines the entry point, classpath, top-level REST resources, and location of external configuration file. <br><br> - <p class='bcode'> - <mk>Manifest-Version</mk>: <mv>1.0</mv> - <mk>Main-Class</mk>: <mv>org.apache.juneau.microservice.RestMicroservice</mv> - <mk>Rest-Resources</mk>: <mv>org.apache.juneau.server.samples.RootResources</mv> - <mk>Main-ConfigFile</mk>: <mv>samples.cfg</mv> - <mk>Class-Path</mk>: - <mv>lib/commons-codec-1.9.jar - lib/commons-io-1.2.jar - lib/commons-logging-1.1.1.jar - lib/httpclient-4.5.jar - lib/httpcore-4.4.1.jar - lib/httpmime-4.5.jar - lib/javax.servlet-api-3.0.jar - lib/jetty-all-8.1.0.jar - lib/juneau-all-5.2.jar - lib/org.apache.commons.fileupload_1.3.1.jar - lib/derby.jar - lib/jena-core-2.7.1.jar - lib/jena-iri-0.9.2.jar - lib/log4j-1.2.16.jar - lib/slf4j-api-1.6.4.jar - lib/slf4j-log4j12-1.6.4.jar</mv> - </p> - <li><l>RestMicroservice.java</l> - The application class. - <br>This is a specialized microservice in Juneau for exposing REST servlets. - <br>Allows REST servlets to be registered in the manifest or configuration file. - <li><l>RootResources.java</l> - The top-level REST resource. - <br>This class serves as a "router" page to child resources:<br> - <li><l>samples.cfg</l> - The external configuration file. - <br>A deceptively simple yet powerful INI-style configuration file: - <br><br> - <p class='bcode'> - <cc>#================================================================================ - # Basic configuration file for SaaS microservices - # Subprojects can use this as a starting point. - #================================================================================</cc> - - <cc>#================================================================================ - # REST settings - #================================================================================</cc> - <cs>[REST]</cs> - - <cc># The HTTP port number to use. - # Default is Rest-Port setting in manifest file, or 8000.</cc> - <ck>port</ck> = <cv>10000</cv> - ... - </p> - - </ul> - <p> - At this point you're ready to start the microservice from your workspace. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Samples.Running"></a> - <h3 class='topic' onclick='toggle(this)'>7.2 - Running in Eclipse</h3> - <div class='topic'> - <p> - The <l>microservice-samples-project.launch</l> file is already provided to allow you to quickly start - the Samples microservice. - </p> - <p> - Go to <b>Run->Run Configurations->Java Application->microservice-samples.project</b> and click <b>Run</b>. - </p> - <img class='bordered' src="doc-files/Samples.Running.1.png"> - <p> - In your console view, you can see the following output: - </p> - <img class='bordered' src="doc-files/Samples.Running.2.png"> - <p> - Now open your browser and point to <l>http://localhost:10000</l>. - You can see the following: - </p> - <img class='bordered' src="doc-files/Samples.Running.3.png"> - <p> - You have now started a REST interface on port 10000. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Samples.Building"></a> - <h3 class='topic' onclick='toggle(this)'>7.3 - Building and Running from Command-Line</h3> - <div class='topic'> - <p> - The <l>build.xml</l> file is a very basic ANT script for building the Samples microservice - into an executable jar. - </p> - <p> - To build the Samples microservice, right-click <l>build.xml</l> and select <b>Run As->Ant Build</b>. - Once complete (which takes approximately 1 second), if you refresh the project, you can see the following new directory: - </p> - <img class='bordered' src='doc-files/Samples.Building.1.png'> - <p> - If you open up a command prompt in the <l>build/microservice</l> folder, you can start your microservice as follows: - </p> - <img class='bordered' src='doc-files/Samples.Building.2.png'> - <p class='warn'> - If you get an error message saying <code class='snippet'>java.net.BindException: Address already in use</code>, this means that the microservice - is already running elsewhere, so it cannot bind to port 10000. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Samples.RestResource"></a> - <h3 class='topic' onclick='toggle(this)'>7.4 - MANIFEST.MF</h3> - <div class='topic'> - <p> - The <l>META-INF/MANIFEST.MF</l> file is used to describe the microservice. - If you open it, you'll see the following: - </p> - <p class='bcode'> - <mk>Manifest-Version</mk>: <mv>1.0</mv> - <mk>Main-Class</mk>: <mv>org.apache.juneau.microservice.RestMicroservice</mv> - <mk>Rest-Resources</mk>: <mv>org.apache.juneau.server.samples.RootResources</mv> - <mk>Main-ConfigFile</mk>: <mv>samples.cfg</mv> - <mk>Class-Path</mk>: - <mv>lib/commons-codec-1.9.jar - lib/commons-io-1.2.jar - lib/commons-logging-1.1.1.jar - lib/httpclient-4.5.jar - lib/httpcore-4.4.1.jar - lib/httpmime-4.5.jar - lib/javax.servlet-api-3.0.jar - lib/jetty-all-8.1.0.jar - lib/juneau-all-5.2.jar - lib/org.apache.commons.fileupload_1.3.1.jar - lib/derby.jar - lib/jena-core-2.7.1.jar - lib/jena-iri-0.9.2.jar - lib/log4j-1.2.16.jar - lib/slf4j-api-1.6.4.jar - lib/slf4j-log4j12-1.6.4.jar</mv> - </p> - <h6 class='topic'>Notes</h6> - <ul class='spaced-list'> - <li>The <mk>Main-Class</mk> entry is just the standard manifest entry describing the entry point for the executable jar. - The <l>org.apache.juneau.microservice.RestMicroservice</l> class is the standard microservice class for REST microservices. - Other kinds of microservices can be created by extending the {@link org.apache.juneau.microservice.Microservice} class. - <li>The <mk>Rest-Resources</mk> entry is a comma-delimited list of REST resources. - These are classes that subclass from {@link org.apache.juneau.server.RestServlet}. - This is a specialized entry used by <l>org.apache.juneau.microservice.RestMicroservice</l>. - In this case, you're pointing to a resource defined in our project, <l>org.apache.juneau.samples.RootResources</l>, which serves - as a "grouping" page for several other REST resources. - <li>The <mk>Main-ConfigFile</mk> entry points to the location of an external configuration file for our microservice. - <li>The <mk>Class-Path</mk> entry again is just the standard manifest file entry. - However, if you need to add extra libraries to your microservice, you'll need to copy them into your <l>lib</l> - directory and add them to the classpath here. - </ul> - <p class='warn'> - If you modify the manifest file and get <l>NoClassDefFoundErrors</l>, ensure that the classpath entries contain trailing spaces. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Samples.RootResources"></a> - <h3 class='topic' onclick='toggle(this)'>7.5 - RootResources</h3> - <div class='topic'> - <p> - The <l>RootResources</l> class is the main page for the REST microservice. - It serves as the jumping-off point for the other resources. - </p> - <p> - The class hierarchy for this class is: - </p> - <ul class='javahierarchy'> - <li class='a'>{@link org.apache.juneau.server.RestServlet org.apache.juneau.server.RestServlet} - <br>Contains all the REST servlet logic. - <ul> - <li class='a'>{@link org.apache.juneau.server.RestServletDefault org.apache.juneau.server.RestServletDefault} - <br>Defines default serializers and parsers, and OPTIONs page logic. - <ul> - <li class='a'>{@link org.apache.juneau.server.RestServletGroupDefault org.apache.juneau.server.RestServletGroupDefault} - <br>Specialized subclass for grouping other resources - <ul> - <li class='a'>{@link org.apache.juneau.microservice.ResourceGroup org.apache.juneau.microservice.ResourceGroup} - <br>Specialized subclass when using the Microservice API. - <ul> - <li class='c'><code>org.apache.juneau.server.samples.RootResources</code> - </ul> - </ul> - </ul> - </ul> - </ul> - <p> - Pointing a browser to the resource shows the following: - </p> - <img class='bordered' src='doc-files/Samples.Running.3.png'> - <p> - The <l>RootResources</l> class can also be defined as a servlet in a <l>web.xml</l> file: - </p> - <p class='bcode'> - <xt><web-app</xt> <xa>version</xa>=<xs>'2.3'</xs><xt>></xt> - <xt><servlet></xt> - <xt><servlet-name></xt>RootResources<xt></servlet-name></xt> - <xt><servlet-class></xt>org.apache.juneau.server.samples.RootResources<xt></servlet-class></xt> - <xt></servlet></xt> - <xt><servlet-mapping></xt> - <xt><servlet-name></xt>RootResources<xt></servlet-name></xt> - <xt><url-pattern></xt>/*<xt></url-pattern></xt> - <xt></servlet-mapping></xt> - <xt></web-app></xt> - </p> - <p> - The <l>RootResources</l> class consists entirely of annotations: - </p> - <h6 class='figure'>RootResources.java</h6> - <p class='bcode'> - <jd>/** - * Sample REST resource showing how to implement a "router" resource page. - */</jd> - <ja>@RestResource</ja>( - path=<js>"/"</js>, - messages=<js>"nls/RootResources"</js>, - properties={ - <ja>@Property</ja>(name=<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'$R{servletURI}?method=OPTIONS',source:'$R{servletURI}/source?classes=(org.apache.juneau.server.samples.RootResources)'}"</js>) - }, - children={ - HelloWorldResource.<jk>class</jk>, - MethodExampleResource.<jk>class</jk>, - RequestEchoResource.<jk>class</jk>, - TempDirResource.<jk>class</jk>, - AddressBookResource.<jk>class</jk>, - SampleRemoteableServlet.<jk>class</jk>, - PhotosResource.<jk>class</jk>, - AtomFeedResource.<jk>class</jk>, - JsonSchemaResource.<jk>class</jk>, - SqlQueryResource.<jk>class</jk>, - TumblrParserResource.<jk>class</jk>, - CodeFormatterResource.<jk>class</jk>, - UrlEncodedFormResource.<jk>class</jk>, - SourceResource.<jk>class</jk>, - ConfigResource.<jk>class</jk>, - LogsResource.<jk>class</jk>, - DockerRegistryResource.<jk>class</jk>, - ShutdownResource.<jk>class</jk> - } - ) - <jk>public class</jk> RootResources <jk>extends</jk> ResourceGroup { - <jk>private static final long</jk> <jsf>serialVersionUID</jsf> = 1L; - } - </p> - <p> - The resource bundle contains the localized strings for the resource: - </p> - <h6 class='figure'>RootResources.properties</h6> - <p class='bcode'> - <cc>#-------------------------------------------------------------------------------- - # RootResources labels - #--------------------------------------------------------------------------------</cc> - <ck>label</ck> = <cv>Root resources</cv> - <ck>description</ck> = <cv>This is an example of a router resource that is used to access other resources.</cv> - </p> - <p> - The <l>label</l> and <l>description</l> keys identify the localized values - return by the {@link org.apache.juneau.server.RestServlet#getLabel(RestRequest)} and {@link org.apache.juneau.server.RestServlet#getDescription(RestRequest)} methods. - </p> - <p> - The <l>children</l> annotation defines the child resources of this router resource. - These are resources whose paths are relative to the parent resource. - </p> - <p> - Child resources must also be subclasses of {@link org.apache.juneau.server.RestServlet}, and - must specify a {@link org.apache.juneau.server.annotation.RestResource#path()} annotation to - identify the subpath of the child. - For example, the <l>HelloWorldResource</l> class is annotated as follows: - </p> - <h6 class='figure'>HelloWorldResource.java</h6> - <p class='bcode'> - <ja>@RestResource</ja>(messages=<js>"nls/HelloWorldResource"</js>, path=<js>"/helloWorld"</js>) - <jk>public class</jk> HelloWorldResource <jk>extends</jk> Resource { - </p> - <p> - It should be noted that child resources do not need to be defined this way. - They could also be defined as servlets in the same way as the root resource. - The <l>children</l> annotation approach simply makes it easier to define them without having to touch the <l>web.xml</l> file again. - Child resources can also be defined programmatically by overriding the {@link org.apache.juneau.server.RestServlet#createChildren()} method. - </p> - <p> - Note that these router pages can be arbitrarily nested deep. - You can define many levels of router pages for arbitrarily hierarchical REST interfaces. - </p> - <p class='info'> - Let's step back and describe what's going on here:<br> - During servlet initialization of the <l>RootResources</l> object, the toolkit looks for the <l>@RestResource.children()</l> annotation. - If it finds it, it instantiates instances of each class and recursively peforms servlet initialization on them. - It then associates the child resource with the parent by the name specified by the <l>@RestResource.path()</l> annotation on the child class. - When a request for the child URL (<l>/helloWorld</l>) is received, the <l>RootResources</l> servlet gets the request and sees that the URL remainder matches one of its child resources. - It then forwards the request to the child resource for processing. - The request passed to the child resource is the same as if the child resource had been deployed independently (e.g. path-info, resource-URI, and so forth). - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Samples.HelloWorldResource"></a> - <h3 class='topic' onclick='toggle(this)'>7.6 - HelloWorldResource</h3> - <div class='topic'> - <p> - The <l>HelloWorldResource</l> class is a simple resource that prints a "Hello world!" message. - </p> - <h6 class='figure'>HelloWorldResource.java</h6> - <p class='bcode'> - <jd>/** - * Sample REST resource that prints out a simple "Hello world!" message. - */</jd> - <ja>@RestResource</ja>( - messages=<js>"nls/HelloWorldResource"</js>, - path=<js>"/helloWorld"</js>, - properties={ - <ja>@Property</ja>(name=HTMLDOC_links, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>
<TRUNCATED> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d89c8737/juneau-core/src/main/javadoc/doc-files/Microservices.1.png ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/javadoc/doc-files/Microservices.1.png b/juneau-core/src/main/javadoc/doc-files/Microservices.1.png new file mode 100644 index 0000000..e730d32 Binary files /dev/null and b/juneau-core/src/main/javadoc/doc-files/Microservices.1.png differ
