blob: 73e303cc1f73cc40ffdd1a32cc25f05c0dc1fa15 [file] [log] [blame]
<!--
/***************************************************************************************************************************
* 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: <dc>ConfigFileBuilder</dc>.
<li>Removed the <dc>Lockable</dc> interface.
<li>New <c>addBeanTypeProperties</c> setting added to serializers to override the
<dc>SerializerContext.SERIALIZER_addBeanTypeProperties</dc> setting
for individual serializers in a serializer group:
<ul>
<li><dc>HtmlSerializerContext.HTML_addBeanTypeProperties</dc>
<li><dc>JsonSerializerContext.JSON_addBeanTypeProperties</dc>
<li><dc>MsgPackSerializerContext.MSGPACK_addBeanTypeProperties</dc>
<li><dc>UonSerializerContext.UON_addBeanTypeProperties</dc>
<li><dc>XmlSerializerContext.#XML_addBeanTypeProperties</dc>
<li><dc>RdfSerializerContext.RDF_addBeanTypeProperties</dc>
</ul>
<li>UON notation serializers and parsers moved into the new <c>org.apache.juneau.uon</c> 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 <c>style()</c> 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 <dc>here</dc> 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><dc>$SWITCH</dc> 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: <dc>SerializerContext.SERIALIZER_abridged</dc>.
<li>Support for defining interface proxies against 3rd-party REST interfaces.
<br>New package <dc>org.apache.juneau.remoteable</dc> for all remoteable proxy interface annotations.
<br><ja>@Remoteable</ja> annotation has been moved to this package.
<li>Updated doc: <dc>6 - Remoteable Services</dc>
<li>New doc: <dc>6.1 - Interface proxies against 3rd-party REST interfaces</dc>
<li>New URL-encoding serializer setting: <dc>UrlEncodingSerializerContext.URLENC_paramFormat</dc>.
<li>New methods on {@link oaj.urlencoding.UrlEncodingSerializerBuilder}:
<ul>
<li><dc>UrlEncodingSerializerBuilder.paramFormat(String)</dc>
<li><dc>UrlEncodingSerializerBuilder.plainTextParams()</dc>
</ul>
</ul>
<h5 class='topic w800'>org.apache.juneau.rest</h5>
<ul class='spaced-list'>
<li><dc>@RestResource</dc> 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 <c>RestServlet</c>
should have an equivalent for non-<c>RestServlet</c> classes.
<br>The only restriction is that the top-level resource must subclass from <c>RestServlet</c>.
Child resources do not.
<br><br>
The majority of code has been split up into two separate classes:
<ul>
<li><dc>RestConfig</dc> - 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><dc>RestServlet.init(RestConfig)</dc> - A modifiable configuration of a resource.
</ul>
Non-<c>RestServlet</c> classes must have one of the following to allow it to be instantiated:
<ul>
<li>A <c><jk>public</jk> T(RestConfig)</c> constructor.
<li>A <c><jk>public</jk> T()</c> constructor.
<li>The parent resource must have a customized {@link oajr.RestResourceResolver} for instantiating it.
</ul>
<br>
Non-<c>RestServlet</c> classes can optionally include the following init methods to gain access to the config and context:
<ul>
<li><dc><jk>public</jk> init(RestConfig)</dc>
<li><dc><jk>public</jk> init(RestContext)</dc>
</ul>
<li>New annotations added to <dc>@RestResource</dc> to allow non-<c>RestServlet</c>
resources to do the same as subclassing directly from <c>RestServlet</c>:
<ul>
<li><dc>RestResource.resourceResolver()</dc>
- Specify a {@link oajr.RestResourceResolver} class for resolving child resources.
<li><dc>RestResource.callHandler()</dc>
- Specify a {@link oajr.RestCallHandler} class for handling the lifecycle of a REST call.
<li><dc>RestResource.infoProvider()</dc>
- Specify a {@link oajr.RestInfoProvider} class for customizing title/description/Swagger information on a REST resource.
<li><dc>RestResource.logger()</dc>
- Specify a {@link oajr.RestLogger} class for handling logging.
</ul>
<li>New annotations added to <dc>@RestResource</dc> and {@link oajr.annotation.RestMethod @RestMethod}
to simplify defining page title, text, and links on HTML views:
<ul>
<li><dc>@RestResource(pageTitle)</dc>
<li><dc>@RestMethod(pageTitle)</dc>
<li><dc>@RestResource(pageText)</dc>
<li><dc>@RestMethod(pageText)</dc>
<li><dc>@RestResource(pageLinks)</dc>
<li><dc>@RestMethod(pageLinks)</dc>
</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 <c>title</c> and <c>description</c> 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><dc>RestResource.stylesheet()</dc> can now take in a comma-delimited list of stylesheet paths.
<li><dc>StreamResource</dc> can now contain multiple sources from a variety of source types (e.g. <c><jk>byte</jk>[]</c> arrays, <c>InputStreams</c>, <c>Files</c>, etc...)
and is now immutable. It also includes a new <dc>StreamResourceBuilder</dc> class.
<li>Simplified remoteable proxies using the <c><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</c> annotation on REST methods.
Used to expose interface proxies without the need for <dc>RemoteableServlet</dc>.
<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 <c>RestClient</c> class <c>doX(Object url)</c> methods now handle HttpClient <c>URIBuilder</c> instances.
<li>New methods added/updated to {@link oajrc.RestClient}:
<ul>
<li><dc>RestClient.getRemoteableProxy(Class,Object)</dc> - For interface proxies defined using <c><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</c>.
<li><dc>RestClient.getRemoteableProxy(Class,Object,Serializer,Parser)</dc> - 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><dc>query(String,Object,boolean,PartSerializer)</dc>
<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><dc>formData(String,Object,boolean,PartSerializer)</dc>
<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><dc>header(String,Object,boolean,PartSerializer)</dc>
<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><dc>RestClientBuilder.plainTextParams()</dc>
<li>{@link oajrc.RestClientBuilder#noTrace() noTrace()} - Adds a <c>No-Trace: true</c> 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 <c>Debug: true</c> 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><dc>input(Object)</dc> - 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 <c>HttpResponse</c> returned by the inner <c>HttpClient</c>.
<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><dc>append(String,Object,PartSerializer)</dc>
</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 <c>0</c>s to try a random port.
<li>Methods added to <dc>RestMicroservice</dc> class:
<ul>
<li><dc>getPort()</dc>
<li><dc>getURI()</dc>
<li>Override methods added from {@link oaj.microservice.Microservice} class for easier method chaining.
</ul>
</ul>