| <!-- |
| /*************************************************************************************************************************** |
| * 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. |
| ***************************************************************************************************************************/ |
| --> |
| |
| 6.2.0 (Apr 28, 2017) |
| |
| <p> |
| Juneau 6.2.0 is a major update. |
| </p> |
| |
| <h5 class='topic w800'>org.apache.juneau</h5> |
| <ul class='spaced-list'> |
| <li> |
| Revamped the serializer, parser classes to use builders for creation. |
| Serializers and parsers are now unmodifiable objects once they are created. |
| This is a breaking code change that will require adoption. |
| <p class='bcode w800'> |
| <jc>/* Creating a new serializer or parser */ </jc> |
| |
| <jc>// Old way</jc> |
| WriterSerializer s = <jk>new</jk> JsonSerializer().setUseWhitespace(<jk>true</jk>).pojoSwaps(BSwap.<jk>class</jk>).lock(); |
| |
| <jc>// New way</jc> |
| WriterSerializer s = JsonSerializer.<jsm>create</jsm>().ws().pojoSwaps(BSwap.<jk>class</jk>).build(); |
| |
| <jc>/* Cloning an existing serializer or parser */ </jc> |
| |
| <jc>// Old way</jc> |
| WriterSerializer s = SimpleJsonSerializer.<jsf>DEFAULT</jsf> |
| .clone().setUseWhitespace(<jk>true</jk>).pojoSwaps(BSwap.<jk>class</jk>).lock(); |
| |
| <jc>// New way</jc> |
| WriterSerializer s = SimpleJsonSerializer.<jsf>DEFAULT</jsf> |
| .builder().ws().pojoSwaps(BSwap.<jk>class</jk>).build(); |
| </p> |
| <li>Also introduced the following builder classes and related architecture changes to make the built objects unmodifiable: |
| <ul> |
| <li>{@link oaj.serializer.SerializerGroupBuilder} |
| <li>{@link oaj.parser.ParserGroupBuilder} |
| <li>{@link oaj.encoders.EncoderGroupBuilder} |
| </ul> |
| <li>Revamped the config file API to use a build: <code><del>ConfigFileBuilder</del></code>. |
| <li>Removed the <code><del>Lockable</del></code> interface. |
| <li>New <code>addBeanTypeProperties</code> setting added to serializers to override the |
| <code><del>SerializerContext.SERIALIZER_addBeanTypeProperties</del></code> setting |
| for individual serializers in a serializer group: |
| <ul> |
| <li><code><del>HtmlSerializerContext.HTML_addBeanTypeProperties</del></code> |
| <li><code><del>JsonSerializerContext.JSON_addBeanTypeProperties</del></code> |
| <li><code><del>MsgPackSerializerContext.MSGPACK_addBeanTypeProperties</del></code> |
| <li><code><del>UonSerializerContext.UON_addBeanTypeProperties</del></code> |
| <li><code><del>XmlSerializerContext.#XML_addBeanTypeProperties</del></code> |
| <li><code><del>RdfSerializerContext.RDF_addBeanTypeProperties</del></code> |
| </ul> |
| <li>UON notation serializers and parsers moved into the new <code>org.apache.juneau.uon</code> package. |
| <li>New {@link oaj.xml.annotation.XmlFormat#VOID} format to identify HTML void elements. |
| <li>Tweaks to HTML5 support. |
| <ul> |
| <li>Fixed handling of empty non-void elements in HTML serializer. |
| <li>Added <code>style()</code> override methods to all elements. |
| </ul> |
| <li>Improvements to Swagger support. |
| <ul> |
| <li>New {@link oaj.dto.swagger.SwaggerBuilder} class. |
| <li>Fluent-style setters added to the Swagger beans. |
| <li>Added Swagger examples <code><del>here</del></code> and in the <del>org.apache.juneau.dto.swagger</del> javadocs. |
| </ul> |
| <li>Improvements to {@link oaj.svl.VarResolver}. |
| <ul> |
| <li>New {@link oaj.svl.vars.IfVar $IF} variable for if-else block logic. |
| <li><code><del>$SWITCH</del></code> variable for switch block logic. |
| <li>Whitespace wasn't being ignored in some cases. |
| </ul> |
| <li>{@link oaj.html.HtmlParser} can now parse full body contents generated by {@link oaj.html.HtmlDocSerializer}. |
| <li>Parse-args supported added to {@link oaj.msgpack.MsgPackParser} to allow it to be used in remoteable proxies. |
| <li>Added some convenience classes for constructing collections using a fluent interface: |
| <ul> |
| <li>{@link oaj.utils.AList} |
| <li>{@link oaj.utils.ASet} |
| <li>{@link oaj.utils.AMap} |
| </ul> |
| <li>New {@link oaj.annotation.Bean#typePropertyName @Bean(typePropertyName)} annotation allows you to |
| specify the name of the <js>"_type"</js> property at the class level. |
| <li>New methods added to HTML5 container beans: |
| <ul> |
| <li>{@link oaj.dto.html5.HtmlElementContainer#getChild(int...)} |
| <li>{@link oaj.dto.html5.HtmlElementMixed#getChild(int...)} |
| </ul> |
| <li>New common serializer setting: <code><del>SerializerContext.SERIALIZER_abridged</del></code>. |
| <li>Support for defining interface proxies against 3rd-party REST interfaces. |
| <br>New package <code><del>org.apache.juneau.remoteable</del></code> for all remoteable proxy interface annotations. |
| <br><ja>@Remoteable</ja> annotation has been moved to this package. |
| <li>Updated doc: <code><del>6 - Remoteable Services</del></code> |
| <li>New doc: <code><del>6.1 - Interface proxies against 3rd-party REST interfaces</del></code> |
| <li>New URL-encoding serializer setting: <code><del>UrlEncodingSerializerContext.URLENC_paramFormat</del></code>. |
| <li>New methods on {@link oaj.urlencoding.UrlEncodingSerializerBuilder}: |
| <ul> |
| <li><code><del>UrlEncodingSerializerBuilder.paramFormat(String)</del></code> |
| <li><code><del>UrlEncodingSerializerBuilder.plainTextParams()</del></code> |
| </ul> |
| </ul> |
| |
| <h5 class='topic w800'>org.apache.juneau.rest</h5> |
| <ul class='spaced-list'> |
| <li>{@link oajr.annotation.RestResource @RestResource} annotation can now be applied to |
| any class! You're no longer restricted to subclassing your resources from {@link oajr.RestServlet}. |
| <br>This is a major enhancement in the API. Anything you could do by subclassing from <code>RestServlet</code> |
| should have an equivalent for non-<code>RestServlet</code> classes. |
| <br>The only restriction is that the top-level resource must subclass from <code>RestServlet</code>. |
| Child resources do not. |
| <br><br> |
| The majority of code has been split up into two separate classes: |
| <ul> |
| <li><code><del>RestConfig</del></code> - A modifiable configuration of a resource. Subclasses from {@link javax.servlet.ServletConfig}. |
| <li>{@link oajr.RestContext} - A read-only configuration that's the result of a snapshot of the config. |
| </ul> |
| <br><br> |
| The {@link oajr.RestServlet} class now has the following initialization method that allows you to override |
| the config settings define via annotations: |
| <ul> |
| <li><code><del>RestServlet.init(RestConfig)</del></code> - A modifiable configuration of a resource. |
| </ul> |
| Non-<code>RestServlet</code> classes must have one of the following to allow it to be instantiated: |
| <ul> |
| <li>A <code><jk>public</jk> T(RestConfig)</code> constructor. |
| <li>A <code><jk>public</jk> T()</code> constructor. |
| <li>The parent resource must have a customized {@link oajr.RestResourceResolver} for instantiating it. |
| </ul> |
| <br> |
| Non-<code>RestServlet</code> classes can optionally include the following init methods to gain access to the config and context: |
| <ul> |
| <li><code><del><jk>public</jk> init(RestConfig)</del></code> |
| <li><code><del><jk>public</jk> init(RestContext)</del></code> |
| </ul> |
| <li>New annotations added to {@link oajr.annotation.RestResource @RestResource} to allow non-<code>RestServlet</code> |
| resources to do the same as subclassing directly from <code>RestServlet</code>: |
| <ul> |
| <li>{@link oajr.annotation.RestResource#resourceResolver() resourceResolver()} |
| - Specify a {@link oajr.RestResourceResolver} class for resolving child resources. |
| <li>{@link oajr.annotation.RestResource#callHandler() callHandler()} |
| - Specify a {@link oajr.RestCallHandler} class for handling the lifecycle of a REST call. |
| <li>{@link oajr.annotation.RestResource#infoProvider() infoProvider()} |
| - Specify a {@link oajr.RestInfoProvider} class for customizing title/description/Swagger information on a REST resource. |
| <li>{@link oajr.annotation.RestResource#logger() logger()} |
| - Specify a {@link oajr.RestLogger} class for handling logging. |
| </ul> |
| <li>New annotations added to {@link oajr.annotation.RestResource @RestResource} and {@link oajr.annotation.RestMethod @RestMethod} |
| to simplify defining page title, text, and links on HTML views: |
| <ul> |
| <li><code><del>@RestResource(pageTitle)</del></code> |
| <li><code><del>@RestMethod(pageTitle)</del></code> |
| <li><code><del>@RestResource(pageText)</del></code> |
| <li><code><del>@RestMethod(pageText)</del></code> |
| <li><code><del>@RestResource(pageLinks)</del></code> |
| <li><code><del>@RestMethod(pageLinks)</del></code> |
| </ul> |
| <p class='bcode w800'> |
| <jc>// Old method</jc> |
| <ja>@RestResource</ja>( |
| properties={ |
| <ja>@Property</ja>(name=<jsf>HTMLDOC_title</jsf>, value=<js>"System properties resource"</js>), |
| <ja>@Property</ja>(name=<jsf>HTMLDOC_description</jsf>, value=<js>"REST interface for performing CRUD operations on system properties."</js>), |
| <ja>@Property</ja>(name=<jsf>HTMLDOC_navlinks</jsf>, value=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js>) |
| } |
| ) |
| |
| <jc>// New method</jc> |
| <ja>@RestResource</ja>( |
| pageTitle=<js>"System properties resource"</js>, |
| pageDescription=<js>"REST interface for performing CRUD operations on system properties."</js>, |
| pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> |
| ) |
| </p> |
| <p> |
| Typically you're going to simply want to use the <code>title</code> and <code>description</code> annotations |
| which apply to both the page title/text and the swagger doc: |
| </p> |
| <p class='bcode w800'> |
| <ja>@RestResource</ja>( |
| title=<js>"System properties resource"</js>, |
| description=<js>"REST interface for performing CRUD operations on system properties."</js>, |
| pageLinks=<js>"{up:'$R{requestParentURI}',options:'?method=OPTIONS'}"</js> |
| ) |
| </p> |
| <li><code><del>RestResource.stylesheet()</del></code> can now take in a comma-delimited list of stylesheet paths. |
| <li><code><del>StreamResource</del></code> can now contain multiple sources from a variety of source types (e.g. <code><jk>byte</jk>[]</code> arrays, <code>InputStreams</code>, <code>Files</code>, etc...) |
| and is now immutable. It also includes a new <code><del>StreamResourceBuilder</del></code> class. |
| <li>Simplified remoteable proxies using the <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code> annotation on REST methods. |
| Used to expose interface proxies without the need for <code><del>RemoteableServlet</del></code>. |
| <p class='bcode w800'> |
| <jc>// Server side</jc> |
| <ja>@RestMethod</ja>(name=<js>"PROXY"</js>, path=<js>"/myproxy/*"</js>) |
| <jk>public</jk> IAddressBook getProxy() { |
| <jk>return</jk> <jf>addressBook</jf>; |
| } |
| |
| <jc>// Client side</jc> |
| RestClient client = RestClient.<jsm>create</jsm>().rootUrl(<jf>samplesUrl</jf>).build(); |
| IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>, <js>"/addressBook/myproxy"</js>); |
| </p> |
| See {@link oajr.annotation.RestMethod#name() @RestMethod(name)} for more information. |
| <li>{@link oajr.RestRequest#toString()} can be called at any time to view the headers and content of the request |
| without affecting functionality. Very useful for debugging. |
| <li>{@link oajr.annotation.RestMethod#name() @RestMethod(name)} annotation is now optional. Defaults to <js>"GET"</js>. |
| </ul> |
| |
| <h5 class='topic w800'>org.apache.juneau.rest.client</h5> |
| <ul class='spaced-list'> |
| <li>Revamped the client API to use builders. |
| <li>New doc: <del>1.5 - Debugging</del> |
| <li>The <code>RestClient</code> class <code>doX(Object url)</code> methods now handle HttpClient <code>URIBuilder</code> instances. |
| <li>New methods added/updated to {@link oajrc.RestClient}: |
| <ul> |
| <li><code><del>RestClient.getRemoteableProxy(Class,Object)</del></code> - For interface proxies defined using <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code>. |
| <li><code><del>RestClient.getRemoteableProxy(Class,Object,Serializer,Parser)</del></code> - Same as above, but overrides the serializer and parser defined on the client. |
| <li>{@link oajrc.RestClient#doPost(Object) doPost(Object)} |
| <li>{@link oajrc.RestClient#doCall(HttpMethod,Object,Object) doCall(HttpMethod,Object,Object)} - Can now pass in instances of {@link oajrc.NameValuePairs} for easy form posts. |
| <br>This extends to all methods that take in the input. |
| </ul> |
| <li>New methods on {@link oajrc.RestCall}: |
| <ul> |
| <li>{@link oajrc.RestCall#uri(Object) uri(Object)} |
| <li><code><del>query(String,Object,boolean,PartSerializer)</del></code> |
| <li>{@link oajrc.RestCall#query(String,Object) query(String,Object)} |
| <li>{@link oajrc.RestCall#queryIfNE(String,Object) queryIfNE(String,Object)} |
| <li>{@link oajrc.RestCall#query(Map) query(Map)} |
| <li>{@link oajrc.RestCall#queryIfNE(Map) queryIfNE(Map)} |
| <li>{@link oajrc.RestCall#query(String) query(String)} |
| <li><code><del>formData(String,Object,boolean,PartSerializer)</del></code> |
| <li>{@link oajrc.RestCall#formData(String,Object) formData(String,Object)} |
| <li>{@link oajrc.RestCall#formDataIfNE(String,Object) formDataIfNE(String,Object)} |
| <li>{@link oajrc.RestCall#formData(Map) formData(Map)} |
| <li>{@link oajrc.RestCall#formDataIfNE(Map) formDataIfNE(Map)} |
| <li><code><del>header(String,Object,boolean,PartSerializer)</del></code> |
| <li>{@link oajrc.RestCall#header(String,Object) header(String,Object)} |
| <li>{@link oajrc.RestCall#headerIfNE(String,Object) headerIfNE(String,Object)} |
| <li>{@link oajrc.RestCall#headers(Map) headers(Map)} |
| <li>{@link oajrc.RestCall#headersIfNE(Map) headersIfNE(Map)} |
| <li>{@link oajrc.RestCall#host(String) host(String)} |
| <li>{@link oajrc.RestCall#port(int) port(int)} |
| <li>{@link oajrc.RestCall#userInfo(String,String) userInfo(String,String)} |
| <li>{@link oajrc.RestCall#userInfo(String) userInfo(String)} |
| <li>{@link oajrc.RestCall#scheme(String) scheme(String)} |
| </ul> |
| <li>New methods added to {@link oajrc.RestClientBuilder}: |
| <ul> |
| <li>{@link oajrc.RestClientBuilder#executorService(ExecutorService,boolean) executorService(ExecutorService,boolean)} |
| <li>{@link oajrc.RestClientBuilder#paramFormat(String) paramFormat(ExecutorService,boolean)} |
| <li><code><del>RestClientBuilder.plainTextParams()</del></code> |
| <li>{@link oajrc.RestClientBuilder#noTrace() noTrace()} - Adds a <code>No-Trace: true</code> header on all requests to prevent |
| the servlet from logging errors. |
| <br>Useful for testing scenarios when you don't want the console to end up showing errors done on purpose. |
| <li>{@link oajrc.RestClientBuilder#debug() debug()} now adds a <code>Debug: true</code> header on all requests. |
| </ul> |
| <li>New methods added/updated to {@link oajrc.RestCall}: |
| <ul> |
| <li>{@link oajrc.RestCall#runFuture() runFuture()} |
| <li>{@link oajrc.RestCall#getResponseFuture(Class) getResponseFuture(Class)} |
| <li>{@link oajrc.RestCall#getResponseFuture(Type,Type...) getResponseFuture(Type,Type...)} |
| <li>{@link oajrc.RestCall#getResponseAsStringFuture() getResponseAsStringFuture()} |
| <li>{@link oajrc.RestCall#serializer(Serializer) serializer(Serializer)} - Override the serializer defined on the client for a single call. |
| <li>{@link oajrc.RestCall#parser(Parser) parser(Parser)} - Override the parser defined on the client for a single call. |
| <li><code><del>input(Object)</del></code> - Now accepts instances of {@link oajrc.NameValuePairs}. |
| <li>{@link oajrc.RestCall#getResponse(Class) getResponse(Class)} - Can now pass in any of the following: |
| <ul> |
| <li>{@link org.apache.http.HttpResponse} - Returns the raw <code>HttpResponse</code> returned by the inner <code>HttpClient</code>. |
| <li>{@link java.io.Reader} - Returns access to the raw reader of the response. |
| <li>{@link java.io.InputStream} - Returns access to the raw input stream of the response. |
| </ul> |
| </ul> |
| <li>New methods added to {@link oajrc.NameValuePairs}: |
| <ul> |
| <li>{@link oajrc.NameValuePairs#append(String,Object) append(String,Object)} |
| <li><code><del>append(String,Object,PartSerializer)</del></code> |
| </ul> |
| <li>{@link oajrc.RetryOn} is now an abstract class with an additional method: |
| <ul> |
| <li>{@link oajrc.RetryOn#onResponse(HttpResponse) onResponse(HttpResponse)} |
| </ul> |
| </ul> |
| |
| <h5 class='topic w800'>org.apache.juneau.microservice</h5> |
| <ul class='spaced-list'> |
| <li><js>"REST/port"</js> configuration setting can now be a comma-limited list of port numbers to try. |
| <br>You can also specify one or more <code>0</code>s to try a random port. |
| <li>Methods added to <code><del>RestMicroservice</del></code> class: |
| <ul> |
| <li><code><del>getPort()</del></code> |
| <li><code><del>getURI()</del></code> |
| <li>Override methods added from {@link oaj.microservice.Microservice} class for easier method chaining. |
| </ul> |
| </ul> |