Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 47951200D26 for ; Fri, 20 Oct 2017 17:17:17 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 45F551609E1; Fri, 20 Oct 2017 15:17:17 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 131A1160BCB for ; Fri, 20 Oct 2017 17:17:14 +0200 (CEST) Received: (qmail 35585 invoked by uid 500); 20 Oct 2017 15:17:14 -0000 Mailing-List: contact commits-help@juneau.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@juneau.apache.org Delivered-To: mailing list commits@juneau.apache.org Received: (qmail 35576 invoked by uid 99); 20 Oct 2017 15:17:14 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd3-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Oct 2017 15:17:14 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd3-us-west.apache.org (ASF Mail Server at spamd3-us-west.apache.org) with ESMTP id 1DEEB1807A3 for ; Fri, 20 Oct 2017 15:17:13 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd3-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -3.721 X-Spam-Level: X-Spam-Status: No, score=-3.721 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_NUMSUBJECT=0.5, KAM_SHORT=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd3-us-west.apache.org [10.40.0.10]) (amavisd-new, port 10024) with ESMTP id SSHkgwpnh22y for ; Fri, 20 Oct 2017 15:16:59 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP id 937F05F566 for ; Fri, 20 Oct 2017 15:16:57 +0000 (UTC) Received: (qmail 35287 invoked by uid 99); 20 Oct 2017 15:16:57 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Oct 2017 15:16:57 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 4869ADFAE4; Fri, 20 Oct 2017 15:16:56 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jamesbognar@apache.org To: commits@juneau.incubator.apache.org Date: Fri, 20 Oct 2017 15:16:57 -0000 Message-Id: In-Reply-To: <36528e724b7144179392853bb3dc7996@git.apache.org> References: <36528e724b7144179392853bb3dc7996@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/3] incubator-juneau-website git commit: Upload pages for v7.0.0 archived-at: Fri, 20 Oct 2017 15:17:17 -0000 http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/index.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/index.html b/content/7.0.0/index.html new file mode 100644 index 0000000..be3b0ab --- /dev/null +++ b/content/7.0.0/index.html @@ -0,0 +1,204 @@ + + + + + + + + + + + + + Apache Juneau Universal Serialization and REST API Library + + + + + + +
+ + + + + +
+ Loading... +
+ + +
+ + + http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/issues.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/issues.html b/content/7.0.0/issues.html new file mode 100644 index 0000000..ebd0806 --- /dev/null +++ b/content/7.0.0/issues.html @@ -0,0 +1,34 @@ + + + + + + +
Issues
+

+ Juneau has no bugs. However, in the extremely unlikely event that you happen to find a bug, please report it at the JIRA repository listed below. +

+ +

+ External developers should use the following categories for requests: +

+
    +
  • Bug - Broken functionality. +
  • Feature Request - Requests for brand new functionality. +
  • Improvement - Requests for improvements to existing functionality. +
  • Wish - Trivial requests. +
+
Security Vulnerabilities
+

+ If you discover any security vulnerabilities in this code, please refer to the instructions found here: +

+ + + http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/marshall.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/marshall.html b/content/7.0.0/marshall.html new file mode 100644 index 0000000..5796661 --- /dev/null +++ b/content/7.0.0/marshall.html @@ -0,0 +1,417 @@ + + + + + + + + + + +
juneau-marshall
+
+
Maven Dependency
+

+ <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-marshall</artifactId> + <version>7.0.0</version> + </dependency> +

+ +
Java Library
+

+ juneau-marshall-7.0.0.jar +

+ +
OSGi Module
+

+ org.apache.juneau.marshall_7.0.0.jar +

+ +

+ The juneau-marshall library includes easy-to-use and highly customizable serializers and parsers + based around a common API. + They provide support for the following languages: +

+
    +
  • JSON +
  • XML +
  • HTML +
  • UON (URL-Encoded Object Notation) +
  • URL-Encoding +
  • MessagePack +
  • SOAP/XML +
  • CSV +
  • BSON (coming soon) +
  • YAML (coming soon) +
  • Protobuf (coming soon) +
+

+ The default serializers can often be used to serialize POJOs in a single line of code: +

+

+ // A simple bean + public class Person { + public String name = "John Smith"; + public int age = 21; + } + + Person p = new Person(); + + // Produces: + // "{name:'John Smith',age:21}" + String laxJson = JsonSerializer.DEFAULT_LAX.serialize(p); + + // Produces: + // "{"name":"John Smith","age":21}" + String strictJson = JsonSerializer.DEFAULT.serialize(p); + + // Produces: + // <object> + // <name>John Smith</name> + // <age>21</age> + // </object> + String xml = XmlSerializer.DEFAULT_SIMPLE.serialize(p); + + // Produces: + // <table> + // <tr><td>name</td><td>John Smith</td></tr> + // <tr><td>age</td><td>21</td></tr> + // </table> + String html = HtmlSerializer.DEFAULT.serialize(p); + + // Same as Html, but wraps it in HTML and BODY elements with page title/description/links: + String htmlDoc = HtmlDocSerializer.DEFAULT.serialize(p); + + // Produces: + // name='John+Smith'&age=21 + String urlEncoding = UrlEncodingSerializer.DEFAULT.serialize(p); + + // Produces: + // (name='John Smith',age=21) + String uon = UonSerializer.DEFAULT.serialize(p); + + // Produces: + // 82 A4 name AA 4A John Smith 68 A3 age 15 + byte[] messagePack = MsgPackSerializer.DEFAULT.serialize(p); +

+

+ Parsing back into POJOs is equally simple for any of the supported languages shown above. + Language fragments are also supported. +

+

+ JSON parsing shown here: +

+

+ // Use one of the predefined parsers. + ReaderParser parser = JsonParser.DEFAULT; + + // Parse a JSON object (creates a generic ObjectMap). + String json = "{name:'John Smith',age:21}"; + Map m1 = parser.parse(json, Map.class); + + // Parse a JSON string. + json = "'foobar'"; + String s2 = parser.parse(json, String.class); + + // Parse a JSON number as a Long or Float. + json = "123"; + Long l3 = parser.parse(json, Long.class); + Float f3 = parser.parse(json, Float.class); + + // Parse a JSON object as a bean. + json = "{name:'John Smith',age:21}"; + Person p4 = parser.parse(json, Person.class); + + // Parse a JSON object as a HashMap<String,Person>. + json = "{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"; + Map<String,Person> m5 = parser.parse(json, HashMap.class, String.class, Person.class); + + // Parse a JSON object as a HashMap<String,LinkedList<Person>>. + json = "{a:[{name:'John Smith',age:21},{name:'Joe Smith',age:42}]}"; + Map<String,List<Person>> m6 = parser.parse(json, HashMap.class, String.class, LinkedList.class, Person.class); + + // Parse a JSON array of integers as a Collection of Integers or int[] array. + json = "[1,2,3]"; + List<Integer> l7 = parser.parse(json, LinkedList.class, Integer.class); + int[] i7 = parser.parse(json, int[].class); + + // Parse arbitrary input into ObjectMap or ObjectList objects + // (similar to JSONObject/JSONArray but generalized for all languages). + json = "{name:'John Smith',age:21}"; + ObjectMap m8a = parser.parse(json, ObjectMap.class); + int age = m8a.getInt("age"); + ObjectMap m8b = (ObjectMap)parser.parse(json, Object.class); // Equivalent. + + json = "[1,true,null]"; + ObjectList l9a = parser.parse(json, ObjectList.class); + boolean b = l9a.getBoolean(1); + ObjectList l9b = (ObjectList)parser.parse(json, Object.class); // Equivalent. +

+ +
Features
+
    +
  • Serializers can send output directly to Writers, OutputStreams, Files, Strings, or byte arrays. +
  • Parsers can receive input directly from Readers, InputStreams, Files, Strings, or byte arrays. +
  • Parsers can reconstruct arbitrarily complex data structures consisting of maps, collections, beans, and other POJOs. +
  • 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. +
  • Supported languages are highly-customizable and powerful. For example, JSON support includes: +
      +
    • Support for variants such as LAX syntax (unquoted attributes and single quotes). +
    • Support for embedded Javascript comments. +
    • Fully RFC1759 compliant. +
    • 20% faster than Jackson. +
    +
+

+

+ Serializers and parsers are builder-based. Build from scratch or clone existing instances. Lots of configuration options available for all the languages. +

+

+ // Create a serializer from scratch using a builder + JsonSerializer serializer = new JsonSerializerBuilder() + .simple() // Simple mode + .sq() // Use single quotes + .pojoSwaps( // Swap unserializable classes with surrogate POJOs + IteratorSwap.class, // Iterators swapped with lists + ByteArrayBase64Swap.class, // byte[] swapped with base-64 encoded strings + CalendarSwap.ISO8601DT.class // Calendars swapped with ISO8601-compliant strings + ) + .beanFilters(MyBeanFilter.class) // Control how bean properties are handled + .timeZone(TimeZone.GMT) // For serializing Calendars + .locale(Locale.JAPAN) // For timezone-specific serialization + .sortCollections(true) // For locale-specific serialization + .sortProperties(true) // Various behavior settings + .trimNullProperties(true) + .trimStrings(true) + .methodVisibility(PROTECTED) // Control which fields/methods are serialized + .beanDictionary( // Adds type variables for resolution during parsing + MyBeanA.class, + MyBeanB.class + ) + .debug(true) // Add debug output + .build(); + + // Clone an existing serializer and modify it to use single-quotes + JsonSerializer serializer = JsonSerializer.DEFAULT.builder() + .sq() + .build(); +

+


+

+ 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. +

+
    +
  • Transforms +
      +
    • Bean filters - Control how bean properties are handled (naming conventions, ordering, visibility,...). +
    • POJO swaps - Replace non-serializable POJOs with serializable equivalents. +
      Predefined swaps provided for common cases: ByteArrayBase64Swap, 50+ variants of Calendar/Date swaps, Enumeration/Iterator swaps. +
    +
  • Annotations +
    Various annotations available for your POJO classes that are recognized by ALL serializers and parsers: +
    @Bean, @Pojo, @BeanIgnore, @BeanParam, @BeanProperty, @NameProperty, @ParentProperty +
    +
    Annotations also provided for language-specific behaviors where it makes sense: +
    @Json, @Html, @Xml, @UrlEncoding +
    +
    All annotations have programmatic equivalents when you don't have access to POJO source. + +
  • Swap methods +
    By default, various instance and static methods and constructors are automatically detected and supported: +
    valueOf(String), parse(String), parseString(String), forName(String), forString(String), + fromString(String), T(String), Object swap(BeanSession), T unswap(BeanSession, T.class) +
+ + + +

+

+ 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. +

+

+ ( + id=1, + name='John+Smith', + uri=http://sample/addressBook/person/1, + addressBookUri=http://sample/addressBook, + birthDate=1946-08-12T00:00:00Z, + addresses=@( + ( + uri=http://sample/addressBook/address/1, + personUri=http://sample/addressBook/person/1, + id=1, + street='100+Main+Street', + city=Anywhereville, + state=NY, + zip=12345, + isCurrent=true + ) + ) + ) +

+ + + +

+

+ Lots of shortcuts are provided throughout the API to simplify tasks, and the APIs are often useful for debugging and logging purposes as well... +

+

+ // Create JSON strings from scratch using fluent-style code. + String jsonObject = new ObjectMap().append("foo","bar").toString(); + String jsonArray = new ObjectList().append("foo").append(123).append(null).toString(); + + // Create maps and beans directly from JSON. + Map<String,Object> myMap = new ObjectMap("{foo:'bar'}"); + List<Object> myList = new ObjectList("['foo',123,null]"); + + // Load a POJO from a JSON file. + MyPojo myPojo = JsonParser.DEFAULT.parse(new File("myPojo.json")); + + // Serialize POJOs and ignore exceptions (great for logging) + String json = JsonSerializer.DEFAULT_LAX.toString(myPojo); + + // Dump a POJO to the console. + JsonSerializer.DEFAULT_LAX.println(myPojo); + + // Delayed serialization. + // (e.g. don't serialize an object if it's not going to be logged). + logger.log(FINE, "My POJO was: {0}", new StringObject(myPojo)); + logger.log(FINE, "My POJO in XML was: {0}", new StringObject(XmlSerializer.DEFAULT, myPojo)); + + String message = new StringMessage("My POJO in {0}: {1}", "JSON", new StringObject(myPojo)).toString(); + + // Create a 'REST-like' wrapper around a POJO. + // Allows you to manipulate POJO trees using URIs and GET/PUT/POST/DELETE commands. + PojoRest pojoRest = new PojoRest(myPojo); + pojoRest.get(String.class, "addressBook/0/name"); + pojoRest.put("addressBook/0/name", "John Smith"); +

+


+

+ SerializerGroup and ParserGroup classes allow serializers and parsers + to be retrieved by W3C-compliant HTTP Accept and Content-Type values: +

+

+ // Construct a new serializer group with configuration parameters that get applied to all serializers. + SerializerGroup sg = new SerializerGroupBuilder() + .append(JsonSerializer.class, UrlEncodingSerializer.class); + .ws() // or .setUseWhitespace(true) + .pojoSwaps(CalendarSwap.ISO8601DT.class) + .build(); + + // Find the appropriate serializer by Accept type and serialize our POJO to the specified writer. + // Fully RFC2616 compliant. + sg.getSerializer("text/invalid, text/json;q=0.8, text/*;q:0.6, *\/*;q=0.0") + .serialize(myPersonObject, myWriter); + + // Construct a new parser group with configuration parameters that get applied to all parsers. + ParserGroup pg = new ParserGroupBuilder() + .append(JsonParser.class, UrlEncodingParser.class); + .pojoSwaps(CalendarSwap.ISO8601DT.class) + .build(); + + Person p = pg.getParser("text/json").parse(myReader, Person.class); +

+ +


+ + +
+ + + + + +
juneau-marshall-rdf
+
+
Maven Dependency
+

+ <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-marshall-rdf</artifactId> + <version>7.0.0</version> + </dependency> +

+ +
Java Library
+

+ juneau-marshall-rdf-7.0.0.jar +

+ +
OSGi Module
+

+ org.apache.juneau.marshall.rdf_7.0.0.jar +

+ +

+ The juneau-marshall-rdf library provides additional serializers and parsers for RDF. + These rely on the Apache Jena library to provide support for the following languages: +

+
    +
  • RDF/XML +
  • RDF/XML-Abbrev +
  • N-Triple +
  • Turtle +
  • N3 +
+

+ The serializers and parsers work identically to those in juneau-marshall, but are + packaged separately so that you don't need to pull in the Jena dependency unless you need it. +

+ +

+ // A simple bean + public class Person { + public String name = "John Smith"; + public int age = 21; + } + + // Serialize a bean to JSON, XML, or HTML + Person p = new Person(); + + // 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> + String rdfXml = RdfSerializer.DEFAULT_XMLABBREV.serialize(p); + + // Produces: + // @prefix jp: <http://www.apache.org/juneaubp/> . + // @prefix j: <http://www.apache.org/juneau/> . + // [] jp:age "21" ; + // jp:name "John Smith" . + String rdfN3 = RdfSerializer.DEFAULT_N3.serialize(p); + + // Produces: + // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/name> "John Smith" . + // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/age> "21" . + String rdfNTriple = RdfSerializer.DEFAULT_NTRIPLE.serialize(p); +

+ + +
+ + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/microservice.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/microservice.html b/content/7.0.0/microservice.html new file mode 100644 index 0000000..ce7fe29 --- /dev/null +++ b/content/7.0.0/microservice.html @@ -0,0 +1,227 @@ + + + + + + + + + + +
juneau-microservice
+
+ +

+ 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. +

+ + + + + +
juneau-microservice-server
+
+ +
Maven Dependency
+

+ <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-microservice-server</artifactId> + <version>7.0.0</version> + </dependency> +

+ +
Java Library
+

+ juneau-microservice-server-7.0.0.jar +

+ +
OSGi Module
+

+ org.apache.juneau.microservice.server_7.0.0.jar +

+ +

+ 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: +

+
    +
  • An executable jar file that starts up a REST interface in milliseconds. +
  • A configurable jetty.xml file. +
  • An external INI file that can be used to configure your REST resources on the fly. +
+

+ The microservice API was originally designed for and particularly suited for use in Docker containers. +

+

+ REST microservices can also be started programmatically in existing code: +

+

+ RestMicroservice myRestService = new RestMicroservice() + .setConfig("microservice.cfg", false) + .setJettyXml("my-jetty.xml"); + myRestService.start(); + URI uri = myRestService.getURI(); +

+

+ The provided microservice.cfg template file gives you a starting point for defining your microservice: +

+

+ #================================================================================ + # Basic configuration file for SaaS microservices + # Subprojects can use this as a starting point. + #================================================================================ + + #================================================================================ + # REST settings + #================================================================================ + [REST] + + # The location of the jetty.xml file to use for configuring Jetty. + jettyXml = jetty.xml + + # Stylesheet to use for HTML views. + # The default options are: + # - styles/juneau.css + # - styles/devops.css + # Other stylesheets can be referenced relative to the servlet package or working + # directory. + stylesheet = styles/devops.css + + # What to do when the config file is saved. + # Possible values: + # NOTHING - Don't do anything. + # RESTART_SERVER - Restart the Jetty server. + # RESTART_SERVICE - Shutdown and exit with code '3'. + saveConfigAction = RESTART_SERVER + + #================================================================================ + # Logger settings + # See FileHandler Java class for details. + #================================================================================ + [Logging] + + # The directory where to create the log file. + # Default is "." + logDir = logs + + # The name of the log file to create for the main logger. + # The logDir and logFile make up the pattern that's passed to the FileHandler + # constructor. + # If value is not specified, then logging to a file will not be set up. + logFile = microservice.%g.log + + # Whether to append to the existing log file or create a new one. + # Default is false. + append = + + # The SimpleDateFormat format to use for dates. + # Default is "yyyy.MM.dd hh:mm:ss". + dateFormat = + + # The log message format. + # The value can contain any of the following variables: + # {date} - The date, formatted per dateFormat. + # {class} - The class name. + # {method} - The method name. + # {logger} - The logger name. + # {level} - The log level name. + # {msg} - The log message. + # {threadid} - The thread ID. + # {exception} - The localized exception message. + # Default is "[{date} {level}] {msg}%n". + format = + + # The maximum log file size. + # Suffixes available for numbers. + # See ConfigFile.getInt(String,int) for details. + # Default is 1M. + limit = 10M + + # Max number of log files. + # Default is 1. + count = 5 + + # Default log levels. + # Keys are logger names. + # Values are serialized Level POJOs. + levels = { org.apache.juneau:'INFO' } + + # Only print unique stack traces once and then refer to them by a simple 8 character hash identifier. + # Useful for preventing log files from filling up with duplicate stack traces. + # Default is false. + useStackTraceHashes = true + + # The default level for the console logger. + # Default is WARNING. + consoleLevel = + + #================================================================================ + # System properties + #-------------------------------------------------------------------------------- + # These are arbitrary system properties that are set during startup. + #================================================================================ + [SystemProperties] + + # Configure Jetty for StdErrLog Logging + org.eclipse.jetty.util.log.class = org.eclipse.jetty.util.log.StrErrLog + + # Jetty logging level + org.eclipse.jetty.LEVEL = WARN +

+

+ This external config file is meant to be used for all of your resource configurations. + APIs are provided in the REST Server APIs for easily accessing these values programmatically, or + by using "$C{...}" variables in your @RestResource and @RestMethod annotations. +

+

+ Various predefined reusable REST resource classes are provided for accessing log files, viewing and editing the config file, etc... + These allow you to quickly put together sophisticated REST microservices. +

+ + +
+ + + + + +
juneau-microservice-template
+
+ +
Archive File
+

+ my-microservice-7.0.0.zip +

+ +

+ The juneau-microservice-template module is a bare-bones microservice project that can be + used as a starting point for creating your own microservice. +

+

+ The template project ships as a zipped Eclipse project that can be quickly imported into your + workspace as an Eclipse project called "my-microservice". +

+

+ Once loaded, you should see the following project structure: +

+ +

+ The microservice can be started from the my-microservice.launch file. + It will start up the microservice on port 10000 which you can then view through a browser: +

+ + + +
+
+ + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/rest-client.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/rest-client.html b/content/7.0.0/rest-client.html new file mode 100644 index 0000000..088d7d7 --- /dev/null +++ b/content/7.0.0/rest-client.html @@ -0,0 +1,168 @@ + + + + + + + + + + +
juneau-rest-client
+
+
Maven Dependency
+

+ <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-rest-client</artifactId> + <version>7.0.0</version> + </dependency> +

+ +
Java Library
+

+ juneau-rest-client-7.0.0.jar +

+ +
OSGi Module
+

+ org.apache.juneau.rest.client_7.0.0.jar +

+ +

+ The REST client API allows you to access REST interfaces using POJOs: +

+

+ // Create a reusable JSON client. + RestClient client = new RestClientBuilder().build(); + + // The address of the root resource. + String url = "http://localhost:10000/systemProperties"; + + // Do a REST GET against a remote REST interface and convert + // the response to an unstructured ObjectMap object. + Map m1 = client.doGet(url).getResponse(TreeMap.class); + + // Add some new system properties. + // Use XML as the transport medium. + client = new RestClientBuilder(XmlSerializer.class, XmlParser.class).build(); + Properties p = new Properties(); + p.load(reader); + int returnCode = client.doPost(url + "/systemProperties", p).execute(); +

+

+ 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. +

+

+

+ The remote proxy interface API allows you to invoke server-side POJO methods on the client side using REST (i.e. RPC over REST): +

+

+ // Get an interface proxy. + IAddressBook ab = restClient.getRemoteableProxy(IAddressBook.class); + + // Invoke a method on the server side and get the returned result. + Person p = ab.createPerson( + new Person( + "John Smith", + "Aug 1, 1999", + new Address("My street", "My city", "My state", 12345, true) + ) + ); +

+

+ Although the client API is not dependent on the juneau-rest-server module, the server + module provides some convenience APIs for exposing remoteable proxies on the server side: +

+
    +
  1. Extending from RemoteableServlet. +
  2. Using a @RestMethod(name=PROXY) annotation on a Java method. +
+

+ The RemoteableServlet class is a simple specialized servlet with an abstract getServiceMap() + method to define the server-side POJOs: +

+

+ @RestResource( + path="/remote" + ) + public class SampleRemoteableServlet extends RemoteableServlet { + + // Our server-side POJO. + AddressBook addressBook = new AddressBook(); + + @Override /* RemoteableServlet */ + protected Map<Class<?>,Object> getServiceMap() throws Exception { + Map<Class<?>,Object> m = new LinkedHashMap<Class<?>,Object>(); + + // In this simplified example, we expose the same POJO service under two different interfaces. + // One is IAddressBook which only exposes methods defined on that interface, and + // the other is AddressBook itself which exposes all methods defined on the class itself (dangerous!). + m.put(IAddressBook.class, addressBook); + m.put(AddressBook.class, addressBook); + return m; + } + } +

+

+ The @RestMethod(name=PROXY) 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: +

+

+ // Our exposed proxy object. + @RestMethod(name=PROXY, path="/addressbookproxy/*") + public IAddressBook getProxy() { + return addressBook; + } +

+

+ 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. +

+

+ 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! +

+

+ The parameters and return types of the Java methods can be any of the supported serializable and parsable types in POJO Categories. + 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. +

+

+ The RemoteableServlet 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. +

+

+

+ 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. +

+

+ 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. +

+

+ @Remoteable + public interface MyProxyInterface { + + @RemoteMethod(httpMethod=POST, path="/method") + String doSomething(@Header("E-Tag") UUID etag, @Query("debug") boolean debug, @Body MyPojo pojo); + } + + RestClient client = new RestClientBuilder().build(); // Default is JSON + MyProxyInterface p = client.getRemoteableProxy(MyProxyInterface.class, "http://hostname/some/rest/interface"); + String response = p.doSomething(UUID.generate(), true, new MyPojo()); +

+ + +
+ + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/rest-server.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/rest-server.html b/content/7.0.0/rest-server.html new file mode 100644 index 0000000..a4c2b85 --- /dev/null +++ b/content/7.0.0/rest-server.html @@ -0,0 +1,748 @@ + + + + + + + + + + + +
juneau-rest-server
+
+
Maven Dependency
+

+ <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-rest-server</artifactId> + <version>7.0.0</version> + </dependency> +

+ +
Java Library
+

+ juneau-rest-server-7.0.0.jar +

+ +
OSGi Module
+

+ org.apache.juneau.rest.server_7.0.0.jar +

+ +

+ The REST server API builds upon the SerializerGroup and ParserGroup classes + to provide annotated REST servlets that automatically negotiate the HTTP media types for you. +
Developers simply work with requests, responses, headers, path variables, query parameters, and form data as POJOs. +
It allows you to create sophisticated REST interfaces using tiny amounts of code. +

+

+ 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: +

+
    +
  • HTML for viewing POJOs in easy-to-read format in a browser. +
  • JSON for interacting through Javascript. +
  • XML for interacting with other applications. +
  • RDF for interacting with triple stores. +
  • URL-Encoding for interacting through HTML forms. +
  • MessagePack for efficiently transmitting large amounts of data. +
+

+ A simple example that supports all languages: +

+

+ @RestResource( + path="/systemProperties", + title="System properties resource" + ) + public class SystemPropertiesResource extends RestServletDefault { + + @RestMethod(name=GET, path="/") + public Map getSystemProperties(@Query("sort") boolean sort) throws Throwable { + if (sort) + return new TreeMap(System.getProperties()); + return System.getProperties(); + } + + @RestMethod(name=GET, path="/{propertyName}") + public String getSystemProperty(@Path String propertyName) throws Throwable { + return System.getProperty(propertyName); + } + + @RestMethod(name=PUT, path="/{propertyName}", guards=AdminGuard.class) + public String setSystemProperty(@Path String propertyName, @Body String value) { + System.setProperty(propertyName, value); + return "OK"; + } + + @RestMethod(name=POST, path="/", guards=AdminGuard.class) + public String setSystemProperties(@Body java.util.Properties newProperties) { + System.setProperties(newProperties); + return "OK"; + } + + @RestMethod(name=DELETE, path="/{propertyName}", guards=AdminGuard.class) + public String deleteSystemProperty(@Path String propertyName) { + System.clearProperty(propertyName); + return "OK"; + } + } +

+

+ 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. +

+

+ @RestResource( + path="/systemProperties", + title="System properties resource", + description="REST interface for performing CRUD operations on system properties.", + messages="nls/SystemPropertiesResource", // Location of localized messages. + + // Widget used for content-type pull-down menu. + widgets={ + ContentTypeMenuItem.class + }, + + // Links on the HTML rendition page. + // "request:/..." URIs are relative to the request URI. + // "servlet:/..." URIs are relative to the servlet URI. + htmldoc=@HtmlDoc( + + // Custom navigation links. + links={ + "up: request:/..", + "options: servlet:/?method=OPTIONS", + "form: servlet:/formPage", + "$W{ContentTypeMenuItem}", + "source: $C{Source/gitHub}/org/apache/juneau/examples/rest/SystemPropertiesResource.java" + }, + + // Custom page text in aside section. + aside={ + "<div style='max-width:800px' class='text'>", + " <p>Shows standard GET/PUT/POST/DELETE operations and use of Swagger annotations.</p>", + "</div>" + }, + + // Custom CSS styles applied to HTML view. + style={ + "aside {display:table-caption;}" + } + ), + + // Set serializer, parser, and REST context properties. + properties={ + @Property(name=SERIALIZER_quoteChar, value="'") + }, + + // Add compression support. + encoders=GzipEncoder.class, + + // Augment generated Swagger information. + swagger=@ResourceSwagger( + contact="{name:'John Smith',email:'john@smith.com'}", + license="{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}", + version="2.0", + termsOfService="You're on your own.", + tags="[{name:'Java',description:'Java utility',externalDocs:{description:'Home page',url:'http://juneau.apache.org'}}]", + externalDocs="{description:'Home page',url:'http://juneau.apache.org'}" + ) + ) + public class SystemPropertiesResource extends RestServlet { + + @RestMethod( + name=GET, path="/", + summary="Show all system properties", + description="Returns all system properties defined in the JVM.", + + // Augment generated Swagger information. + swagger=@MethodSwagger( + parameters={ + @Parameter(in="query", name="sort", description="Sort results alphabetically.", _default="false") + }, + responses={ + @Response(value=200, description="Returns a map of key/value pairs.") + } + ) + ) + public Map getSystemProperties(@Query("sort") boolean sort) throws Throwable { + if (sort) + return new TreeMap(System.getProperties()); + return System.getProperties(); + } + + ... + } +

+ +

+ In HTML, our resource looks like this: +

+ + +

+ When combined with the support for HTML5 beans, simple HTML forms can be constructed for easy input and output + using nothing more than Java: +

+

+ import static org.apache.juneau.dto.html5.HtmlBuilder.*; + + @RestMethod( + name=GET, path="/formPage", + summary="Form entry page", + description="A form post page for setting a single system property value.", + guards=AdminGuard.class + ) + public Form getFormPage() { + return form().method(POST).action("formPagePost").children( + table( + tr( + th("Set system property").colspan(2) + ), + tr( + td("Name: "), td(input("text").name("name")) + ), + tr( + td("Value: "), td(input("text").name("value")) + ) + ), + button("submit","Click me!").style("float:right") + ); + } + + @RestMethod( + name=POST, path="/formPagePost", + description="Accepts a simple form post of a system property name/value pair.", + guards=AdminGuard.class + ) + public Redirect formPagePost(@FormData("name") String name, @FormData("value") String value) { + System.setProperty(name, value); + return new Redirect("servlet:/"); // Redirect to the servlet top page. + } +

+ +

+ The REST API is built on top of Servlets, making them easy to deploy in any JEE environment. +

+

+ REST Java methods can return any of the following objects: +
POJOs, Readers, InputStreams, ZipFiles, Redirects, Streamables, and Writables. +

+

+ Or add your own handlers for other types. +

+

+ REST Java methods can be passed any of the following objects in any order: +

+
    +
  • Low-level request/response objects: +
    HttpServletRequest, HttpServletResponse, RestRequest, RestResponse. +
  • Intermediate-level objects: +
    RequestHeaders, RequestQuery, RequestFormData, RequestPathMatch, RequestBody. +
  • All RFC 2616 request header objects: +
    Accept, AcceptLanguage, AcceptEncoding... +
  • Annotated parameters: +
    @Header, @Query, @FormData, @Path, @PathRemainder, @Body. +
  • Other objects: +
    Locale, ResourceBundle, MessageBundle, InputStream, OutputStream, Reader, Writer... +
  • User-defined parameter types. +
+

+ It's up to you how you want to define your REST methods. + As a general rule, there are 3 broad approaches typically used: +

+ +
Methodology #1 - Annotated parameters
+

+ This approach uses annotated parameters for retrieving input from the request. +

+

+ @RestMethod(name=GET, path="/example1/{p1}/{p2}/{p3}/*") + public String example1( + @Method String method, // HTTP method. + @Path String p1, // Path variables. + @Path int p2, + @Path UUID p3, + @Query("q1") int q1, // Query parameters. + @Query("q2") String q2, + @Query("q3") UUID q3, + @PathRemainder String remainder, // Path remainder after pattern match. + @Header("Accept-Language") String lang, // Headers. + @Header("Accept") String accept, + @Header("DNT") int doNotTrack + ) { + + // Send back a simple String response + String output = String.format( + "method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d", + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + return output; + } +

+ +
Methodology #2 - Low-level request/response objects
+

+ This approach uses low-level request/response objects to perform the same as above. +

+

+ @RestMethod(name=GET, path="/example2/{p1}/{p2}/{p3}/*") + public String example2( + RestRequest req, // A direct subclass of HttpServletRequest. + RestResponse res // A direct subclass of HttpServletResponse. + ) { + + // HTTP method. + String method = req.getMethod(); + + // Path variables. + RequestPathMatch path = req.getPathMatch(); + String p1 = path.get("p1", String.class); + int p2 = path.get("p2", int.class); + UUID p3 = path.get("p3", UUID.class); + + // Query parameters. + RequestQuery query = req.getQuery(); + int q1 = query.get("q1", 0, int.class); + String q2 = query.get("q2", String.class); + UUID q3 = query.get("q3", UUID.class); + + // Path remainder after pattern match. + String remainder = req.getPathMatch().getRemainder(); + + // Headers. + String lang = req.getHeader("Accept-Language"); + String accept = req.getHeader("Accept"); + int doNotTrack = req.getHeaders().get("DNT", int.class); + + // Send back a simple String response + String output = String.format( + "method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d", + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + res.setOutput(output); // Or use getWriter(). + } +

+ +
Methodology #3 - Intermediate-level API objects
+

+ This approach is sort of the middle ground where you get access functional area APIs. +

+

+ @RestMethod(name=GET, path="/example3/{p1}/{p2}/{p3}/*") + public String example3( + HttpMethod method, // HTTP method. + RequestPathMatch path, // Path variables. + RequestQuery query, // Query parameters. + RequestHeaders headers, // Headers. + AcceptLanguage lang, // Specific header classes. + Accept accept + ) { + + // Path variables. + String p1 = path.get("p1", String.class); + int p2 = path.get("p2", int.class); + UUID p3 = path.get("p3", UUID.class); + + // Query parameters. + int q1 = query.get("q1", 0, int.class); + String q2 = query.get("q2", String.class); + UUID q3 = query.get("q3", UUID.class); + + // Path remainder after pattern match. + String remainder = path.getRemainder(); + + // Headers. + int doNotTrack = headers.get("DNT", int.class); + + // Send back a simple String response + String output = String.format( + "method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d", + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + res.setOutput(output); + } +

+

+ All three are completely equivalent. It's up to your own coding preferences which methodology you use. +

+

+

+ Lifecycle hooks allow you to hook into lifecycle events of the servlet or REST call. + Like @RestMethod methods, the list of parameters are specified by the developer. +

+

+ For example, if you want to add an initialization method to your resource: +

+

+ @RestResource(...) + public class MyResource { + + // Our database. + private Map<Integer,Object> myDatabase; + + @RestHook(INIT) + public void initMyDatabase(RestConfig config) throws Exception { + myDatabase = new LinkedHashMap<>(); + } + } +

+

+ Or if you want to intercept REST calls: +

+

+ @RestResource(...) + public class MyResource { + + // Add a request attribute to all incoming requests. + @RestHook(PRE_CALL) + public void onPreCall(RestRequest req) { + req.setAttribute("foo", "bar"); + } + } +

+

+ The hook events can be broken down into two categories: +

+
    +
  • Resource lifecycle events: +
      +
    • INIT - Right before initialization. +
    • POST_INIT - Right after initialization. +
    • POST_INIT_CHILD_FIRST - Right after initialization, but run child methods first. +
    • DESTROY - Right before servlet destroy. +
    +
  • REST call lifecycle events: +
      +
    • START_CALL - At the beginning of a REST call. +
    • PRE_CALL - Right before the @RestMethod method is invoked. +
    • POST_CALL - Right after the @RestMethod method is invoked. +
    • END_CALL - At the end of the REST call after the response has been flushed. +
    +
+

+

+ Auto-generated OPTIONS pages are constructed from Swagger DTO beans, here shown serialized as HTML: +

+ +

+ Swagger documentation can be populated from annotations (as above), resource bundles, or Swagger JSON files. +

+

+ 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: +

+

+ @RestMethod(name=OPTIONS, path="/*") + public Swagger getOptions(RestRequest req) { + return req.getSwagger(); + } +

+


+

+ Navigable hierarchies of REST resources are easy to set up either programmatically or through annotations. +
+ The following example is the RootResources class from the REST examples showing how to construct + a grouping of resources using the children() annotation: +

+

+ @RestResource( + path="/", + title="Root resources", + description="Example of a router resource page.", + widgets={ + PoweredByApache.class, + ContentTypeMenuItem.class + }, + htmldoc=@HtmlDoc( + links={ + "options: ?method=OPTIONS", + "$W{ContentTypeMenuItem}", + "source: $C{Source/gitHub}/org/apache/juneau/examples/rest/RootResources.java" + }, + aside={ + "<div style='max-width:400px' class='text'>", + " <p>This is an example of a 'router' page that serves as a jumping-off point to child resources.</p>", + " <p>Resources can be nested arbitrarily deep through router pages.</p>", + " <p>Note the options link provided that lets you see the generated swagger doc for this page.</p>", + " <p>Also note the source link on these pages to view the source code for the page.</p>", + " <p>All content on pages in the UI are serialized POJOs. In this case, it's a serialized array of beans with 2 properties, 'name' and 'description'.</p>", + " <p>Other features (such as this aside) are added through annotations.</p>", + "</div>" + }, + footer="$W{PoweredByApache}" + ), + children={ + HelloWorldResource.class, + PetStoreResource.class, + SystemPropertiesResource.class, + MethodExampleResource.class, + RequestEchoResource.class, + TempDirResource.class, + AddressBookResource.class, + SampleRemoteableServlet.class, + PhotosResource.class, + AtomFeedResource.class, + JsonSchemaResource.class, + SqlQueryResource.class, + TumblrParserResource.class, + CodeFormatterResource.class, + UrlEncodedFormResource.class, + ConfigResource.class, + LogsResource.class, + DockerRegistryResource.class, + ShutdownResource.class + } + ) + public class RootResources extends RestServletGroupDefault { /* No code needed! */ } +

+

+ The above resource when rendered in HTML shows how easy it is to discover and navigate to child resources using a browser: +

+ +

+ Resources can be nested arbitrarily deep. + The @RestResource and @RestMethod annotations can be applied to any classes, not just + servlets. The only requirement is that the top-level resource be a subclass of RestServlet as a hook into + the servlet container. +

+ +

+ The juneau-examples-rest project includes various other examples that highlight some of the + capabilities of the REST servlet API. +
+ For example, the PetStoreResource class shows some advanced features such as using POJO renders + and converters, and HTML widgets. +

+ + +

+ The beans being serialized are shown here: +

+

+ // Our bean class. + public class Pet { + + @Html(link="servlet:/{id}") // Creates a hyperlink in HTML view. + @NameProperty // Links the parent key to this bean. + public int id; + + public String name; + public Kind kind; + + @BeanProperty(format="$%.2f") // Renders price in dollars. + public float price; + + @BeanProperty(swap=DateSwap.RFC2822D.class) // Renders dates in RFC2822 format. + public Date birthDate; + + public int getAge() { + Calendar c = new GregorianCalendar(); + c.setTime(birthDate); + return new GregorianCalendar().get(Calendar.YEAR) - c.get(Calendar.YEAR); + } + } + + @Html(render=KindRender.class) // Render as an icon in HTML. + public static enum Kind { + CAT, DOG, BIRD, FISH, MOUSE, RABBIT, SNAKE + } + + public static class KindRender extends HtmlRender<Kind> { + @Override + public Object getContent(SerializerSession session, Kind value) { + return new Img().src("servlet:/htdocs/"+value.toString().toLowerCase()+".png"); + } + @Override + public String getStyle(SerializerSession session, Kind value) { + return "background-color:#FDF2E9"; + } + } +

+ +

+ The QUERY 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. +
+ In this case, we're using the Queryable converter that allows us to perform search/view/sort/paging + against collections of beans: +

+ + +

+ 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. +

+

+ @RestMethod( + name=GET, + path="/", + summary="The complete list of pets in the store", + + // Add 'query' and 'content-types' menu items. + widgets={ + QueryMenuItem.class, + ContentTypeMenuItem.class, + StyleMenuItem.class + }, + + // Add our converter for POJO query support. + converters=Queryable.class, + + // Add our menu items in the nav links. + htmldoc=@HtmlDoc( + links={ + "up: request:/..", + "options: servlet:/?method=OPTIONS", + "$W{QueryMenuItem}", + "$W{ContentTypeMenuItem}", + "$W{StyleMenuItem}", + "source: $C{Source/gitHub}/org/apache/juneau/examples/rest/PetStoreResource.java" + } + ) + ) + public Collection<Pet> getPets() { +

+ +

+ HTML views are highly customizable with abilities such as defining your own look-and-feel and even allowing + you to define your own templates. +

+

+ For example, the PetStore page above rendered in one of the other predefined stylesheets: +

+ +

+

+ Automatic error handling is provided for a variety of conditions: +

+
    +
  • Automatic 401 errors (Unauthorized) on failed guards. +
  • Automatic 404 errors (Not Found) on unmatched path patterns. +
  • Automatic 405 errors (Method Not Implemented) on unimplemented methods. +
  • Automatic 406 errors (Not Acceptable) when no matching serializer was found to handle the Accept header. +
  • Automatic 412 errors (Precondition Failed) when all matchers failed to match. +
  • Automatic 415 errors (Unsupported Media Type) when no matching parser was found was found to handle the Content-Type header. +
  • Automatic 500 errors on uncaught exceptions. +
  • Throw your own runtime RestException with HTTP status and response object. +
+

+ Other features include: +

+
    +
  • Extremely simple debuggability using nothing more than your browser. +
  • Simplified localization support. +
  • Configurability through external INI files. +
  • Client-versioned responses (and other customizable heuristic matching APIs). +
  • Define and use your own HTML stylesheets. +
  • Lots of up-to-date documentation and examples. +
  • MUCH MORE!.... +
+ + + +
User Interfaces (UI) vs. Developer Interfaces (DI)
+
+

+ An important distinction needs to be made about the HTML representations produced by the REST + API. These should not be considered User Interfaces, but rather Developer Interfaces. +

+

+ UIs should hide the end-user from the underlying architecture. + The audience generally consists of non-technical people not interested in how the UI works. +

+

+ DIs, on the other hand, should NOT hide the end-user from the underlying architecture. + Instead, it's a thin veneer over the REST interface with the following goals: +

+
    +
  • Make it easy for the developer to explore and understand the REST API. +
  • Make it easy for the developer to debug the REST API using simple tools (hopefully just a browser). +
+

+ As a result, the following guidelines are recommended: +

+
    +
  • + Use titles/descriptions/asides to describe why the REST interface exists. + A developer knowing little about it should be able to access it with a browser and quickly + understand what it is and how to use it. +
  • + Don't hide the raw data! + The HTML view should simply be considered an easier-to-read representation of the data normally + rendered in JSON or some other format. +
  • + Limit your use of Javascript! + You can use it sparingly if you want to implement something simple like a pull-down menu to + simplify some debug task, but remember that your audience cares more about interacting with your + service programmatically using REST. + Remember that the HTML is just icing on the cake. +
  • + Don't use it to implement a Web 2.0 interface! + If you want a Web 2.0 UI, implement it separately ON TOP OF this REST interface. + The architecture is flexible enough that you could in theory pull in and use jQuery, React, + Angular, or any number of sophisticated Javascript UI frameworks. Resist the urge to do so. +
+
+
+ + + + + +
juneau-rest-server-jaxrs
+
+
Maven Dependency
+

+ <dependency> + <groupId>org.apache.juneau</groupId> + <artifactId>juneau-rest-server-jaxrs</artifactId> + <version>7.0.0</version> + </dependency> +

+ +
Java Library
+

+ juneau-rest-server-jaxrs-7.0.0.jar +

+ +
OSGi Module
+

+ org.apache.juneau.rest.server.jaxrs_7.0.0.jar +

+ +

+ The juneau-rest-server-jaxrs module defines predefined MessageBodyReader and + MessageBodyWriter implementations for using Juneau serializers and parsers in JAX-RS environments. + It consists of the following classes: +

+
    +
  • + org.apache.juneau.rest.jaxrs.BaseProvider - The base provider class that implements the JAX-RS + MessageBodyReader and MessageBodyWriter interfaces. +
  • + org.apache.juneau.rest.jaxrs.JuneauProvider - Annotation that is applied to subclasses of BaseProvider + to specify the serializers/parsers associated with a provider, and optionally filters and properties to + apply to those serializers and parsers. +
  • + org.apache.juneau.rest.jaxrs.DefaultProvider - A default provider that provides the same level + of media type support as the RestServletDefault class. +
+

+ The JAX/RS support does provide you will the full marshalling capabilities of Juneau. + However, it should be noted that you lose some sophisticated functionality by not using the REST servlet + API (such as the Developer Interfaces, guards, path matchers, localization, auto-generated Swagger docs, etc...). +

+ + +
+ + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/sitemap.xml ---------------------------------------------------------------------- diff --git a/content/7.0.0/sitemap.xml b/content/7.0.0/sitemap.xml new file mode 100644 index 0000000..ac114f4 --- /dev/null +++ b/content/7.0.0/sitemap.xml @@ -0,0 +1,31 @@ + + + + http://juneau.apache.org/ + weekly + + + http://juneau.apache.org/about.html + weekly + + + http://juneau.apache.org/community.html + weekly + + + http://juneau.apache.org/documentation.html + weekly + + + http://juneau.apache.org/downloads.html + weekly + + + http://juneau.apache.org/sourceCode.html + weekly + + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/sourceCode.html ---------------------------------------------------------------------- diff --git a/content/7.0.0/sourceCode.html b/content/7.0.0/sourceCode.html new file mode 100644 index 0000000..c31bc5a --- /dev/null +++ b/content/7.0.0/sourceCode.html @@ -0,0 +1,28 @@ + + + + + + +
Source Code
+

+ Source code can be accessed through either GitHub or the Apache Git repository. +

+

+ The GitHub repository is read-only. If you want to make contributions to the source tree, you'll need to use the Apache GIT repository. +

+ +
Builds
+ + + http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/4e699954/content/7.0.0/styles/juneau-code.css ---------------------------------------------------------------------- diff --git a/content/7.0.0/styles/juneau-code.css b/content/7.0.0/styles/juneau-code.css new file mode 100644 index 0000000..3db6880 --- /dev/null +++ b/content/7.0.0/styles/juneau-code.css @@ -0,0 +1,124 @@ +/*************************************************************************************************************************** + * 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. * + ***************************************************************************************************************************/ +/*************************************************************************************************************************** + * Styles for embedded highlighted code. + * + * Allows you to embed paragraphs of highlighted code into HTML documents. + * For example: + *

+ * public static void myMethod(int foo, String bar) throws Exception { + * System.err.println("Hello world!"); + * } + *

+ * + * The various tags can also be used outside of code blocks. + * For example: + *
This is how you represent a java int.
+ * + * Available classes: + * code - Unbordered code block + * bcode - Bordered code block + * + * Available tags: + * - Java comment + * - Javadoc comment + * - Javadoc tag + * - Java keyword + * - Java string + * - Java field + * - Java static field + * - Java static method + * - Java annotation + * - XML tag + * - XML attribute + * - XML comment + * - XML string + * - XML value + * - Manifest file key + * - Manifest file value + * - Config file comment + * - Config file section + * - Config file key + * - Config file entry + ***************************************************************************************************************************/ + +/* Monospaced font size */ +.code, +.bcode, +jc,jd,jt,jk,js,jf,jsf,jsm,ja, +xt,xa,xc,xs, +mk,mv, +cc,cs,ck,ce { + font-size: 9pt; + white-space: pre; + font-family: monospace; + tab-size: 3; + -moz-tab-size: 3; + -o-tab-size: 3; +} + +/*--- Bordered code ---*/ +p.bcode { + border: 1px solid black; + margin: 0px 20px; + border-radius: 10px; + overflow: hidden; + background-color: #f8f8f8; + border-color: #cccccc; + box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.5); +} + +/*--- Bordered code in a section of a method doc ---*/ +dd p.bcode { + margin-left:0px; + margin-right:20px; +} + +/* Override padding bottom in javadoc comments. */ +.blockList p.bcode { + padding-bottom: 0px !important; +} + +/*--- Unbordered code ---*/ +p.code { + padding-bottom: 15px; + margin: -15px; +} + +/*--- Java code effects ---*/ +jc { color: green; } +jd { color: #3f5fbf; } +jt { color: #7f9fbf; font-weight: bold; } +jk { color: #7f0055; font-weight: bold; } +js { color: blue; } +jf { color: DarkBlue; } +jsf { color: DarkBlue; font-style: italic; } +jsm { font-style: italic; } +ja { color: grey; } + +/*--- XML code effects ---*/ +xt { color: DarkCyan; } +xa { color: purple; } +xc { color: mediumblue; } +xs { color: blue; font-style: italic; } +xv { color: black; } + +/*--- Manifest-file code effects ---*/ +mk { color: DarkRed; font-weight: bold; } +mv { color: DarkBlue;} + +/*--- Config file effects ---*/ +cc { color: green; } +cs { color: DarkRed;font-weight: bold;} +ck { color: DarkRed; } +cv { color: DarkBlue; }