| <!-- |
| /*************************************************************************************************************************** |
| * 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>&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> |