blob: 98e818475a71d0944bc9b8647ce7dc49a603b542 [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.3.0 (Jun 30, 2017)
<p>
Juneau 6.3.0 is a major update with significant new functionality for defining proxy interfaces against
arbitrary 3rd-party REST interfaces.
</p>
<h5 class='topic w800'>org.apache.juneau</h5>
<ul class='spaced-list'>
<li>
New package: {@link oaj.http}.
<li>
Support for dynamic beans. See <dc>@BeanProperty(name)</dc>.
<li>
New doc: <dc>2.8 - Virtual Beans</dc>
<li>
New doc: <dc>2.13 - Comparison with Jackson</dc>
<li>
All parsers now allow for numeric types with <js>'K'</js>/<js>'M'</js>/<js>'G'</js> suffixes to represent
kilobytes, megabytes, and gigabytes.
<p class='bcode w800'>
<jc>// Example</jc>
<jk>int</jk> i = JsonParser.<jsf>DEFAULT</jsf>.parse(<js>"123M"</js>); <jc>// 123MB</jc>
</p>
<li>New/modified methods on <dc>ConfigFile</dc>:
<ul>
<li><dc>ConfigFile.put(String,String,String,boolean)</dc>
<li><dc>ConfigFile.put(String,String,Object,Serializer,boolean,boolean)</dc>
<li><dc>ConfigFile.getObject(String,Type,Type...)</dc>
<li><dc>ConfigFile.getObject(String,Parser,Type,Type...)</dc>
<li><dc>ConfigFile.getObject(String,Class)</dc>
<li><dc>ConfigFile.getObject(String,Parser,Class)</dc>
<li><dc>ConfigFile.getObject(String,String,Type,Type...)</dc>
<li><dc>ConfigFile.getObject(String,String,Parser,Type,Type...)</dc>
<li><dc>ConfigFile.getObject(String,String,Class)</dc>
<li><dc>ConfigFile.getObject(String,String,Parser,Class)</dc>
<li><dc>ConfigFile.getObjectWithDefault(String,Object,Type,Type...)</dc>
<li><dc>ConfigFile.getObjectWithDefault(String,Parser,Object,Type,Type...)</dc>
<li><dc>ConfigFile.getObjectWithDefault(String,Object,Class)</dc>
<li><dc>ConfigFile.getObjectWithDefault(String,Parser,Object,Class)</dc>
</ul>
<li>New ability to interact with config file sections with proxy interfaces with new method <dc>ConfigFile.getSectionAsInterface(String,Class)</dc>.
<li><dc>@BeanProperty</dc> annotation can now be applied to getters
and setters defined on interfaces.
<li>New methods on {@link oaj.serializer.SerializerSession} and {@link oaj.parser.ParserSession}
for retrieving context and runtime-override properties:
<ul>
<li><dc>Session.getProperty(String)</dc>
<li><dc>Session.getProperty(String,String)</dc>
<li><dc>Session.getProperty(Class,String)</dc>
<li><dc>Session.getProperty(Class,String,Object)</dc>
</ul>
<li>New <dc>org.apache.juneau.serializer.PartSerializer</dc> interface particularly tailored to HTTP
headers, query parameters, form-data parameters, and path variables.
<br>Allows easy user-defined serialization of these objects.
<br>The interface can be used in the following locations:
<ul>
<li><dc>org.apache.juneau.rest.client.RestClientBuilder.partSerializer(Class)</dc>
<li><dc>org.apache.juneau.remoteable.Path.serializer</dc>
<li><dc>org.apache.juneau.remoteable.Query.serializer</dc>
<li><dc>org.apache.juneau.remoteable.QueryIfNE.serializer</dc>
<li><dc>org.apache.juneau.remoteable.FormData.serializer</dc>
<li><dc>org.apache.juneau.remoteable.FormDataIfNE.serializer</dc>
<li><dc>org.apache.juneau.remoteable.Header.serializer</dc>
<li><dc>org.apache.juneau.remoteable.HeaderIfNE.serializer</dc>
</ul>
<li>Across-the-board improvements to the URI-resolution support (i.e. how URIs get serialized).
<ul>
<li>New support for resolving URIs with the following newly-recognized protocols:
<ul>
<li><js>"context:/..."</js> - Relative to context-root of the application.
<li><js>"servlet:/..."</js> - Relative to the servlet URI.
<li><js>"request:/..."</js> - Relative to the request URI.
</ul>
For example, currently we define HTML page links using variables and servlet-relative URIs...
<p class='bcode w800'>
pages=<js>"{up:'$R{requestParentURI}', options:'?method=OPTIONS', upload:'upload'}"</js>
</p>
With these new protocols, we can define them like so:
<p class='bcode w800'>
links=<js>"{top:'context:/', up:'request:/..' ,options:'servlet:/?method=OPTIONS', upload:'servlet:/upload'}"</js>
</p>
The old method of using variables and servlet-relative URIs will still be supported, but using
these new protocols should (hopefully) be easier to understand.
<br>
These protocols work on all serialized URL and URI objects, as well as classes and properties
annotated with {@link oaj.annotation.URI @URI}.
<li>New classes:
<ul>
<li>{@link oaj.UriContext}
<li>{@link oaj.UriRelativity}
<li>{@link oaj.UriResolution}
<li>{@link oaj.UriResolver}
</ul>
<li>New configuration properties:
<li><dc>SerializerContext.SERIALIZER_uriContext</dc>
<li><dc>SerializerContext.SERIALIZER_uriRelativity</dc>
<li><dc>SerializerContext.SERIALIZER_uriResolution</dc>
<li><dc>SerializerContext.SERIALIZER_maxIndent</dc>
</ul>
<li>New annotation property: <dc>@BeanProperty(value)</dc>.
<br>The following two annotations are considered equivalent:
<p class='bcode w800'>
<ja>@BeanProperty</ja>(name=<js>"foo"</js>)
<ja>@BeanProperty</ja>(<js>"foo"</js>)
</p>
<li>Fixed a race condition in ClassMeta.
<li><jsf>URLENC_paramFormat</jsf> has been moved to <dc>UonSerializer.UON_paramFormat</dc>,
and the UON/URL-Encoding serializers will now always serialize all values as plain text.
<br>This means that arrays and maps are converted to simple comma-delimited lists.
<li>Listener APIs added to serializers and parsers:
<ul>
<li>{@link oaj.serializer.SerializerListener}
<li>{@link oaj.serializer.SerializerBuilder#listener(Class)}
<li><dc>@RestResource(serializerListener)</dc>
<li><dc>RestConfig.serializerListener(Class)</dc>
<li>{@link oaj.parser.ParserListener}
<li>{@link oaj.parser.ParserBuilder#listener(Class)}
<li><dc> @RestResource(parserListener)</dc>
<li><dc>RestConfig.parserListener(Class)</dc>
<li><dc>RestClientBuilder.listeners(Class,Class)</dc>
</ul>juneau-examples-core.import1.pngjuneau-examples-core.import1.png
<li>The {@link oaj.BeanContext#BEAN_debug} flag will now capture parser input and make it
available through the <dc>ParserSession.getInputAsString()</dc> method so that it can be used
in the listeners.
<li>Significant new functionality introduced to the HTML serializer.
<br>Lots of new options for customizing the HTML output.
<ul>
<li>New {@link oaj.html.annotation.Html#render() @Html(render)} annotation and {@link oaj.html.HtmlRender} class that allows you
to customize the HTML output and CSS style on bean properties:
<br><img class='bordered' src='doc-files/ReleaseNotes.630.1.png'>
<br>Annotation can be applied to POJO classes and bean properties.
<li>Several new properties for customizing parts of the HTML page:
<ul>
<li><dc>HtmlDocSerializerContext.HTMLDOC_title</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_description</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_branding</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_header</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_nav</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_aside</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_footer</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_noResultsMessage</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_cssUrl</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_css</dc>
<li><dc>HtmlDocSerializerContext.HTMLDOC_template</dc>
</ul>
<li>New interface {@link oaj.html.HtmlDocTemplate} that allows full control over rendering
of HTML produced by {@link oaj.html.HtmlDocSerializer}.
</ul>
<li>{@link oaj.annotation.NameProperty @NameProperty} and {@link oaj.annotation.ParentProperty @ParentProperty}
can now be applied to fields.
<li>New properties on {@link oaj.BeanContext}:
<ul>
<li><dc>BEAN_includeProperties</dc>
<li><dc>BEAN_excludeProperties</dc>
</ul>
<li>New annotation property: <dc>@BeanProperty(format)</dc>.
</ul>
<h5 class='topic w800'>org.apache.juneau.rest</h5>
<ul class='spaced-list'>
<li>
MAJOR enhancements made to the REST API.
<li>
The {@link oajr.RestRequest} class functionality has been broken up into the following
functional pieces to reduce its complexity:
<ul>
<li>{@link oajr.RestRequest#getBody()} - The request body.
<li>{@link oajr.RestRequest#getHeaders()} - The request headers.
<li>{@link oajr.RestRequest#getQuery()} - The request query parameters.
<li>{@link oajr.RestRequest#getFormData()} - The request form data parameters.
<li>{@link oajr.RestRequest#getPathMatch()} - The path variables and remainder.
</ul>
The following classes have been introduced:
<ul>
<li>{@link oajr.RequestBody}
<li>{@link oajr.RequestHeaders}
<li>{@link oajr.RequestQuery}
<li>{@link oajr.RequestFormData}
<li>{@link oajr.RequestPath}
</ul>
<li>
The un-annotated parameter types that can be passed in through REST Java methods has been significantly expanded.
<br>For reference, the previous supported types were:
<ul>
<li>{@link oajr.RestRequest} - The request object.
<li>{@link javax.servlet.http.HttpServletRequest} - The superclass of <c>RestRequest</c>.
<li>{@link oajr.RestResponse} - The response object.
<li>{@link javax.servlet.http.HttpServletResponse} - The superclass of <c>RestResponse</c>.
</ul>
The new supported types are:
<ul>
<li>{@link oaj.http.Accept}
<li>{@link oaj.http.AcceptCharset}
<li>{@link oaj.http.AcceptEncoding}
<li>{@link oaj.http.AcceptLanguage}
<li>{@link oaj.http.Authorization}
<li>{@link oaj.http.CacheControl}
<li>{@link oaj.http.Connection}
<li>{@link oaj.http.ContentLength}
<li>{@link oaj.http.ContentType}
<li>{@link oaj.http.Date}
<li>{@link oaj.http.Expect}
<li>{@link oaj.http.From}
<li>{@link oaj.http.Host}
<li>{@link oaj.http.IfMatch}
<li>{@link oaj.http.IfModifiedSince}
<li>{@link oaj.http.IfNoneMatch}
<li>{@link oaj.http.IfRange}
<li>{@link oaj.http.IfUnmodifiedSince}
<li>{@link oaj.http.MaxForwards}
<li>{@link oaj.http.Pragma}
<li>{@link oaj.http.ProxyAuthorization}
<li>{@link oaj.http.Range}
<li>{@link oaj.http.Referer}
<li>{@link oaj.http.TE}
<li>{@link oaj.http.UserAgent}
<li>{@link oaj.http.Upgrade}
<li>{@link oaj.http.Via}
<li>{@link oaj.http.Warning}
<li>{@link java.util.TimeZone}
<li>{@link java.io.InputStream}
<li>{@link javax.servlet.ServletInputStream}
<li>{@link java.io.Reader}
<li>{@link java.io.OutputStream}
<li>{@link javax.servlet.ServletOutputStream}
<li>{@link java.io.Writer}
<li>{@link java.util.ResourceBundle} - Client-localized resource bundle.
<li>{@link oaj.utils.MessageBundle} - A resource bundle with additional features.
<li>{@link java.util.Locale} - Client locale.
<li>{@link oajr.RequestHeaders} - API for accessing request headers.
<li>{@link oajr.RequestQuery} - API for accessing request query parameters.
<li>{@link oajr.RequestFormData} - API for accessing request form data.
<li>{@link oajr.RequestPath} - API for accessing path variables.
<li>{@link oajr.RequestBody} - API for accessing request body.
<li>{@link oaj.http.HttpMethod} - The method name matched (when using <c><ja>@RestMethod</ja>(name=<js>"*"</js>)</c>)
<li>{@link java.util.logging.Logger} - The logger to use for logging.
<li>{@link oaj.internal.JuneauLogger} - Logger with additional features.
<li>{@link oajr.RestContext} - The resource read-only context.
<li>{@link oaj.parser.Parser} - The parser matching the request content type.
<li>{@link oaj.dto.swagger.Swagger} - The auto-generated Swagger doc.
<li><dc>ConfigFile</dc> - The external config file for the resource.
</ul>
So, for example...
<p class='bcode w800'>
<jd>/** Old way */</jd>
<ja>@RestMethod</ja>(name=<js>"*"</js>, path=<js>"/example1/{a1}/{a2}/{a3}/*"</js>)
<jk>public</jk> String example1(
<ja>@Method</ja> String method,
<ja>@Path</ja>(<js>"a1"</js>) String a1,
<ja>@Path</ja>(<js>"a2"</js>) <jk>int</jk> a2,
<ja>@Path</ja>(<js>"a3"</js>) UUID a3,
<ja>@Query</ja>(<js>"p1"</js>) <jk>int</jk> p1,
<ja>@Query</ja>(<js>"p2"</js>) String p2,
<ja>@Query</ja>(<js>"p3"</js>) UUID p3,
<ja>@Header</ja>(<js>"Accept-Language"</js>) String lang,
<ja>@Header</ja>(<js>"Accept"</js>) String accept
)
<jd>/** New way */</jd>
<ja>@RestMethod</ja>(name=<js>"*"</js>, path=<js>"/example2/{a1}/{a2}/{a3}/*"</js>)
<jk>public</jk> String example2(
HttpMethod httpMethod,
RequestPathParams pathParams,
RequestQuery query,
AcceptLanguage acceptLanguage,
Accept accept
)
</p>
<li>
A new annotation <dc>@RestResource(paramResolvers)</dc>}
that allows you to define your own custom Java method parameter resolvers.
<li>
Fixed bug where Writer returned by {@link oajr.RestResponse#getWriter()} was not being flushed automatically
at the end of the HTTP call.
<li>
New annotations added to {@link oajr.annotation.RestMethod @RestMethod}:
<ul>
<li>{@link oajr.annotation.RestMethod#defaultQuery() defaultQuery()}
<li>{@link oajr.annotation.RestMethod#defaultFormData() defaultFormData()}
<li><dc>bpIncludes()</dc>
<li><dc>bpExcludes()</dc>
</ul>
<li>
Default values on header, query, and form-data annotations:
<ul>
<li><dc>@Header(def)</dc> - Default header value.
<li><dc>@Query(def)</dc> - Default query parameter value.
<li><dc>@FormData(def)</dc> - Default form data parameter value.
</ul>
<li>
New attributes on <dc>@RestResource</dc>:
<ul>
<li><dc>serializerListener()</dc>
<li><dc>parserListener()</dc>
<li><dc>widgets()</dc>
<li><dc>swagger()</dc>
<li><dc>htmldoc()</dc>
</ul>
<li>
New attributes on {@link oajr.annotation.RestMethod @RestMethod}:
<ul>
<li><dc>widgets()</dc>
<li>{@link oajr.annotation.RestMethod#swagger() swagger()}
<li>{@link oajr.annotation.RestMethod#htmldoc() htmldoc()}
</ul>
<li>
New string vars:
<ul>
<li>{@link oajr.vars.UrlVar} - Resolve <js>"$U{...}"</js> variables to URLs.
<li>{@link oajr.vars.WidgetVar} - Resolve <js>"$W{...}"</js> variables to widget contents.
</ul>
<li>
New methods on <dc>RestConfig</dc>:
<ul>
<li><dc>setHtmlTitle(String)</dc>
<li><dc>setHtmlDescription(String)</dc>
<li><dc>setHtmlBranding(String)</dc>
<li><dc>setHtmlHeader(String)</dc>
<li><dc>setHtmlLinks(String)</dc>
<li><dc>setHtmlNav(String)</dc>
<li><dc>setHtmlAside(String)</dc>
<li><dc>setHtmlFooter(String)</dc>
<li><dc>setHtmlCss(String)</dc>
<li><dc>setHtmlCssUrl(String)</dc>
<li><dc>setHtmlNoWrap(boolean)</dc>
<li><dc>setHtmlNoResultsMessage(String)</dc>
<li><dc>setHtmlTemplate(Class)</dc>
<li><dc>setHtmlTemplate(HtmlDocTemplate)</dc>
<li><dc>addWidget(Class)</dc>
</ul>
<li>
New methods on {@link oajr.RestResponse}:
<ul>
<li><dc>setHtmlTitle(Object)</dc>
<li><dc>setHtmlDescription(Object)</dc>
<li><dc>setHtmlBranding(Object)</dc>
<li><dc>setHtmlHeader(Object)</dc>
<li><dc>setHtmlLinks(Object)</dc>
<li><dc>setHtmlNav(Object)</dc>
<li><dc>setHtmlAside(Object)</dc>
<li><dc>setHtmlFooter(Object)</dc>
<li><dc>setHtmlCss(Object)</dc>
<li><dc>setHtmlCssUrl(Object)</dc>
<li><dc>setHtmlNoWrap(boolean)</dc>
<li><dc>setHtmlNoResultsMessage(Object)</dc>
<li><dc>setHtmlTemplate(Class)</dc>
<li><dc>setHtmlTemplate(HtmlDocTemplate)</dc>
</ul>
<li>
<c>&amp;plainText=true</c> parameter now works on byte-based serializers by converting the output to hex.
<li>
New classes for widget support:
<ul>
<li>{@link oajr.widget.Widget}
<li><dc>PoweredByJuneauWidget</dc>
<li><dc>ContentTypeLinksColumnWidget</dc>
<li><dc>ContentTypeLinksRowWidget</dc>
<li><dc>QueryWidget</dc>
</ul>
<li>
<c>devops.css</c> cleaned up.
<li>
Removed a bunch of URL-related methods from {@link oajr.RestRequest}.
These all have equivalents in {@link oajr.RestRequest#getUriContext()}.
<li>
New annotation attributes:
<ul>
<li>{@link oaj.http.annotation.Query#name() @Query(name)}
<li>{@link oaj.http.annotation.FormData#name() @FormData(name)}
<li>{@link oaj.http.annotation.Header#name() @Header(name)}
<li>{@link oaj.http.annotation.Path#name() @Path(name)}
<li>{@link oaj.http.annotation.HasQuery#name() @HasQuery(name)}
<li>{@link oaj.http.annotation.HasFormData#name() @HasFormData(name)}
</ul>
</li>
</ul>
<h5 class='topic w800'>org.apache.juneau.rest.client</h5>
<ul class='spaced-list'>
<li>
New <dc>org.apache.juneau.remoteable.Path</dc> annotation for specifying path variables on remoteable interfaces.
<li>
New <dc>@RequestBean</dc> annotation for specifying beans with remoteable annotations
defined on properties.
<li>
The following annotations (and related methods on RestCall) can now take <c>NameValuePairs</c> and beans as input
when using <js>"*"</js> as the name.
<br><dc>org.apache.juneau.remoteable.FormData</dc>,<dc>org.apache.juneau.remoteable.FormDataIfNE</dc>,
<dc>org.apache.juneau.remoteable.Query</dc>,<dc>org.apache.juneau.remoteable.QueryIfNE</dc>,
<dc>org.apache.juneau.remoteable.Header</dc>,<dc>org.apache.juneau.remoteable.HeaderIfNE</dc>
</ul>
<h5 class='topic w800'>org.apache.juneau.microservice</h5>
<ul class='spaced-list'>
</ul>
<h5 class='topic w800'>org.apache.juneau.examples.rest</h5>
<ul class='spaced-list'>
<li>
Many code enhancements make to examples to reflect new functionality.
<li>All pages now render aside comments to help explain what feature they're trying to explain using the
new features that allow you to customize various elements of the page.
<br>
<img class='bordered' width='50%' src='doc-files/ReleaseNotes.630.2.png'>
</ul>