Juneau 8.2.0 is a major release.
The most significant change is the addition of an entirely new {@link oajr.client2.RestClient} API build from scratch
with near 100% unit test coverage.
The new API is located in the org.apache.juneau.rest.client2 package and will replace the old API in 9.0.
-
{@link oaj.annotation.Bean @Bean} and {@link oaj.annotation.BeanIgnore @BeanIgnore} annotations can alternately occur in parent class hierarchy.
The first one found dictates whether a class is ignored as a bean or not.
-
Applying the {@link oaj.annotation.Bean @Bean} annotation on a class will now force non-public classes to be interpreted as beans.
For example, applying {@link oaj.annotation.Bean @Bean} to a private class will force it to be treated as a bean.
Also, if a public bean constructor cannot be found, the default constructor will be used
regardless of it's visibility if the {@link oaj.annotation.Bean @Bean} annotation is on the class.
-
The @Beanc annotation can now be recognized and used on non-public constructors.
-
Annotations are now aggregated across the entire class hierarchy instead of simply being overridden.
The following is an example.
// Parent class with properties a,b,c
@Bean(bpi="a,b,c")
public class MyClass {
public int a, b, c, d;
}
// New behavior: Child class with properties a,c because @Beans are aggregated.
// Old behavior: Child class with properties a,c,d because @Bean is overridden.
@Bean(bpx="b")
public class MyClass {
public int a, b, c, d;
}
-
Include/exclude/read-only/write-only properties defined on the bean context now override those defined on
annotations of the class itself. For example, the following methods override the {@link oaj.annotation.Bean @Bean}
annotations on classes:
- {@link oaj.BeanContextBuilder}
- {@link oaj.BeanContextBuilder#bpi(Class,String) bpi(Class,String)}
- {@link oaj.BeanContextBuilder#bpi(String,String) bpi(String,String)}
- {@link oaj.BeanContextBuilder#bpx(Class,String) bpx(Class,String)}
- {@link oaj.BeanContextBuilder#bpx(String,String) bpx(String,String)}
- {@link oaj.BeanContextBuilder#bpro(Class,String) bpro(Class,String)}
- {@link oaj.BeanContextBuilder#bpro(String,String) bpro(String,String)}
- {@link oaj.BeanContextBuilder#bpwo(Class,String) bpwo(Class,String}
- {@link oaj.BeanContextBuilder#bpwo(String,String) bpwo(String,String}
-
Config annotations now override class-level annotations.
For example, only the 'a' and 'b' properties get serialized on the bean below:
// Parent class with properties a,b,c
@Bean(bpi="a,b,c")
public class MyClass {
public int a, b, c, d;
}
@RestMethod
@BeanConfig(beanApply={@Bean(on="MyClass",bpi="a,b")}
public MyClass getMyClass() {...}
-
The following concrete annotation implementation classes are now provided that can be used with the {@link oaj.BeanContextBuilder#annotations(Annotation...)} method:
- {@link oaj.annotation.BeanAnnotation} implements {@link oaj.annotation.Bean}
- {@link oaj.annotation.BeancAnnotation} implements {@link oaj.annotation.Beanc}
- {@link oaj.annotation.BeanIgnoreAnnotation} implements {@link oaj.annotation.BeanIgnore}
- {@link oaj.annotation.BeanpAnnotation} implements {@link oaj.annotation.Beanp}
- {@link oaj.annotation.ExampleAnnotation} implements {@link oaj.annotation.Example}
- {@link oaj.annotation.NamePropertyAnnotation} implements {@link oaj.annotation.NameProperty}
- {@link oaj.annotation.ParentPropertyAnnotation} implements {@link oaj.annotation.ParentProperty}
- {@link oaj.annotation.SwapAnnotation} implements {@link oaj.annotation.Swap}
- {@link oaj.annotation.UriAnnotation} implements {@link oaj.annotation.URI}
- {@link oaj.csv.annotation.CsvAnnotation} implements {@link oaj.csv.annotation.Csv}
- {@link oaj.html.annotation.HtmlAnnotation} implements {@link oaj.html.annotation.Html}
- {@link oaj.jso.annotation.JsoAnnotation} implements {@link oaj.jso.annotation.Jso}
- {@link oaj.json.annotation.JsonAnnotation} implements {@link oaj.json.annotation.Json}
- {@link oaj.jsonschema.annotation.SchemaAnnotation} implements {@link oaj.jsonschema.annotation.Schema}
- {@link oaj.msgpack.annotation.MsgPackAnnotation} implements {@link oaj.msgpack.annotation.MsgPack}
- {@link oaj.oapi.annotation.OpenApiAnnotation} implements {@link oaj.oapi.annotation.OpenApi}
- {@link oaj.plaintext.annotation.PlainTextAnnotation} implements {@link oaj.plaintext.annotation.PlainText}
- {@link oaj.soap.annotation.SoapXmlAnnotation} implements {@link oaj.soap.annotation.SoapXml}
- {@link oaj.uon.annotation.UonAnnotation} implements {@link oaj.uon.annotation.Uon}
- {@link oaj.urlencoding.annotation.UrlEncodingAnnotation} implements {@link oaj.urlencoding.annotation.UrlEncoding}
- {@link oaj.xml.annotation.XmlAnnotation} implements {@link oaj.xml.annotation.Xml}
Example:
@Bean(bpi="street,city") // Will be overridden
public class AddressBean {...}
Bean ba = new BeanAnnotation("AddressBean").bpi("street,city,state");
WriterSerializer ws = JsonSerializer.create().annotations(ba).build();
String json = ws.toString(addressBean); // Will print street,city,state
-
Bean maps now have the concept of "hidden" properties (properties that aren't serialized but otherwise accessible).
For example, the {@link oaj.html.annotation.Html#link()} can now reference hidden properties:
@Bean(bpi="a") // Will be overridden
public class MyBean {
@Html(link="servlet:/{b}")
public String a;
public String b; // Not serialized, but referenced in link on a.
}
The general rule for the {@link oaj.BeanMap} class is that get(),put(), and containsKey()
will work against hidden properties, but keySet() and entrySet() will skip them.
-
Several bug fixes in the {@link oaj.html.HtmlSerializer} and {@link oaj.html.HtmlParser} classes around the handling of
collections and arrays of beans with @Bean(typeName) annotations.
-
New swaps auto-added to all serializers/parsers:
- {@link oaj.transforms.MatchResultSwap}
- {@link oaj.transforms.StackTraceElementSwap}
-
{@link oaj.html.annotation.Html#noTableHeaders} now can be applied to collections of beans.
-
New {@link oaj.html.annotation.HtmlDocConfig#asideFloat()} setting so that you can position the contents of the aside section on the page.
-
Various minor fixes surrounding HTML serialization.
- Collections of beans that were supposed to be serialized as tables were being serialized as lists.
- Collections of beans with @Bean(bpi) were not being serialized in the correct column order.
-
Fixed a bug where a copy constructor can erroneously be recognized as a builder constructor if the class also
has a static create method. Net effect was that the copy constructor would needlessly be called during parsing.
-
New {@link oaj.collections} package containing various convenience fluent-style collection classes:
- {@link oaj.collections.AList}
- {@link oaj.collections.ASet}
- {@link oaj.collections.ASortedSet}
- {@link oaj.collections.AMap}
- {@link oaj.collections.ASortedMap}
- {@link oaj.collections.OMap}
- {@link oaj.collections.OList}
-
{@link oaj.ObjectMap} is being deprecated and replaced with {@link oaj.collections.OMap}.
-
{@link oaj.ObjectList} is being deprecated and replaced with {@link oaj.collections.OList}.
-
All classes in the {@link oaj.http.response} and {@link oaj.http.exception} now have header(String,Object)
methods for adding response headers.
// Method that performs a BASIC Auth handshake.
@RestMethod
public Ok checkBasicAuth(@Header("Authorization") String auth) throws Unauthorized {
if (auth == null)
throw new Unauthorized().header("WWW-Authenticate", "BASIC realm=\"foo\"");
return Ok.OK;
}
-
New annotations for multi-part support:
- {@link oaj.http.annotation.Header#multi()}
- {@link oaj.http.annotation.Query#multi()}
- {@link oaj.http.annotation.FormData#multi()}
-
{@link oaj.BeanTraverseContext#BEANTRAVERSE_ignoreRecursions} setting no longer requires {@link oaj.BeanTraverseContext#BEANTRAVERSE_detectRecursions}
to be enabled.
-
Fixed bug in JSON/UON/URL-Encoding serializers where indentation was not correct of first line when {@link oaj.BeanTraverseContext#BEANTRAVERSE_initialDepth}
used.
-
Fixed bug in JSON/UON/URL-Encoding serializers where properties past the max depth were being serialized as null instead
of being treated as null and not being serialized at all.
-
Fixed bug in HTML serializer where tables of maps were not sorted if SERIALIZER_sortMaps was specified.
-
SERIALIZER_trimNullProperties has been replaced with {@link oaj.serializer.Serializer#SERIALIZER_keepNullProperties SERIALIZER_keepNullProperties}.
-
Improvements to OpenAPI serializer and parser:
- Collection format can now be specified on OBJECTs to allow key/value pairs to be delimited with the same support as ARRAYs.
- New {@link oaj.oapi.OpenApiCommon#OAPI_format OAPI_format} and {@link oaj.oapi.OpenApiCommon#OAPI_collectionFormat OAPI_collectionFormat} properties.
-
Convenience methods added to {@link oaj.httppart.HttpPartSchema} and related classes to simplify schema definitions:
import static org.apache.juneau.httppart.HttpPartSchema.*;
// Old
HttpPartSchema s = schema("object")
.property("f01", schema("array").collectionFormat("pipes").items(schema("string")))
.property("f02", schema("array").collectionFormat("pipes").items(schema("string", "byte")))
.property("f03", schema("array").collectionFormat("pipes").items(schema("string", "date-time")))
.build();
// New
HttpPartSchema s = tObject()
.p("f01", tArray(tString()))
.p("f02", tArray(tByte()))
.p("f03", tArray(tDateTime()))
.build();
-
Fixes where the bean method/constructor visibility wasn't being used when finding swap methods and constructors.
-
HTML-Schema support is being deprecated due to low-use and difficulty in maintaining. It will be removed in 9.0.
-
JuneauLogger class is being deprecated. Improvements in logging in Java 8 make it obsolete.
-
Bean filters can now be specified programmatically through a builder API.
// Create a JSON serializer that only includes specified fields on a specific class.
WriterSerializer s = JsonSerializer
.create()
.beanFilters(BeanFilter.create(MyBean.class).bpi("foo,bar,baz").build())
.build();
-
BeanContext.REST_pojoSwaps replaced with {@link oaj.BeanContext#BEAN_swaps} (and builder methods as well).
-
New Bean Property Interceptor API for intercepting calls to bean getters/setters.
- {@link oaj.transform.BeanInterceptor}
- {@link oaj.annotation.Bean#interceptor Bean(interceptor)}
- {@link oaj.BeanContextBuilder#beanInterceptor(Class,Class)}
-
Fluent setters that follow the withX convention are now automatically detected by all parsers.
// A bean with a fluent setter.
public class MyBean {
public MyBean withFoo(String foo) {
this.foo = foo;
return this;
}
}
Note you could previously use the @BeanProperty annotation to identify these setters.