Apache Juneau Overview
Juneau is a single cohesive framework consisting of the following parts:
Questions via email to<EMAIL_ADDRESS>are always welcome.
Juneau is packed with features that may not be obvious at first. Users are encouraged to ask for code reviews by providing links to specific source files such as through GitHub. Not only can we help you with feedback, but it helps us understand usage patterns to further improve the product.
Juneau started off as a popular internal IBM toolkit called Juno. Originally used for serializing POJOs to and from JSON, it later expanded in scope to include a variety of content types, and then later REST servlet, client, and microservice APIs. It's use grew to more than 50 projects and was one of the most popular community source projects within IBM.
In June of 2016, the code was donated to the Apache Foundation under the project
Maps
and Collections
).
We've strived to keep prerequisites to an absolute minimum in order to make adoption as easy as possible.
The library consists of the following artifacts found in the Maven group "org.apache.juneau"
:
| Category | Maven Artifacts | Description | Prerequisites |
|---|---|---|---|
| juneau-core | juneau-marshall | Serializers and parsers for:
|
|
| juneau-marshall-rdf |
Serializers and parsers for:
|
|
|
| juneau-dto |
Data Transfer Objects for:
|
|
|
| juneau-svl | Simple Variable Language API |
|
|
| juneau-config | Configuration file API |
|
|
| juneau-rest | juneau-rest-server | REST Servlet API |
|
| juneau-rest-server-jaxrs | Optional JAX-RS support |
|
|
| juneau-rest-client | REST Client API |
|
|
| juneau-microservice | juneau-microservice-server | REST Microservice Server API |
|
| juneau-microservice-template | Developer template project |
|
|
| juneau-examples | juneau-examples-core | Core code examples | |
| juneau-examples-rest | REST code examples | ||
| juneau-all | juneau-all |
Combination of the following:
|
|
Each component are also packaged as stand-alone OSGi modules.
The core Maven artifacts of Juneau consist of the following:
juneau-marshall-7.0.0.jar
org.apache.juneau.marshall_7.0.0.jar
The juneau-marshall
artifact contains the API for defining serializers and parsers, and
marshalling support for JSON, XML, HTML, URL-Encoding, UON and others.
It also defines many convenience utility classes used throughout the framework.
One of the goals of Juneau was to make serialization as simple as possible. In a single line of code, you should be able to serialize and parse most POJOs. Despite this simplicity, Juneau provides lots of extensibility and configuration properties for tailoring how POJOs are serialized and parsed.
The built-in serializers in Juneau are fast, efficient, and highly configurable. They work by serializing POJOs directly to streams instead of using intermediate Document Object Model objects.
In most cases, you can serialize objects in one line of code by using one of the default serializers:
In addition to the default serializers, customized serializers can be created using various built-in options:
Default serialization support is provided for Java primitives, Maps
, Collections
,
beans, and arrays.
Extensible support for other data types such as Calendars
, Dates
,
Iterators
is available through the use of POJO swaps (described later).
Parsers work by parsing input directly into POJOs instead of having to create intermediate Document Object Models. This allows them to parse input with minimal object creation.
Like the serializers, you can often parse objects in one line of code by using one of the default parsers:
The parsers can also be used to populating existing bean and collection objects:
Above the serializers and parsers are the {@link org.apache.juneau.serializer.SerializerGroup} and
{@link org.apache.juneau.parser.ParserGroup} classes.
These classes allow serializers and parsers to be retrieved by W3C-compliant HTTP Accept
and Content-Type
values...
The REST servlet API builds upon the SerializerGroup
and ParserGroup
classes
to provide annotated REST servlets that automatically negotiate the HTTP media types and allow the developer
to work with requests and responses as POJOs.
The {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} classes are generic Java representations of JSON objects and arrays. These classes can be used to create "unstructured" models for serialization (as opposed to "structured" models consisting of beans). If you want to quickly generate JSON/XML/HTML from generic maps/collections, or parse JSON/XML/HTML into generic maps/collections, these classes work well.
These classes extend directly from the following JCF classes:
The
These object can be serialized in one of two ways:
Any valid JSON can be parsed into an unstructured model consisting of generic
{@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} objects.
(In theory, any valid XML can also be parsed into an unstructured model, although this has not been
officially 'tested')
The ObjectMap
and ObjectList
classes have many convenience features:
Serializers and parsers have a wide variety of configurable properties.
They all extend from the {@link org.apache.juneau.BeanContextBuilder} class that allows you to easily construct
new instances from scratch or build upon existing instances.
For example, the following code shows how to configure a JSON serializer:
WriterSerializer s = JsonSerializer
.
Configurable settings can also be set declaratively.
The following produces the same serializer.
WriterSerializer s = JsonSerializer
.
However, each of the serializers and parsers already contain reusable instances with common configurations.
For example, JSON has the following predefined reusable serializers and parsers:
These can be used directly, as follows:
For performance reasons, serializers and parsers are immutable.
However, they can be 'copied' and modified using the builder()
method.
The following is a list of all configurable properties across all serializers and parsers.
All the serializers, parsers, and REST server/client classes use the following design pattern:
BeanContext
, JsonSerializer
BeanContextBuilder
, JsonSerializerBuilder
Context
objects.
BeanSession
, JsonSerializerSession
Context
contains one PropertyStore
.
PropertyStore
objects.
ContextBuilder
contains one PropertyStoreBuilder
.
For example, the class hierarchy for JsonSerializer
is:
Object
Each context object in the hierarchy define properties that can be stored in a PropertyStore
such as
The class hierarchy for JsonSerializerBuilder
is:
Object
The class hierarchy for JsonSerializerSession
is:
Object
The general idea behind a {@link org.apache.juneau.PropertyStore} is to serve as a reusable configuration of an artifact (such as a serializer) such that the artifact can be cached and reused if the property stores are 'equal'.
For example, two serializers of the same type created with the same configuration will always end up being the same serializer:
This has the effect of significantly improving performance, especially if you're creating many serializers and parsers.
The {@link org.apache.juneau.PropertyStoreBuilder} class is used to build up and instantiate immutable
PropertyStore
objects.
In the example above, the property store being built looks like the following:
PropertyStore ps = PropertyStore
.
Property stores are immutable, comparable, and their hashcodes are calculated exactly one time. That makes them particularly suited for use as hashmap keys, and thus for caching reusable serializers and parsers.
Refer to the {@link org.apache.juneau.PropertyStore} javadoc for a detailed explaination on how property stores work.
By default, the Juneau framework can serialize and parse a wide variety of POJOs out-of-the-box.
However, two special classes are provided tailor how certain Java objects are handled by the framework.
These classes are:
Transforms are added to serializers and parsers (and REST clients) using the following configuration properties:
Annotations are also provided for specifying transforms directly on classes and methods (all described in later sections):
{@link org.apache.juneau.transform.PojoSwap PojoSwaps} are a critical component of Juneau. They allow the serializers and parsers to handle Java objects that wouldn't normally be serializable.
Swaps are, simply put, 'object swappers' that swap in serializable objects for non-serializable ones during serialization, and vis-versa during parsing.
Some examples of non-serializable POJOs are File
, Reader
,
Iterable
, etc...
These are classes that aren't beans and cannot be represented as simple maps, collections, or primitives.
In the following example, we introduce a PojoSwap
that will swap in ISO8601 strings for
Date
objects:
The swap can then be associated with serializers and parsers like so:
The {@link org.apache.juneau.BeanMap#get(Object)} and {@link org.apache.juneau.BeanMap#put(String,Object)} methods will automatically convert to swapped values as the following example shows:
Another example of a PojoSwap
is one that converts
arrays to
BASE64-encoded strings:
The following example shows the BASE64 swap in use:
Several PojoSwaps
are already provided for common Java objects:
In particular, the {@link org.apache.juneau.transforms.CalendarSwap} and {@link org.apache.juneau.transforms.DateSwap} transforms provide a large number of customized swaps to ISO, RFC, or localized strings.
Swaps have access to the session locale and timezone through the {@link org.apache.juneau.BeanSession#getLocale()} and
{@link org.apache.juneau.BeanSession#getTimeZone()} methods.
This allows you to specify localized swap values when needed.
If using the REST server API, the locale and timezone are set based on the Accept-Language
and
Time-Zone
headers on the request.
Swaps can also be defined per-media-type.
The {@link org.apache.juneau.transform.PojoSwap#forMediaTypes()} method can be overridden to
provide a set of media types that the swap is invoked on.
It's also possible to define multiple swaps against the same POJO as long as they're differentiated
by media type.
When multiple swaps are defined, the best-match media type is used.
In the following example, we define 3 swaps against the same POJO. One for JSON, one for XML, and one for all other types.
In the previous sections, we defined two-way swaps, meaning swaps where the original objects could be
reconstructing during parsing.
However, there are certain kinds of POJOs that we may want to support for serializing, but that are not
possible to reconstruct during parsing.
For these, we can use one-way object swaps.
A one-way POJO swap is simply an object transform that only implements the {@code swap()} method.
The {@code unswap()} method is simply left unimplemented.
An example of a one-way swaps would be one that allows {@code Iterators} to be serialized as JSON arrays.
It can make sense to be able to render {@code Iterators} as arrays, but in general it's not possible to
reconstruct an {@code Iterator} during parsing.
Here is an example of our one-way swap being used.
Note that trying to parse the original object will cause a {@link org.apache.juneau.parser.ParseException}
to be thrown.
{@link org.apache.juneau.annotation.Swap @Swap} can be used to associate a swap class using an
annotation.
This is often cleaner than using the builder pojoSwaps()
method since you can keep
your swap class near your POJO class.
Multiple swaps can be associated with a POJO by using the {@link org.apache.juneau.annotation.Swaps @Swaps} annotation:
Readers
get serialized directly to the output of a serializer.
Therefore it's possible to implement a swap that provides fully-customized output.
The
The {@link org.apache.juneau.annotation.Swap#template() @Swap.template()} annotation allows you to associate
arbitrary contextual strings with swaps.
The primary purpose is for providing template names, such as for Apache FreeMarker, therefore
the name 'template'.
However, the usage of the string is open-ended.
For example, you could pair a template string like so:
The implementation of the FreeMarker swap would look something like this:
Various methods can be defined on a class directly to affect how it gets serialized.
This can often be simpler than using PojoSwaps
.
Objects serialized as Strings
can be parsed back into their original objects by
implementing one of the following methods on the class:
public static T fromString(String)
method.
valueOf(String)
parse(String)
parseString(String)
forName(String)
forString(String)
public T(String)
constructor.
Note that these methods cover conversion from several built-in Java types, meaning the parsers can automatically construct these objects from strings:
fromString(String)
- {@link java.util.UUID}
valueOf(String)
- {@link java.lang.Boolean}, {@link java.lang.Byte},
{@link java.lang.Double}, {@link java.lang.Float},
{@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Short}, {@link java.sql.Date},
{@link java.sql.Time}, {@link java.sql.Timestamp}
parse(String)
- {@link java.text.DateFormat}, {@link java.text.MessageFormat},
{@link java.text.NumberFormat}, {@link java.util.Date}, {@link java.util.logging.Level}
parseString(String)
- {@link javax.xml.bind.DatatypeConverter}
forName(String)
- {@link java.lang.Class}
If you want to force a bean-like class to be serialized as a string, you can use the
{@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} annotation on the class to force it to be
serialized to a string using the toString()
method.
Serializing to other intermediate objects can be accomplished by defining a swap method directly on the class:
public X swap(BeanSession)
method, where X
is any serializable
object.
The BeanSession
parameter allows you access to various information about the current
serialization session.
For example, you could provide customized results based on the media type being produced
({@link org.apache.juneau.BeanSession#getMediaType()}).
The following example shows how an HTML5 form template object can be created that gets serialized as a populated HTML5 {@link org.apache.juneau.dto.html5.Form} bean.
Swapped objects can be converted back into their original form by the parsers by specifying one of the following methods:
public static T unswap(BeanSession, X)
method where X
is the
swap class type.
public T(X)
constructor where X
is the swap class type.
The following shows how our form template class can be modified to allow the parsers to reconstruct our original object:
Surrogate classes are very similar in concept to one-way PojoSwaps
except they represent a
simpler syntax.
For example, let's say we want to be able to serialize the following class, but it's not serializable for some reason (for example, there are no properties exposed):
This could be solved with the following PojoSwap
.
However, the same can be accomplished by using a surrogate class that simply contains a constructor with the non-serializable class as an argument:
The surrogate class is registered in the same way as a PojoSwap
:
When the serializer encounters the non-serializable class, it will serialize an instance of the surrogate instead.
The {@link org.apache.juneau.annotation.Bean @Bean} annotation is used to tailor how beans are interpreted by the framework.
Bean property inclusion and ordering on a bean class can be done using the {@link org.apache.juneau.annotation.Bean#properties() @Bean.properties()} annotation.
Bean properties can be excluded using the {@link org.apache.juneau.annotation.Bean#excludeProperties() @Bean.excludeProperties()} annotation.
Bean properties can be sorted alphabetically using {@link org.apache.juneau.annotation.Bean#sort() @Bean.sort()}
The {@link org.apache.juneau.annotation.Bean#propertyNamer() @Bean.propertyNamer()} annotation is used to provide customized naming of properties.
Property namers are used to transform bean property names from standard form to some other form.
For example, the {@link org.apache.juneau.PropertyNamerDLC} will convert property names to
dashed-lowercase, and these will be used as attribute names in JSON and element names in XML.
The {@link org.apache.juneau.annotation.Bean#interfaceClass @Bean.interfaceClass()} annotation is used
to limit properties on beans to specific interface classes.
When specified, only the list of properties defined on the interface class will be used during
serialization.
Additional properties on subclasses will be ignored.
Note that this annotation can be used on the parent class so that it filters to all child classes.
Or can be set individually on the child classes.
The {@link org.apache.juneau.annotation.Bean#stopClass @Bean.stopClass()} annotation is another
way to limit which properties are serialized (except from the opposite direction).
It's identical in purpose to the stop class specified by {@link java.beans.Introspector#getBeanInfo(Class, Class)}.
Any properties in the stop class or in its base classes will be ignored during analysis.
For example, in the following class hierarchy, instances of C3
will include property
p3
, but not p1
or p2
.
The {@link org.apache.juneau.annotation.Bean#propertyFilter() @Bean.propertyFilter()} annotation and {@link org.apache.juneau.transform.PropertyFilter} class can be used to perform interception and inline handling of bean getter and setter calls.
The {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotation is used to tailor how individual bean properties are interpreted by the framework.
The {@link org.apache.juneau.annotation.BeanProperty#name() @BeanProperty.name()} annotation is used to override the name of the bean property.
If the {@link org.apache.juneau.BeanContext#BEAN_beanFieldVisibility} setting on the bean context excludes this field (e.g. the visibility is set to the default of PUBLIC, but the field is PROTECTED), this annotation can be used to force the field to be identified as a property.
The bean property named
This is similar in concept to the Jackson
The primary purpose is for backwards compatibility in parsing newer streams with addition
information into older beans.
The following shows various ways of using dynamic bean properties.
Similar rules apply for value types and swaps.
The property values optionally can be any serializable type or use swaps.
The {@link org.apache.juneau.annotation.BeanProperty#value() @BeanProperty.value()} annotation
is a synonym for {@link org.apache.juneau.annotation.BeanProperty#name() @BeanProperty.name()}.
Use it in cases where you're only specifying a name so that you can shorten your annotation.
The following annotations are equivalent:
The {@link org.apache.juneau.annotation.BeanProperty#type() @BeanProperty.type()} annotation
is used to identify a specialized class type for a generalized property.
Normally the type is inferred through reflection of the field type or getter return type.
However, you'll want to specify this value if you're parsing beans where the bean property class
is an interface or abstract class to identify the bean type to instantiate.
Otherwise, you may cause an {@link java.lang.InstantiationException} when trying to set these fields.
This property must denote a concrete class with a no-arg constructor.
The {@link org.apache.juneau.annotation.BeanProperty#params() @BeanProperty.params()} annotation
is for bean properties of type map or collection.
It's used to identify the class types of the contents of the bean property object when
the general parameter types are interfaces or abstract classes.
The {@link org.apache.juneau.annotation.BeanProperty#properties() @BeanProperty.properties()}
annotation is used to limit which child properties are rendered by the serializers.
It can be used on any of the following bean property types:
The {@link org.apache.juneau.annotation.BeanProperty#format() @BeanProperty.format()} annotation specifies a String format for converting a bean property value to a formatted string.
The {@link org.apache.juneau.annotation.BeanConstructor @BeanConstructor} annotation is used to
map constructor arguments to property names on bean with read-only properties.
Since method parameter names are lost during compilation, this annotation essentially redefines
them so that they are available at runtime.
The definition of a read-only bean is a bean with properties with only getters, like shown below:
Beans can also be defined with a combination of read-only and read-write properties.
The {@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} annotation is used to ignore classes, fields, and methods from being interpreted as beans or bean components.
When applied to classes, objects will be converted to strings even though they look like beans.
When applied to fields and getters/setters, they will be ignored as bean properties.
The {@link org.apache.juneau.annotation.NameProperty @NameProperty} annotation is used to identify a setter as a method for setting the name of a POJO as it's known by its parent object.
A commonly-used case is when you're parsing a JSON map containing beans where one of the bean properties is the key used in the map.
The {@link org.apache.juneau.annotation.ParentProperty @ParentProperty} annotation is used to identify a setter as a method for adding a parent reference to a child object.
A commonly-used case is when you're parsing beans and a child bean has a reference to a parent bean.
Parsers will automatically set this field for you in the child beans.
Juneau serializers have sophisticated support for transforming relative URIs to absolute form.
The following example shows a bean containing URIs of various forms and how they end up serialized.
URI resolution is controlled by the following settings:
Juneau automatically interprets any {@link java.net.URL} and {@link java.net.URI} objects as URIs and will
resolve them accordingly.
The {@link org.apache.juneau.annotation.URI @URI} annotation can be used to extend that to other bean
properties and class types so that they also get interpreted as URIs.
For example:
The {@link org.apache.juneau.transform.BeanFilter} class is the programmatic equivalent to the {@link org.apache.juneau.annotation.Bean @Bean} annotation.
In practice, it's usually simpler to use the {@link org.apache.juneau.annotation.Bean @Bean} and
{@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotations on your bean classes.
However, bean filters make it possible to accomplish the same when you can't add annotations
to existing code.
Bean filters are defined through {@link org.apache.juneau.transform.BeanFilterBuilder BeanFilterBuilders}.
In the previous examples, we defined this bean annotation:
The programmatic equivalent would be:
Bean filters are added to serializers and parsers using the following:
For example:
Note that if you use the annotation, you do NOT need to set anything on the serializers/parsers.
The annotations will be detected and bean filters will automatically be created for them.
The {@link org.apache.juneau.BeanContextBuilder#beanFilters(Object...)} method also allows you to pass in interfaces.
Any class that's not a subclass of {@link org.apache.juneau.transform.BeanFilterBuilder} get interpreted
as bean interface classes.
These cause bean implementations of those interfaces to only expose the properties defined on the
interface.
Occasionally, you may want to limit bean properties to only those defined on a parent class or interface.
This is accomplished through interface filters.
Interface filters are defined through the following:
For example, let's define the following interface and implementation:
Suppose we only want to render the properties defined on our interface, not the implementation.
To do so, we can define the following bean filter:
When serialized, the serialized bean will only include properties defined on the interface.
WriterSerializer s = JsonSerializer
.
The {@link org.apache.juneau.BeanContextBuilder#beanFilters(Object...)} method will automatically interpret any
non-BeanFilter
classes passed in as meaning interface classes.
So in the previous example, the BeanFilter
class could have been avoided altogether by just
passing in MyInterface.
to the serializer, like so:
WriterSerializer s = JsonSerializer
.
The annotation equivalent is {@link org.apache.juneau.annotation.Bean#interfaceClass() Bean#interfaceClass()}.
The annotation can be used in a couple of ways.
Using the annotation on an interface will be inherited by all children.
The annotation can be used on parent classes as well.
Child beans will only serialize properties defined on the parent class.
Whereas interface filters limit properties defined on child classes, stop filters do the opposite and limit properties defined on parent classes.
Stop classes are defined through the following:
Stop classes are identical in purpose to the stop class specified by {@link java.beans.Introspector#getBeanInfo(Class, Class)}.
Any properties in the stop class or in its base classes will be ignored during serialization.
For example, in the following class hierarchy, instances of C3
will include property p3
,
but not p1
or p2
.
Juneau serializers treat instances of Readers
and InputStreams
special by
simply serializing their contents directly to the output stream or writer.
This allows you to embed fully customized serializer output.
Note that if you're serializing Readers and InputStreams, it's up to you to make sure you're producing valid output (in this case JSON).
A more typical scenario where this is useful is by using swaps to convert POJOs to Readers whose
contents are determined via the {@link org.apache.juneau.BeanSession#getMediaType()} method.
In the following example, we're customizing the JSON output for a particular bean type, but leaving
all other renditions as-is:
While parsing into beans, Juneau attempts to determine the class types of bean properties through
reflection on the bean property getter or setter.
Often this is insufficient if the property type is an interface or abstract class that cannot be
instantiated.
This is where bean names and dictionaries come into play.
Bean names and dictionaries are used for identifying class types when they cannot be inferred through reflection.
Bean classes are given names through the {@link org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()}
annotation.
These names are then added to the serialized output as virtual
On the parsing side, these type names are resolved to classes through the use of bean dictionaries.
For example, if a bean property is of type Object
, then the serializer will add
When serialized as JSON,
{
x: [
{_type:
Type names can be represented slightly differently in different languages.
For example, the dictionary name is used as element names when serialized to XML.
This allows the typeName
annotation to be used as a shortcut for defining element names for
beans.
When serialized as XML, the bean is rendered as:
Bean dictionaries are registered through the following:
The bean dictionary setting can consist of any of the following types:
The
When using the annotation, you'll typically want to define it on an interface class so that it can be inherited by all subclasses.
object, array, number, boolean, null
.
In addition to the bean type name support described above, simplified support is provided for bean subtypes.
Bean subtypes are similar in concept to bean type names, except for the following differences:
In the following example, the abstract class has two subclasses:
When serialized, the subtype is serialized as a virtual
JsonSerializer s = JsonSerializer.
The following shows what happens when parsing back into the original object.
JsonParser p = JsonParser.
The {@link org.apache.juneau.BeanContext#BEAN_useInterfaceProxies} setting (enabled by default) allows the Juneau parsers to parse content into virtual beans (bean interfaces without implementation classes).
For example, the following code creates an instance of the specified unimplemented interface:
Getter and setter values can be any parsable values, even other virtual beans.
Under-the-covers, a virtual bean is simply a proxy interface on top of an existing BeanMap
instance. From a programmatic point-of-view, they're indistinguishable from real beans, and can be
manipulated and serialized like any other bean.
Virtual beans can also be created programmatically using the BeanContext
class:
Address address = BeanContext.
Juneau was developed independently from Jackson, but shares many of the same features and capabilities. Whereas Jackson was created to work primarily with JSON, Juneau was created to work for multiple languages. Therefore, the terminology and annotations in Juneau are similar, but language-agnostic.
The following charts describe equivalent features between the two libraries:
| Jackson | Juneau |
|---|---|
|
|
{@link org.apache.juneau.annotation.BeanProperty @BeanProperty} |
|
|
{@link org.apache.juneau.annotation.BeanProperty#name() @BeanProperty(name="*")} |
|
|
{@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} |
|
{@link org.apache.juneau.annotation.Bean#excludeProperties @Bean(excludeProperties="...")} |
|
No equivalent annotation, but can be controlled via:
{@link org.apache.juneau.BeanContext#BEAN_beanFieldVisibility} {@link org.apache.juneau.BeanContext#BEAN_beanMethodVisibility} Future annotation support planned. |
|
|
{@link org.apache.juneau.annotation.BeanConstructor @BeanConstructor} |
|
No equivalent.
Future support planned. |
|
|
|
Juneau uses swaps to convert non-serializable object to serializable forms:
{@link org.apache.juneau.annotation.Swap @Swap} |
|
No equivalent annotation, but can be controlled via various settings:
{@link org.apache.juneau.BeanContext} {@link org.apache.juneau.serializer.Serializer} Future annotation support planned. |
|
|
{@link org.apache.juneau.annotation.Bean#properties @Bean(properties="...")}
{@link org.apache.juneau.annotation.Bean#sort @Bean(sort=x)} |
|
|
|
Can be replicated using swaps with Reader swapped values.
|
The following chart shows POJOs categorized into groups and whether they can be serialized or parsed:
| Group | Description | Examples | Can serialize? | Can parse? |
|---|---|---|---|---|
| 1 | Java primitives and primitive objects |
|
yes | yes |
| 2 | Java Collections Framework objects and Java arrays | |||
| 2a |
With standard keys/values
Map keys are group [1, 4a, 6a] objects. Map, Collection, and array values are group [1, 2, 3ac, 4a, 6a] objects. |
|
yes | yes |
| 2b |
With non-standard keys/values
Map keys are group [2, 3, 4b, 5, 6b, 7] objects. Map, Collection, and array values are group [3b, 4b, 5, 6b, 7] objects. |
|
yes | no |
| 3 | Java Beans | |||
| 3a |
With standard properties
These are beans that have one or more properties defined by public getter or public fields. Properties can also be defined as final read-only fields and passed in as constructor args. Property values are group [1, 2, 3ac, 4a, 6a] objects. |
yes | yes | |
| 3b |
With non-standard properties or not true beans
These include true beans that have one or more properties defined by getter and setter methods or properties, but property types include group [3b, 4b, 5, 6b, 7] objects. This also includes classes that look like beans but aren't true beans. For example, classes that have getters but not setters, or classes without no-arg constructors. |
yes | no | |
| 3c |
Virtual beans
These are unimplemented bean interfaces with properties of type [1, 2, 3ac, 4a, 6a] objects. Parsers will automatically create interface proxies on top of BeanMap instances. |
yes | yes | |
| 3d |
Read-only beans without setters
The same as 3a, but without property setters or constructor args. |
yes | no | |
| 4 |
Swapped objects
These are objects that are not directly serializable, but have {@link org.apache.juneau.transform.PojoSwap PojoSwaps} associated with them. The purpose of a POJO swap is to convert an object to another object that is easier to serialize and parse. For example, the {@link org.apache.juneau.transforms.DateSwap.ISO8601DT} class can be used to serialize {@link java.util.Date} objects to ISO8601 strings, and parse them back into {@link java.util.Date} objects. |
|||
| 4a |
2-way swapped to group [1, 2a, 3ac] objects
For example, a swap that converts a {@code Date} to a {@code String}. |
|
yes | yes |
| 4b |
1-way swapped to group [1, 2, 3] objects
For example, a swap that converts an {@code Iterator} to a {@code List}. This would be one way, since you cannot reconstruct an {@code Iterator}. |
|
yes | no |
| 5 |
Readers and InputStreams
Contents are serialized directly to the output stream or writer. Typically used for low-level language-specific replacement of POJOs using per-Media-Type POJO swaps. |
|
yes | no |
| 6 |
Non-serializable objects with standard methods for converting to a serializable form |
|||
| 6a |
Classes with a method that converts it to a serializable form:
|
|
yes | yes |
| 6b |
Classes that only have a method to convert to a serializable form:
|
yes | no | |
| 7 |
All other objects
Anything that doesn't fall into one of the groups above are simply converted to {@code Strings} using the {@code toString()} method. |
yes | no |
Extensive javadocs exist for individual language support. Refer to these docs for language-specific information.
juneau-marshall-rdf-7.0.0.jar
org.apache.juneau.marshall.rdf_7.0.0.jar
The juneau-marshall-rdf
library provides additional serializers and parsers for RDF.
These rely on the Apache Jena library to provide support for the following languages:
The serializers and parsers work identically to those in juneau-marshall
, but are
packaged separately so that you don't need to pull in the Jena dependency unless you need it.
juneau-dto-7.0.0.jar
org.apache.juneau.dto_7.0.0.jar
The juneau-dto
library contains several predefined POJOs for generating commonly-used document types.
This section describes support for these POJOs.
The Juneau HTML5 DTOs are simply beans with fluent-style setters that allow you to quickly construct HTML fragments as Java objects. These object can then be serialized to HTML using one of the existing HTML serializers, or to other languages such as JSON using the JSON serializers.
The {@link org.apache.juneau.dto.html5.HtmlBuilder} class is a utility class with predefined static methods that allow you to easily construct DTO instances in a minimal amount of code.
The following examples show how to create HTML tables.
| Java code | HTML |
|---|---|
|
|
|
|
|
|
|
|
Using the HTML5 DTOs, you should be able to construct any valid HTML5 from full document bodies to any possible fragments.
The {@link org.apache.juneau.html.HtmlParser} class can be used convert these HTML documents back into POJOs.
Other serializers and parsers (e.g. {@link org.apache.juneau.json.JsonSerializer}) can be used to represent these POJOs in languages other than HTML.
The Juneau ATOM feed DTOs are simply beans with fluent-style setters.
The following code shows a feed being created programmatically using the
{@link org.apache.juneau.dto.atom.AtomBuilder} class.
To serialize this to ATOM, use the {@link org.apache.juneau.xml.XmlSerializer} class:
The {@link org.apache.juneau.xml.XmlParser} class can be used convert these Atom documents back into POJOs.
Other serializers and parsers (e.g. {@link org.apache.juneau.json.JsonSerializer}) can be used to represent these POJOs in languages other than XML.
The Juneau Swagger DTOs are simply beans with fluent-style setters that allow you to quickly construct Swagger documents as Java objects. These object can then be serialized to JSON using one of the existing JSON serializers, or to other languages such as XML or HTML using the other serializers.
The {@link org.apache.juneau.dto.swagger.SwaggerBuilder} class is a utility class with predefined static methods that allow you to easily construct DTO instances in a minimal amount of code.
The following is an example Swagger document from the Swagger website.
{
This document can be generated by the following Java code:
Methods that take in beans and collections of beans can also take in JSON representations of those objects.
Properties can also be accessed via the {@link org.apache.juneau.dto.swagger.SwaggerElement#get(String,Class)}
and {@link org.apache.juneau.dto.swagger.SwaggerElement#set(String,Object)} methods.
These methods can also be used to set and retrieve non-Swagger attributes such as
Swagger docs can be parsed back into Swagger beans using the following code:
Swagger swagger = JsonParser.
juneau-svl-7.0.0.jar
org.apache.juneau.svl_7.0.0.jar
The juneau-svl
library defines an API for a language called "Simple Variable Language".
In a nutshell, Simple Variable Language (or SVL) is text that contains variables of the form
Variables can be recursively nested within the varKey (e.g.
The following shows how variables can be arbitrarily nested...
SVL is a large topic on it's own. It is used extensively in the ConfigFile, REST and Microservice APIs.
juneau-config-7.0.0.jar
org.apache.juneau.config_7.0.0.jar
The juneau-config
library contains a powerful API for creating and using INI-style config files.
An example of an INI file:
This class can be used to easily access contents of the file:
The interface also allows a config file to be easily constructed programmatically:
The following is equivalent, except that it uses {@link org.apache.juneau.ini.ConfigFile#put(String, Object)} to set values:
Values are LAX JSON (i.e. unquoted attributes, single quotes) except for top-level strings which are left unquoted. Any parsable object types are supported as values (e.g. arrays, collections, beans, swappable objects, enums, etc...).
The config file looks deceptively simple, the config file API is a very powerful feature with many capabilities, including:
Config files can also be used to directly populate beans using the {@link org.apache.juneau.ini.ConfigFile#getSectionAsBean(String,Class,boolean)}:
Config file sections can also be accessed via interface proxies using {@link org.apache.juneau.ini.ConfigFile#getSectionAsInterface(String,Class)}:
The REST Maven artifacts of Juneau consist of the following:
juneau-rest-server-7.0.0.jar
org.apache.juneau.rest.server_7.0.0.jar
The juneau-rest-server
library provides servlet-based REST resources on top of existing POJOs.
The API automatically detects
Automatic built-in support is provided for negotiation of response character sets and gzip encoding.
The following is an example of a REST API used to view and set JVM system properties.
The resource above is deployed like any other servlet, in this way:
Pointing your browser to the resource renders the POJOs as HTML (since that's what the browser specifies in the
Accept
header).
One of the most useful aspects of using this API is the self-discovering, self-documenting OPTIONS pages. These are constructed automatically using reflection, augmented with information pulled from annotations (as shown above), resource bundles, or Swagger JSON files:
Arbitrarily complex POJO models can be serialized using any of the supported serializers, and content can be parsed using any of the supported parsers.
The
The framework allows you to override header values through GET parameters, so that you can specify the
Also, localization can be tested by passing in an
The Server API is an exhaustive topic on its own. Refer to the additional information for an in-depth examination of the API.
Juneau provides the capability of calling methods on POJOs on a server through client-side proxy interfaces. It offers a number of advantages over other similar remote proxy interfaces, such as being much simpler to define and use, and allowing much more flexibility in the types of objects serialized.
The remote proxy interface API allows you to invoke server-side POJO methods on the client side using REST as the communications protocol:
Under the covers, this method call gets converted to a REST POST.
HTTP POST http://localhost/remoteable/org.apache.juneau.examples.rest.IAddressBook/createPerson Accept: application/json Content-Type: application/json [ { "name":"John Smith", "birthDate":"Aug 1, 1999", "addresses":[ { "street":"My street", "city":"My city", "state":"My state", "zip":12345, "isCurrent":true } ] } ]
Note that the body of the request is an array. This array contains the serialized arguments of the method. The object returned by the method is then serialized as the body of the response.
To define a remoteable interface, simply add the {@link org.apache.juneau.remoteable.Remoteable @Remoteable} annotation to your interface class.
This annotation tells the framework that all methods defined on this interface can be executed remotely. It can be applied to super-interfaces, super-classes, etc..., and exposes the methods at whatever level it is defined.
The {@link org.apache.juneau.remoteable.RemoteMethod @RemoteMethod} annotation can also be used on individual methods to tailor which methods are exposed or their paths.
There are two ways to expose remoteable proxies on the server side:
RemoteableServlet
.
@RestMethod (name=PROXY )
annotation on a Java method.
The RemoteableServlet
class is a simple specialized servlet with an abstract
getServiceMap()
method to define the server-side POJOs:
The
approach is easier if you only have a single
interface you want to expose.
You simply define a Java method whose return type is an interface, and return the implementation of that
interface:
In either case, the proxy communications layer is pure REST. Therefore, in cases where the interface classes are not available on the client side, the same method calls can be made through pure REST calls. This can also aid significantly in debugging, since calls to the remoteable service can be made directly from a browser with no coding involved.
The parameters and return types of the Java methods can be any of the supported serializable and parsable types in POJO Categories. This ends up being WAY more flexible than other proxy interfaces since Juneau can handle so may POJO types out-of-the-box. Most of the time you don't even need to modify your existing Java implementation code.
The RemoteableServlet
class itself shows how sophisticated REST interfaces can be built on the Juneau
RestServlet API using very little code.
The class consists of only 53 lines of code, yet is a sophisticated discoverable and
self-documenting REST interface.
And since the remote proxy API is built on top of REST, it can be debugged using just a browser.
The requirements for a method to be callable through a remoteable service are:
Throwables
with public no-arg or single-arg-string constructors which will
be automatically recreated on the client side.
The Juneau REST server API is compatible with dependency injection frameworks such as Spring.
The important class is the {@link org.apache.juneau.rest.RestResourceResolver} class which is used to resolve child servlet/resource implementation classes inside parent contexts. In other words, it's used for resolving {@link org.apache.juneau.rest.annotation.RestResource#children() @RestResource.children()} instances.
The general approach starts with defining a resolver that uses the Spring application context for resolution:
Next, define the Spring configuration to return our resolver:
Finally, define your Root
resource with a constructor that takes in our rest resource resolver and
sets it on the config object during initialization.
After that, just define constructors on your child resources to take in Spring beans:
Juneau is built as a veneer on top of the Servlet API, allowing you to use low-level Servlet APIs whenever needed. This allows you to take advantage of the newest HTTP/2 features implemented in the new Servlet 4.0 specification.
Coming soon (sorry)
juneau-rest-server-jaxrs-7.0.0.jar
org.apache.juneau.rest.server_7.0.0.jar
The juneau-rest-server-jaxrs
library provides an implementation of a MessageBodyReader
and MessageBodyWriter
to allow any of the Juneau serializers and parsers to be used in a
JAX/RS environment.
juneau-rest-client-7.0.0.jar
org.apache.juneau.rest.client_7.0.0.jar
The REST client API provides the ability to access remote REST interfaces and transparently convert the input and output to and from POJOs using any of the provided serializers and parsers.
Built upon the
The Client API is also an exhaustive topic on its own. Refer to the additional information for an in-depth examination of the API.
The juneau-rest-client
library can also be used to define interface proxies against 3rd-party REST interfaces.
This is an extremely powerful feature that allows you to quickly define easy-to-use interfaces against
virtually any REST interface.
Similar in concept to remoteable services defined above, but in this case we simply define our interface with special annotations that tell us how to convert input and output to HTTP headers, query parameters, form post parameters, or request/response bodies.
The Java method arguments can be annotated with any of the following:
Map<String,Object>
- Individual name-value pairs.
String
- Treated as a query string.
POST
.
Map<String,Object>
- Individual name-value pairs.
Map<String,Object>
- Individual name-value pairs.
RestClient
.
The return type of the Java method can be any of the following:
RestClient
.
HttpResponse
- Returns the raw HttpResponse
returned by the inner HttpClient
.
The Microservice Maven artifacts of Juneau consist of the following:
Microservices combine all the functionality of the core, server, and client APIs to provide truly powerful and easy-to-use REST interfaces with minimal overhead.
juneau-microservice-server-7.0.0.jar
org.apache.juneau.microservice.server_7.0.0.jar
The juneau-microservice-server
library consists of the following classes used for constructing
stand-alone microservices as executable jars or inside docker containers:
RestServletDefault
with support for manfest-file and args variables
and configured to use the external INI file.
RestServletGroupDefault
with support for manfest-file and args variables
and configured to use the external INI file.
The following predefined resource classes are also provided for easy inclusion into your microservice:
my-microservice-7.0.0.zip
The juneau-microservice-template
project creates an archive file containing an Eclipse
project that can be loaded into an Eclipse workspace to quickly get a microservice project
up-and-running.
Download the my-microservice-7.0.0.zip
file from the downloads page
(located in the binaries) and import it into your workspace as an existing project:
Select the archive file and import the project:
Once loaded, you should see the following project structure:
The microservice can be started from the my-microservice.launch
file.
It will start up the microservice on port 10000 which you can then view through a browser:
Now play with it!
The Example Maven artifacts of Juneau consist of the following:
juneau-examples-core-7.0.0.zip
The juneau-examples-core
project contains various code examples for using the core APIs.
The project project can be loaded into your workspace by importing the
juneau-examples-core-7.0.0.zip
file.
Download the juneau-examples-core-7.0.0.zip
file from the downloads page
(located in the binaries) and import it into your workspace as an existing project:
Select the archive file and import the project:
Once loaded, you should see the following project structure:
The Core library samples are currently a work-in-progress so there's not much here yet. This section will be updated as new code is added.
juneau-examples-rest-7.0.0.zip
The juneau-examples-rest
project includes everything you need to start the Samples REST
microservice in an Eclipse workspace.
This project is packaged as a Juneau Microservice project that allows REST resources to be started using embedded Jetty.
Download the juneau-examples-rest-7.0.0.zip
file from the downloads page
(located in the binaries) and import it into your workspace as an existing project:
Select the archive file and import the project:
Once loaded, you should see the following project structure:
The microservice can be started from the juneau-examples-rest.launch
file.
It will start up the microservice on port 10000 which you can then view through a browser:
The
The class hierarchy for this class is:
org.apache.juneau.rest.samples.RootResources
Pointing a browser to the resource shows the following:
The
The
The resource bundle contains the localized strings for the resource:
The
The
Child resources must also be subclasses of {@link org.apache.juneau.rest.RestServlet}, and
must specify a {@link org.apache.juneau.rest.annotation.RestResource#path() @RestResource.path()} annotation to
identify the subpath of the child.
For example, the
It should be noted that child resources do not need to be defined this way.
They could also be defined as servlets in the same way as the root resource.
The
Note that these router pages can be arbitrarily nested deep. You can define many levels of router pages for arbitrarily hierarchical REST interfaces.
The
The class hierarchy for this class is:
org.apache.juneau.rest.samples.HelloWorldResource
Pointing a browser to the resource shows the following:
Using the special
The
The resource is provided to show how various HTTP entities (e.g. parameters, headers) can be accessed
as either annotated Java parameters, or through methods on the
The class consists of 4 methods:
There's a lot going on in this method. Notice how you're able to access URL attributes, parameters, headers, and content as parsed POJOs. All the input parsing is already done by the toolkit. You simply work with the resulting POJOs.
As you might notice, using annotations typically results in fewer lines of code and are therefore usually preferred over the API approach, but both are equally valid.
When you visit this page through the router page, you can see the following (after the automatic redirection occurs):
Notice how the conversion to POJOs is automatically done for us, even for non-standard POJOs such as UUID.
One of the main features of Juneau is that it produces OPTIONS pages for self-documenting design (i.e. REST interfaces that document themselves).
Much of the information populated on the OPTIONS page is determined through reflection. This basic information can be augmented with information defined through:
SystemPropertiesResource
example above.
$L
localization variable.
MethodExampleResource.json
).
MethodExampleResource_ja_JP.json
);
OPTIONS pages are simply serialized {@link org.apache.juneau.dto.swagger.Swagger} DTO beans. Localized versions of these beans are retrieved using the {@link org.apache.juneau.rest.RestRequest#getSwagger()} method.
To define an OPTIONS request handler, the {@link org.apache.juneau.rest.RestServletDefault} class defines the following Java method:
The
This simply creates a link that's the same URL as the resource URL appended with
Metadata about the servlet class is combined with localized strings from a properties file associated
through a
annotation.
The properties file contains localized descriptions for the resource, resource methods, and method
parameters.
Clicking the
This page (like any other) can also be rendered in JSON or XML by using the
The
The class is shown below:
The {@link org.apache.juneau.rest.RestRequest#getClasspathReaderResource(String,boolean)} method pulls in the following file located in the same package as the class:
The
The
Pointing a browser to the resource shows the following:
Entering some values and clicking
Another option is to construct the HTML form in Java using HTML5 beans. This is arguably a better approach since it's typically cleaner with less code, and the headers/links are already part of the page.
The
It provides examples of the following:
The class is shown below:
Again, there's a lot going on here that's new that requires some explanation.
The
The {@link org.apache.juneau.rest.annotation.RestResource#properties() @RestResource.properties()}, {@link org.apache.juneau.rest.annotation.RestResource#beanFilters() @RestResopurce.beanFilters()}, and {@link org.apache.juneau.rest.annotation.RestResource#pojoSwaps() @RestResopurce.pojoSwaps()} annotations are used to set behavior properties on the resource's underlying bean context, serializers, and parsers. You're using them here to modify the behavior of serialization for all content types. The annotations are functionally equivalent to using the {@link org.apache.juneau.rest.RestContextBuilder} class, as follows:
Note how the annotations generally require fewer lines of code.
Pointing a browser to the resource shows the following:
This gives you an idea of what kinds of POJO models can be serialized, since you are serializing a regular
old
The
Pointing a browser to the resource shows the following:
The code is straightforward, consisting of the following classes:
Persons
.
The
Our address book uses the following interface:
The
@Xml (elementName="addressBook" )
annotation tells the toolkit that
when serialized as XML, the element name is
The
@Rdf (beanUri=true )
annotation identifies the @BeanProperty (swap=CalendarSwap.Medium.class )
annotation causes
the date field to be serialized in the format
The
@Xml (ns="mail" )
annotation.
The
The
The
The OPTIONS page uses the servlet resource bundle to specify the labels so that they're globalizable.
Pointing a browser to the resource shows the results of running the
Clicking the
Notice how the
Also notice how the dates are formatted as readable strings.
This was from the transform you added to the
Let's see what the output looks like in other formats:
Notice how our
Also notice how the
annotations caused the
Notice how the
annotations are used to identify
values for
Also notice how
Now lets look at the schema outputs that can be rendered that show information about the POJO classes themselves.
Now let's see what else you can do.
Clicking on the first
Clicking on the OPTIONS link on the page shows you the Swagger doc generated from our annotations and resource bundle properties:
Because you added the
The
The
The
You'll notice that the class is a stand-alone executable that can be invoked as a plain Java process.
The output from running this code is the following:
Running client test... Number of entries = 2 Deleted person Barack Obama, response = DELETE successful Deleted person George Walker Bush, response = DELETE successful Number of entries = 0 Created person Barack Obama, uri = http://localhost:9081/sample/addressBook/people/3 Created person George Walker Bush, uri = http://localhost:9081/sample/addressBook/people/4 Created address http://localhost:9081/sample/addressBook/addresses/7 Created address http://localhost:9081/sample/addressBook/addresses/8 Changed name, response = PUT successful New name = Barack Hussein Obama
The Juneau architecture is designed to make it easy to debug REST resources using nothing more than a browser. The same actions done programmatically in the last section can also be done using URLs. By default, you can override the HTTP Method and Content through GET parameters, as shown below:
The ability to overload methods is enabled through the
setting.
RestResource.allowMethodParam()
The
The
The
Pointing a browser to the resource shows the following:
Clicking the hyperlinks on each shows you the list of methods that can be invoked on that service.
Note that the
Proxy interfaces are then retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)} method.
The client side code for invoking this method is shown below:
The
Pointing a browser to the resource shows the following:
Pointing a browser to the
Note how a system property variable can be defined in the properties file.
Note how the HTML file contains localized variables for the servlet label and description.
The
Pointing a browser to the resource shows the following:
True ATOM feeds require using an
Other languages, such as JSON are also supported:
The
Pointing a browser to the resource shows the following:
Clicking the
The Docker registry URL is specified in the
The
Pointing a browser at a Tumblr blog name, such as
The
The resource consists of a simple registry of images with integer IDs.
It is initialized with a single entry, which can be accessed through a GET request.
The
The resource consists of a pre-initialized {@link org.apache.juneau.dto.jsonschema.Schema} object. Pointing a browser to the resource shows the following:
For true JSON-Schema, you need to specify the header
The
The example uses embedded Derby to create a database whose name is defined in the external configuration files.
Pointing a browser to the resource shows the following:
Running a query results in the following output:
The {@link org.apache.juneau.microservice.resources.ConfigResource} class is a reusable resource defined in the org.apache.juneau.microservice API. It provides a REST interface for reading and altering the microservice config file.
Pointing a browser to the resource shows the following:
An edit page is provided for altering the raw config file:
The {@link org.apache.juneau.ini.ConfigFile} class is a serializable POJO, which makes the resource relatively straightforward to implement.
The {@link org.apache.juneau.microservice.resources.LogsResource} class is a reusable resource defined in the org.apache.juneau.microservice API. It provides a REST interface for the log files generated by the microservice.
Pointing a browser to the resource shows the following:
The
The
Security is always an ongoing concern in any library. If you discover any security vulnerabilities in this code, please refer to the instructions found here:
One common security vulnerability is the ability to create arbitrary Java object instances through crafted
user input. For example, support for constructing POJOs based on an input attribute defining a
fully-qualified class name like
Fortunately, Juneau does not support an open-ended JsonParser.
).
As long as the Class
object passed into this method is not constructed from user-generated input,
it should be free from demarshalling vulnerabilities.
The following example shows a potential vector that circumvents the restriction above:
Juneau does support something similar to a
i.e. instead of
Since bean types are defined at compile time, it's impossible to instantiate arbitrary POJOs.
POJO types of generalized input are also inferred through swaps. Again, since the POJO types are hardcoded at compile time, these should not be subject to demarshalling vulnerabilities. However, it is possible to circumvent this through your swap implementation as shown below:
Note that the {@link org.apache.juneau.jso.JsoParser}, a thin layer of the Juneau Parser API written on
top of plain-old Java Object Serialization which itself is vulnerable to demarshalling issues.
Due to this, the JSO parser is not included in any of the default REST servlet implementations.
Be especially careful when using this parser, particularly if you want to use it for handing
application/x-java-serialized-object
input through REST servlets.
All other parsers (JSON, URL-Encoding, MessagePack, etc...) work the same way in determining POJO types, so should be safe from demarshalling vulnerabilities.
When accessing security vulnerabilities of any library, dependent libraries must also be taken into account:
7.0.1
, no known security vulnerabilities exist that affect Juneau at this time.
Care must be used when defining new {@link org.apache.juneau.svl.Var Vars} using the SVL API since mistakes could potentially expose system properties, environment variables, or even file system files.
For recap, the SVL support allows you to embed variables of the form
An example of a potential security hole is shown below that could potentially expose any file on a file system through a REST request:
This code is simply echoing the value of the foo
query parameter.
Now say for example that a bad actor passes in the query string $F
variable allows you to resolve the contents of files using SVL, and is provided
by default using the built-in variable resolver returned by the RestRequest
object.
You've potentially just exposed the contents of that file through your REST interface.
In reality, the above security hole does not exist because of the following restrictions:
Vars
have two methods {@link org.apache.juneau.svl.Var#allowNested()} and
{@link org.apache.juneau.svl.Var#allowRecurse()} that can be overridden to prevent recursive processing
of string variables. These are both $R
variable, so the $F
variable in the result will never get processed and instead be treated as plain text.
$F
variable only allows you to retrieve files within the JVM starting directory.
Even though the built-in Juneau variables are safe, special care is needed when defining your own custom variables. If your variable resolves user input in any way, it's HIGHLY recommended that you override the {@link org.apache.juneau.svl.Var#allowNested()} and {@link org.apache.juneau.svl.Var#allowRecurse()} methods to prevent recursive handling of variables.
Denial of service attacks can be alleviated through the {@link org.apache.juneau.rest.annotation.RestResource#maxInput() maxInput()} setting. Arbitrarily-large input will trigger an exception before causing out-of-memory errors. The default value for this setting is 100MB.
Since the parsers do not use intermediate DOMs and instead parse directly into Java objects, deeply nested data structures will almost always trigger stack overflow errors long before memory consumption becomes an issue. However, this is NOT true of the RDF parsers that use an intermediate DOM. If parsing RDF, you may want to consider lowering the max-input value above.
Context
classes (e.g. JsonSerializerContext
) have been folded into
their respective serializer or parser classes (e.g. JsonSerializer
).
JsonSerializer
is now:
Context
objects are thread-safe and read-only.
JsonSerializerSession
is now:
JsonSerializerBuilder
is now:
Context
objects.
PropertyStore
class was overly-complicated with many read/write
locks to ensure thread-safety.
PropertyStore
objects
that can be used as hash keys.
PartSerializer
/PartParser
classes
have been replaced with the following all located in the new org.apache.juneau.httppart
package:
ContextBuilder.property(String,Object)
renamed to {@link org.apache.juneau.ContextBuilder#set(String,Object)}.
ResourceFinder
class has been replaced with the following:
HttpServletRequest.getAttribute(String)
.
RestConfig
class into {@link org.apache.juneau.rest.RestContextBuilder}.
RestMatcherReflecting
class.
@RestResource.allowMethodParam
renamed to {@link org.apache.juneau.rest.annotation.RestResource#allowedMethodParams}.
@RestMethod.serializersInherit
and @RestMethod.parsersInherit
replaced with
simplified {@link org.apache.juneau.rest.annotation.RestMethod#inherit() @RestMethod.inherit()}.
Map<String,Object>
instead of Map<String,String>
.
Map<String,Object>
instead of Map<String,String>
.
Map<String,Object>
instead of Map<String,String>
.
getResource(String,Locale)
renamed to {@link org.apache.juneau.rest.RestContext#getClasspathResource(String,Locale) getClasspathResource(String,Locale)}
getResourceAsString(String,Locale)
renamed to {@link org.apache.juneau.rest.RestContext#getClasspathResourceAsString(String,Locale) getClasspathResourceAsString(String,Locale)}
getResource(Class,MediaType,String,Locale)
renamed to {@link org.apache.juneau.rest.RestContext#getClasspathResource(Class,MediaType,String,Locale) getClasspathResourceAsString(Class,MediaType,String,Locale)}
Map<String,Object>
instead of Map<String,String>
.
Map<String,Object>
instead of Map<String,String>
.
getSupportedMediaTypes()
replaced with
{@link org.apache.juneau.rest.RestRequest#getConsumes() getConsumes()} and
{@link org.apache.juneau.rest.RestRequest#getProduces() getProduces()}.
getReaderResource(String,boolean,MediaType)
renamed to
{@link org.apache.juneau.rest.RestRequest#getClasspathReaderResource(String,boolean,MediaType) getClasspathReaderResource(String,boolean,MediaType)}
getReaderResource(String,boolean)
renamed to
{@link org.apache.juneau.rest.RestRequest#getClasspathReaderResource(String,boolean) getClasspathReaderResource(String,boolean)}
getReaderResource(String)
renamed to
{@link org.apache.juneau.rest.RestRequest#getClasspathReaderResource(String) getClasspathReaderResource(String)}
RestCallHandler
split up into {@link org.apache.juneau.rest.RestCallHandler} and
{@link org.apache.juneau.rest.RestCallHandlerDefault}
RestInfoProvider
split up into {@link org.apache.juneau.rest.RestInfoProvider} and
{@link org.apache.juneau.rest.RestInfoProviderDefault}
RestLogger
split up into {@link org.apache.juneau.rest.RestLogger},
{@link org.apache.juneau.rest.RestLoggerDefault} and {@link org.apache.juneau.rest.RestLoggerNoOp}
RestResourceResolverSimple
renamed to {@link org.apache.juneau.rest.RestResourceResolverDefault}
@Messages
and @Properties
REST java method parameter
annotations.
MessageBundle
and
RestRequestProperties
as unannotated parameters.
PartSerializer
with {@link org.apache.juneau.httppart.HttpPartSerializer}.
This release is a minor update. It includes the following prereq updates:
create()
methods for builders on serializers and parsers.
Running class 'RestMicroservice' using config file 'examples.cfg'. Server started on port 10000 List of available commands: exit -- Shut down service restart -- Restarts service help -- Commands help echo -- Echo command > help help NAME help -- Commands help SYNOPSIS help [command] DESCRIPTION When called without arguments, prints the descriptions of all available commands. Can also be called with one or more arguments to get detailed information on a command. EXAMPLES List all commands: > help List help on the help command: > help help >
Commands are pluggable and extensible through the config file.
This release ups the Java prerequisite to Java 7.
org.apache.juneau.dto.Link
renamed to {@link org.apache.juneau.dto.LinkString}.
Helps avoid confusion since there are other Link classes in the library.
@HtmlDoc (links)
renamed to {@link org.apache.juneau.rest.annotation.HtmlDoc#navlinks() navlinks}.
@HtmlDoc (favIcon)
.
@HtmlDoc (head)
, you can define them using:
head={
RestResponse/RestConfig/RestContext
classes and moved it into the new {@link org.apache.juneau.rest.HtmlDocBuilder} class.
The major change in this release is the project structure.
The library now consists of the following artifacts found in the Maven group "org.apache.juneau"
:
| Category | Maven Artifacts | Description | Prereqs |
|---|---|---|---|
| Juneau Core | juneau-marshall | Serializers and parsers for:
|
|
| juneau-marshall-rdf |
Serializers and parsers for:
|
|
|
| juneau-dto |
Data Transfer Objects for:
|
|
|
| juneau-svl | Simple Variable Language API |
|
|
| juneau-config | Configuration file API |
|
|
| Juneau REST | juneau-rest-server | REST Servlet API |
|
| juneau-rest-server-jaxrs | Optional JAX-RS support |
|
|
| juneau-rest-client | REST Client API |
|
|
| Juneau Microservice | juneau-microservice-server | REST Microservice Server API |
|
| juneau-microservice-template | Developer template project |
|
|
| Examples | juneau-examples-core |
Core code examples | |
juneau-examples-rest |
REST code examples | ||
| Juneau All | juneau-all |
Combination of the following:
|
|
@Pojo
and @BeanProperty.swap()
annotations.
PojoSwaps
, this can be used to provide customized
output for specific content types.
SerializeException
/ParseException
.
getClass()
to retrieve the annotation value could not be called before calling
the super ()
method.
toString()
method.
Swagger.toString()
produces JSON and the HTML5 Form.toString()
produces HTML.
init(RestConfig)
- Use {@link org.apache.juneau.rest.annotation.HookEvent#INIT} instead.
onSuccess(RestRequest, RestResponse, long)
- Use {@link org.apache.juneau.rest.annotation.HookEvent#END_CALL} instead.
onPreCall(RestRequest)
- Use {@link org.apache.juneau.rest.annotation.HookEvent#PRE_CALL} instead.
onPostCall(RestRequest, RestResponse)
- Use {@link org.apache.juneau.rest.annotation.HookEvent#POST_CALL} instead.
RestContext.REST_allowHeaderParams
setting.
RestResource.allowMethodParam()
-
RestContext.REST_allowMethodParam
setting.
RestContext.REST_allowBodyParam
setting.
RestContext.REST_xxx
setting.
RestContext.REST_useStackTraceHashes
setting.
RestContext.REST_defaultCharset
setting.
RestResource.paramFormat()
-
RestContext.REST_paramFormat
setting.
RestContext.REST_defaultCharset
setting.
RestMethod.paramFormat()
-
RestContext.REST_paramFormat
setting.
?stylesheet
query parameter.
RestServletJenaDefault
class to remove the Jena dependency class on
the juneau-rest-server
artifact.
RestServletDefault
and add the RDF serializers and
parsers.
jetty.xml
file
for maximum flexibility instead of the hodge-podge of support in the config file.
jetty.xml
file.
Juneau 6.3.1 is a minor release.
HtmlDocSerializerContext
:
HTMLDOC_script
HTMLDOC_style
- Was HTMLDOC_stylesheet
- Was ResourceFinder
utility class.
Allows you to search for resources up the parent hierarchy chain.
Also allows you to search for localized resources.
HtmlDocSerializerContext
:
PoweredByApacheWidget
-> PoweredByApache
PoweredByJuneauWidget
-> PoweredByJuneau
css()
.
cssUrl()
.
@RestResource.stylesheet()
annotation.
It's no longer needed now that you can easily specify styles via title()
description()
branding()
htmldoc=
DockerRegistryResource
examples shows how it can be used to pull in a localized
file from the classpath to populate the aside section of a page.
htmldoc=
bpIncludes()
and bpExcludes()
annotations on $R
variable: Juneau 6.3.0 is a major update with significant new functionality for defining proxy interfaces against arbitrary 3rd-party REST interfaces.
Session.getProperty(String)
Session.getProperty(String,String)
Session.getProperty(Class,String)
Session.getProperty(Class,String,Object)
org.apache.juneau.serializer.PartSerializer
interface particularly tailored to HTTP
headers, query parameters, form-data parameters, and path variables.
pages=
links=
SerializerContext.SERIALIZER_uriContext
SerializerContext.SERIALIZER_uriRelativity
SerializerContext.SERIALIZER_uriResolution
SerializerContext.SERIALIZER_maxIndent
UonSerializer.UON_paramFormat
,
and the UON/URL-Encoding serializers will now always serialize all values as plain text.
RestConfig.serializerListener(Class)
RestConfig.parserListener(Class)
RestClientBuilder.listeners(Class,Class)
ParserSession.getInputAsString()
method so that it can be used
in the listeners.
HtmlDocSerializerContext.HTMLDOC_title
HtmlDocSerializerContext.HTMLDOC_description
HtmlDocSerializerContext.HTMLDOC_branding
HtmlDocSerializerContext.HTMLDOC_header
HtmlDocSerializerContext.HTMLDOC_nav
HtmlDocSerializerContext.HTMLDOC_aside
HtmlDocSerializerContext.HTMLDOC_footer
HtmlDocSerializerContext.HTMLDOC_noResultsMessage
HtmlDocSerializerContext.HTMLDOC_cssUrl
HtmlDocSerializerContext.HTMLDOC_css
HtmlDocSerializerContext.HTMLDOC_template
RestRequest
.
RestResponse
.
@RestMethod (name="*" )
)
bpIncludes()
bpExcludes()
widgets()
widgets()
RestConfig
:
setHtmlTitle(String)
setHtmlDescription(String)
setHtmlBranding(String)
setHtmlHeader(String)
setHtmlLinks(String)
setHtmlNav(String)
setHtmlAside(String)
setHtmlFooter(String)
setHtmlCss(String)
setHtmlCssUrl(String)
setHtmlNoWrap(boolean)
setHtmlNoResultsMessage(String)
setHtmlTemplate(Class)
setHtmlTemplate(HtmlDocTemplate)
addWidget(Class)
setHtmlTitle(Object)
setHtmlDescription(Object)
setHtmlBranding(Object)
setHtmlHeader(Object)
setHtmlLinks(Object)
setHtmlNav(Object)
setHtmlAside(Object)
setHtmlFooter(Object)
setHtmlCss(Object)
setHtmlCssUrl(Object)
setHtmlNoWrap(boolean)
setHtmlNoResultsMessage(Object)
setHtmlTemplate(Class)
setHtmlTemplate(HtmlDocTemplate)
&plainText=true
parameter now works on byte-based serializers by converting the output to hex.
PoweredByJuneauWidget
ContentTypeLinksColumnWidget
ContentTypeLinksRowWidget
QueryWidget
devops.css
cleaned up.
NameValuePairs
and beans as input
when using Juneau 6.2.0 is a major update.
Lockable
interface.
addBeanTypeProperties
setting added to serializers to override the
SerializerContext.SERIALIZER_addBeanTypeProperties
setting
for individual serializers in a serializer group:
HtmlSerializerContext.HTML_addBeanTypeProperties
JsonSerializerContext.JSON_addBeanTypeProperties
MsgPackSerializerContext.MSGPACK_addBeanTypeProperties
UonSerializerContext.UON_addBeanTypeProperties
XmlSerializerContext.#XML_addBeanTypeProperties
RdfSerializerContext.RDF_addBeanTypeProperties
org.apache.juneau.uon
package.
style()
override methods to all elements.
$SWITCH
variable for switch block logic.
SerializerContext.SERIALIZER_abridged
.
UrlEncodingSerializerContext.URLENC_paramFormat
.
UrlEncodingSerializerBuilder.paramFormat(String)
UrlEncodingSerializerBuilder.plainTextParams()
RestServlet
should have an equivalent for non-RestServlet
classes.
RestServlet
.
Child resources do not.
RestConfig
- A modifiable configuration of a resource. Subclasses from {@link javax.servlet.ServletConfig}.
RestServlet.init(RestConfig)
- A modifiable configuration of a resource.
RestServlet
classes must have one of the following to allow it to be instantiated:
public T(RestConfig)
constructor.
public T()
constructor.
RestServlet
classes can optionally include the following init methods to gain access to the config and context:
public init(RestConfig)
public init(RestContext)
RestServlet
resources to do the same as subclassing directly from RestServlet
:
@RestResource.pageTitle()
@RestMethod.pageTitle()
@RestResource.pageText()
@RestMethod.pageText()
@RestResource.pageLinks()
@RestMethod.pageLinks()
Typically you're going to simply want to use the title
and description
annotations
which apply to both the page title/text and the swagger doc:
RestResource.stylesheet()
can now take in a comma-delimited list of stylesheet paths.
byte []
arrays, InputStreams
, Files
, etc...)
and is now immutable. It also includes a new {@link org.apache.juneau.rest.StreamResource.Builder} class.
@RestMethod (name="PROXY" )
annotation on REST methods.
Used to expose interface proxies without the need for {@link org.apache.juneau.rest.remoteable.RemoteableServlet}.
RestClient
class doX(Object url)
methods now handle HttpClient URIBuilder
instances.
@RestMethod (name="PROXY" )
.
query(String,Object,boolean,PartSerializer)
formData(String,Object,boolean,PartSerializer)
header(String,Object,boolean,PartSerializer)
RestClientBuilder.plainTextParams()
No-Trace: true
header on all requests to prevent
the servlet from logging errors.
Debug: true
header on all requests.
HttpResponse
returned by the inner HttpClient
.
append(String,Object,PartSerializer)
0
s to try a random port.
Juneau 6.1.0 is a major update.
In particular, this release cleans up the {@link org.apache.juneau.BeanContext} API to match the {@link org.apache.juneau.PropertyStore}/{@link org.apache.juneau.Context}/{@link org.apache.juneau.Session} paradigm previously used in the serializer and parser APIs. It also makes several improvements to the HTML and XML serialization support and introduces HTML5 DTO beans.
XmlContentHandler
class.
addJsonTypeAttrs
and addJsonStringTypeAttrs
settings.
XMLEventReader
-based to XMLStreamReader
.
SerializerContext
and ParserContext
now extend directly from {@link org.apache.juneau.BeanContext}.
parseMap()
, parseCollection()
)
by replacing them with two simple methods:
ClassMeta
object.
ClassMeta
objects.
parseMap()
and parseCollection()
methods!
BeanContext.normalizeClassMeta()
method.
toObjectMap()
and fromObjectMap()/T(ObjectMap)
methods with
generalized swap(BeanSession)
/unswap(BeanSession,X)
/T(BeanSession,X)
methods.getMapClassMeta()
/getCollectionClassMeta()
methods.
UonParser.DEFAULT_WS_AWARE
and UrlEncodingParser.DEFAULT_WS_AWARE
parsers.
UonParserContext.UON_whitespaceAware
configuration setting.
UonSerializer.DEFAULT_SIMPLE
, UonSerializer.DEFAULT_SIMPLE_ENCODING
and UrlEncodingSerializer.DEFAULT_SIMPLE
serializers since there is no separate simple mode anymore.
UonParserContext.UON_simpleMode
configuration setting.
@Bean (subTypeProperty)
and @Bean (subTypes)
annotations
and replaced them with the ability to define subtypes using the existing {@link org.apache.juneau.annotation.Bean#beanDictionary() @Bean.beanDictionary()}
annotation on parent classes and interfaces.
SerializerContext.SERIALIZER_addBeanTypeProperties
setting is now enabled by default.
SERIALIZER_addIndentation
/JSON_addWhitespace
/UON_addWhitespace
properties into a single SerializerContext.SERIALIZER_useWhitespace
setting.
RestRequest.getTimeZone()
method.
ClassMeta
objects and eliminate the need for casts:
RestRequest.getHeader(String,Class)
RestRequest.getHeader(String,Object,Class)
RestRequest.getHeader(String,Type,Type...)
RestRequest.getQueryParameter(String,Class)
RestRequest.getQueryParameter(String,Object,Class)
RestRequest.getQueryParameter(String,Type,Type...)
RestRequest.getQueryParameter(String,Object,Type,Type...)
RestRequest.getQueryParameters(String,Class)
RestRequest.getQueryParameters(String,Type,Type...)
RestRequest.getFormDataParameter(String,Class)
RestRequest.getFormDataParameter(String,Object,Class)
RestRequest.getFormDataParameters(String,Class)
RestRequest.getFormDataParameter(String,Type,Type...)
RestRequest.getFormDataParameters(String,Type,Type...)
RestRequest.getPathParameter(String,Class)
RestRequest.getPathParameter(String,Type,Type...)
RestRequest.getBody(Class)
RestRequest.getBody(Type,Type...)
&plainText=true
specified.
Juneau 6.0.1 is a minor update.
ParserContext
.
ParserContext.PARSER_strict
ParserContext.PARSER_inputStreamCharset
ParserContext.PARSER_fileCharset
JsonParserContext.JSON_strictMode
. Replaced by PARSER_strict
.
byte[]
arrays can now be passed to {@link org.apache.juneau.parser.Parser#parse(Object,Class)} for reader-based parsers.
Juneau 6.0.0 is a major update.
The major change is rebranding from "Juno" to "Juneau" in preparation for donation to the Apache Foundation.
SerializerContext.SERIALIZER_addBeanTypeProperties
- Controls whether type properties are serialized.
@Xml.name()
annotation, and the
BeanFilter
class to use final fields.
java.util.Date
).
org.apache.juneau.internal
package.
These internal utility classes are not meant for consumption outside the Juneau codebase.
org.apache.juneau.parser.Parser.createSession(ObjectMap,Method,Object)
Parser.getMediaRanges()
org.apache.juneau.serializer.Serializer.createSession(ObjectMap,Method)
Serializer.getMediaRanges()
ClassFilter
class since it's no longer needed.
BeanContext.convertToType(Object,Class)
.
HtmlSerializerContext.HTML_detectLinksInStrings
- Automatically detect hyperlinks in strings.
HtmlSerializerContext.HTML_lookForLabelParameters
- Specify anchor text by appending &label=MyLabel
to URL.
HtmlSerializerContext.HTML_labelParameter
- Specify what URL parameter to use as the anchor text label.
HtmlSerializerContext.URI_ANCHOR
option for HtmlSerializerContext.HTML_uriAnchorText
.
@Transform
annotation to @Pojo
so that it can be used for various POJO-related behavior, not just associating transforms.
ResourceOptions
and related code.
@RestResource.termsOfService()
/ {@link org.apache.juneau.rest.RestInfoProvider#getTermsOfService(RestRequest)}
@RestResource.contact()
/ {@link org.apache.juneau.rest.RestInfoProvider#getContact(RestRequest)}
@RestResource.license()
/ {@link org.apache.juneau.rest.RestInfoProvider#getLicense(RestRequest)}
@RestResource.version()
/ {@link org.apache.juneau.rest.RestInfoProvider#getVersion(RestRequest)}
@RestResource.tags()
/ {@link org.apache.juneau.rest.RestInfoProvider#getTags(RestRequest)}
@RestResource.externalDocs()
/ {@link org.apache.juneau.rest.RestInfoProvider#getExternalDocs(RestRequest)}
RestInfoProvider.getMethodSummary(String,RestRequest)
RestInfoProvider.getMethodDescription(String,RestRequest)
@RestMethod.externalDocs()
@RestMethod.tags()
@RestMethod.deprecated()
@RestMethod.parameters()
@RestMethod.responses()
RestServletContext.paramFormat
context property.
RestServlet.createProperties()
RestServlet.createBeanContext(ObjectMap,Class[],Class[])
RestServlet.createBeanFilters()
RestServlet.createPojoSwaps()
RestServlet.createParsers(ObjectMap,Class[],Class[])
RestServlet.createUrlEncodingSerializer(ObjectMap,Class[],Class[])
RestServlet.createUrlEncodingParser(ObjectMap,Class[],Class[])
RestServlet.createConverters(ObjectMap)
RestServlet.createDefaultRequestHeaders(ObjectMap)
RestServlet.createDefaultResponseHeaders(ObjectMap)
RestServlet.createEncoders(ObjectMap)
RestServlet.createGuards(ObjectMap)
RestServlet.createMimetypesFileTypeMap(ObjectMap)
RestServlet.createResponseHandlers(ObjectMap)
JazzRestClient
class.
RestClient.setClientVersion(String)
.
Juno <IP_ADDRESS> is a moderate update.
ObjectList.getAt(Class,String)
ObjectMap.getAt(Class,String)
@ThreadSafe
annotation.
ClassFilter
class.
ConfigFile.getResolving(StringVarResolver,boolean)
ConfigFile.getStringVar()
ParserContext.PARSER_trimStrings
property.
SerializerContext.SERIALIZER_trimStrings
property.
Args.getStringVar()}
StringMapVar
StringVars
StringVar
XmlParserContext.XML_trimWhitespace
changed to Juno <IP_ADDRESS> is a major update. Major changes have been made to the microservice architecture and config INI file APIs.
ConfigFile.getResolving(StringVarResolver)
ConfigMgr
:
ConfigMgr.create()
, ConfigMgr.create(Reader)
, ConfigMgr.create(File)
ConfigMgr.deleteAll()
fromString(String)
valueOf(String)
(e.g. enums)
parse(String)
(e.g. logging Level
class)
parseString(String)
forName(String)
(e.g. Class
and Charset
classes)
Pair<S,T>
and you try to parse into this
class (e.g. parser.parse(in, Pair.class )
), the unbound type variables
is interpreted as Object
instead of throwing an exception.
AtomicInteger
AtomicLong
BigInteger
BigDecimal
StringObject
class that can be used for delayed object serialization.
StringVarMultipart
StringVarWithDefault
PojoRest.get(Class,String,Object)
StringVar.doResolve(String)
StringVarResolver.DEFAULT
javax.mail.internet.MimeUtility
by implementing our own {@link org.apache.juneau.internal.StringUtils#base64Encode(byte[])} method.
/servletPath/style.css
instead of /servletPath/htdocs/juneau.css
.
This coincides with enhancements made in the server code for specifying styles.
<div class='outerdata'><div class='data' id='data'>...</div></div>
).
Needed for supporting the new devops look-and-feel.
RdfProperties.RDF_looseCollection
loose collections.
NoClassDefFoundErrors
.
UrlEncodingSerializer.DEFAULT_SIMPLE_EXPANDED
serializer.
getMainArg(int)
changed to {@link org.apache.juneau.utils.Args#getArg(int)}.
Non-existent arguments are returned as org.apache.juneau.utils.CharsetUtils
class.
org.apache.juneau.utils.ConcurrentIdentityList
class.
ReaderParser
.
Simplifies the API on the class.
ReaderParser
.
Simplifies the API on the class.
SafeResourceMultiBundle
moved from server component.
StringVarResolver
NoClassDefFoundErrors
so that resources that include Jena support can continue to operate even if the Jena libraries are not present.
org.apache.juneau.rest.client.LaxRedirectStrategy
. Use HTTP Client equivalent.
RestCall#addInterceptor(RestCallInterceptor)
RestCall#addResponsePattern(ResponsePattern)
execute()
.
RestClient.setBasicAuth(String,int,String,String)
RestClient.logTo(Level,Logger)
RestClient.setRootUrl(String)
RestClient.enableSSL(SSLOpts)
RestClient.enableLaxSSL()
RestClient.createHttpClientBuilder()
HttpClientBuilder
:
RestClient.setRedirectStrategy(RedirectStrategy)
RestClient.setDefaultCookieSpecRegistry(Lookup)
RestClient.setRequestExecutor(HttpRequestExecutor)
RestClient.setSSLHostnameVerifier(HostnameVerifier)
RestClient.setPublicSuffixMatcher(PublicSuffixMatcher)
RestClient.setSSLContext(SSLContext)
RestClient.setSSLSocketFactory(LayeredConnectionSocketFactory)
RestClient.setMaxConnTotal(int)
RestClient.setMaxConnPerRoute(int)
RestClient.setDefaultSocketConfig(SocketConfig)
RestClient.setDefaultConnectionConfig(ConnectionConfig)
RestClient.setConnectionTimeToLive(long,TimeUnit)
RestClient.setConnectionManager(HttpClientConnectionManager)
RestClient.setConnectionManagerShared(boolean)
RestClient.setConnectionReuseStrategy(ConnectionReuseStrategy)
RestClient.setKeepAliveStrategy(ConnectionKeepAliveStrategy)
RestClient.setTargetAuthenticationStrategy(AuthenticationStrategy)
RestClient.setProxyAuthenticationStrategy(AuthenticationStrategy)
RestClient.setUserTokenHandler(UserTokenHandler)
RestClient.disableConnectionState()
RestClient.setSchemePortResolver(SchemePortResolver)
RestClient.setUserAgent(String userAgent)
RestClient.setDefaultHeaders(Collection)
RestClient.addInterceptorFirst(HttpResponseInterceptor)
RestClient.addInterceptorLast(HttpResponseInterceptor)
RestClient.addInterceptorFirst(HttpRequestInterceptor)
RestClient.addInterceptorLast(HttpRequestInterceptor)
RestClient.disableCookieManagement()
RestClient.disableContentCompression()
RestClient.disableAuthCaching()
RestClient.setHttpProcessor(HttpProcessor)
RestClient.setRetryHandler(HttpRequestRetryHandler)
RestClient.disableAutomaticRetries()
RestClient.setProxy(HttpHost)
RestClient.setRoutePlanner(HttpRoutePlanner)
RestClient.disableRedirectHandling()
RestClient.setConnectionBackoffStrategy(ConnectionBackoffStrategy)
RestClient.setBackoffManager(BackoffManager)
RestClient.setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)
RestClient.setDefaultCookieStore(CookieStore)
RestClient.setDefaultCredentialsProvider(CredentialsProvider)
RestClient.setDefaultAuthSchemeRegistry(Lookup)
RestClient.setContentDecoderRegistry(Map)
RestClient.setDefaultRequestConfig(RequestConfig)
RestClient.useSystemProperties()
RestClient.evictExpiredConnections()
RestClient.evictIdleConnections(long,TimeUnit)
JazzRestClient
now supports OIDC authentication.
org.apache.juneau.rest.client.jazz.CertificateStore
org.apache.juneau.rest.client.jazz.ICertificateValidator
org.apache.juneau.rest.client.jazz.ITrustStoreProvider
org.apache.juneau.rest.client.jazz.LenientCertificateValidator
org.apache.juneau.rest.client.jazz.SharedTrustStoreProvider
org.apache.juneau.rest.client.jazz.ValidatingX509TrustManager
StringVar
Readers
containing text with StringVarResolver
OutputStreams
.
RestRequest.getReaderResource(String)
- Replaces getVarResource(String)
.
RestRequest.getReaderResource(String,boolean)
RestRequest.getReaderResource(String,boolean,String)
Content-Encoding: identity
when no encoding is used. Some clients don't interpret it correctly.
RestServlet.getChildClasses()
- Programmatic equivalent to {@link org.apache.juneau.rest.annotation.RestResource#children() @RestResource.children()} annotation.
RestServlet.shouldLog(HttpServletRequest,HttpServletResponse,RestException)
RestServlet.shouldLogStackTrace(HttpServletRequest,HttpServletResponse,RestException)
RestServlet.logObjects(Level,String,Object[])
RestServlet.resolveStaticFile(String)
RestServlet.createStyleSheet()
RestServlet.createFavIcon()
RestServlet.createStaticFilesMap()
RestServlet.getConfigMgr()
RestServletJenaDefault
.
These may represent a security risk if not handled correctly, so removed
them as a precaution.
RestServletProperties.REST_htDocsFolder
. Replaced with {@link org.apache.juneau.rest.annotation.RestResource#staticFiles() @RestResource.staticFiles()}.
RestResource.stylesheet()
RestResource.favicon()
org.apache.juneau.rest.jaxrs.JsonProvider
class.
Some JAX-RS implementations use code scanning to find providers, so if you were using DefaultJenaProvider
, it would
pick up JsonProvider
as well. It's easy enough to create your own implementation if needed.
consumes
and produces
fields instead of accept
and contentType
which was confusing.
properties
from OPTIONS pages.
ResourceLink.ResourceLink(String,RestRequest,String,Object[])
constructor.
org.apache.juneau.microservice.Main
class. This is replaced by
the microservice classes defined above.
org.apache.juneau.microservice.RootResource
org.apache.juneau.microservice.SampleResource
StringVarResolver
Juno <IP_ADDRESS> is a moderate update. The biggest improvement is the ability to associate external INI config files with REST servlets using the {@link org.apache.juneau.ini.ConfigFile} functionality.
ConfigMgr
class for managing configuration files.
ObjectMap.remove(Class,String,Object)
method.
EncoderGroup#append(EncoderGroup)
method.
HtmlDocSerializerContext.HTMLDOC_addLinks
configuration property.
Parser.createContext(ObjectMap,Method,Object)
method.
Outer context objects can be passed in to create instances of non-static inner classes.
RestServlet.getConfig()
RestServlet.createConfigFile()
RestServlet.getResource(String)
RestServlet.getResourceAsString(String)
RestServlet.getResource(Class,String,String)
RestServlet.handleNotFound(int,RestRequest,RestResponse)
method for customized handling
of when a resource or method was not found.
RestServlet.handleNotFound(int,RestRequest,RestResponse)
method.
RestRequest.getVarResource(String)
RestRequest.getConfig()
getWriter()
now returns an unnegotiated writer.
getUnbufferedWriter()
has been removed.
RestMethod.inheritEncoders()
annotations.
Allows encoders to be fine-tuned at the method level.
ResourceLink
.
Juno <IP_ADDRESS> is a minor update in terms of core functionality. But it introduces a Microservices project for building REST microservices and docker containers.
StringVarResolver
RestResponse.getUnbufferedWriter()
method.
x-response-headers
parameter from working correctly.
ResourceDescription.ResourceDescription(RestRequest,String,String)
constructor.
Juno <IP_ADDRESS> is a minor update affecting the server component only.
RestMethod.input()
RestMethod.responses()
annotations.
These replace the various description
annotations added 2 days ago with a simpler design.
RestServlet.getMethodDescription(String,RestRequest)
so that subclasses
can override the method description in the OPTIONS page.
RestServlet.createRequestVarResolver(RestRequest)
RestServlet.resolveChild(Class)
and RestServlet.replaceChild(RestServlet)
classes that allows customized resolution of servlet instances (e.g. if services are defined in OSGi).
MethodDescription
Juno <IP_ADDRESS> is a major update.
BeanMap.getFiltered(String)
BeanMap.putFiltered(String,Object)
BeanMapEntry.getFiltered(String)
BeanMapEntry.putFiltered(String,Object)
BeanMapEntry.putFiltered(String,Object)
BeanPropertyMeta.getFiltered()
BeanPropertyMeta.setFiltered(Object)
BeanPropertyMeta.getTransformedClassMeta()
StringVarResolver
StringVarResolver
RestResource.filters()
were being
interpreted as surrogate classes because they have hidden 1-arg constructors due to being inner classes.
RdfProperties.RDF_useXmlNamespaces
property.
XmlParserContext.XML_preserveRootElement
property.
"[ClassName].ResourceDescription"
is now "[ClassName].label"
.
"[ClassName].MethodDescription.[methodName]"
is now "[ClassName].[methodName]"
.
RestRequest.getQueryParameterMap()
RestRequest.getQueryParameterNames()
RestRequest.getPathInfoUndecoded()
RestRequest.getPathRemainderUndecoded()
RestRequest.getTrimmedRequestURI()
RestRequest.getTrimmedRequestURL()
RestRequest.getPathRemainder()
now automatically decodes the path remainder.
Use RestRequest.getPathRemainderUndecoded()
to get the unencoded path remainder.
RestRequest.getRequestParentURI()
when servlet is mapped to RestRequest.getServletURI()
when servlet is mapped to $R{contextPath}
- Returns value from {@link org.apache.juneau.rest.RestRequest#getContextPath()}
$R{methodDescription}
- Returns value from {@link org.apache.juneau.rest.RestRequest#getMethodDescription()}
$R{servletTitle}
- Returns value from {@link org.apache.juneau.rest.RestRequest#getServletTitle()}
$R{servletDescription}
- Returns value from {@link org.apache.juneau.rest.RestRequest#getServletDescription()}
$R{trimmedRequestURI}
- Returns value from RestRequest.getTrimmedRequestURI()
$E{var}
- Environment variables.
RestServlet.getDescription(RestRequest)
and RestServlet.getLabel(RestRequest)
RestServletJenaDefault
now provide default HTML titles
and descriptions:
RestServletJenaDefault
now provide default descriptions and back links:
and descriptions:
RestServletProperties.REST_trimTrailingUriSlashes
and RestServletProperties.REST_pathInfoBlankForNull
.
RestResource.label()
RestMethod#responses()
Attr.description()
Content.description()
HasParam.description()
HasQParam.description()
Header.description()
Param.description()
QParam.description()
/tempDir/upload
showing how to use ServletFileUpload
with multipart form posts.
Juno <IP_ADDRESS> is a moderate update.
ClassMeta.getXmlMeta()
ClassMeta.getJsonMeta()
ClassMeta.getHtmlMeta()
ClassMeta.getUrlEncodingMeta()
ClassMeta.getRdfMeta()
HtmlDocSerializerContext.HTMLDOC_cssImports
property.
SerializerContext.SERIALIZER_sortCollections
and
SerializerContext.SERIALIZER_sortMaps
properties.
RestRequest.getServletParentURI()
method.
$R{servletParentURI}
variable.
Juno <IP_ADDRESS> is a minor update.
SerializerContext
:
SerializerContext.SERIALIZER_relativeUriBase
SerializerContext.SERIALIZER_absolutePathUriBase
SERIALIZER_uriAuthority
and SERIALIZER_uriContext
properties.
RestServletProperties
:
REST_defaultCharset
REST_servletURI
REST_relativeServletURI
RestRequest.getHeader(String,Class)
RestRequest.getHeader(String,Object,Class)
RestRequest.getHeader(String,Type,Type...)
RestRequest.getQueryParameter(String,Class)
RestRequest.getQueryParameter(String,Object,Class)
RestRequest.getQueryParameter(String,Type,Type...)
RestRequest.getQueryParameter(String,Object,Type,Type...)
RestRequest.getQueryParameters(String,Class)
RestRequest.getQueryParameters(String,Type,Type...)
RestRequest.getFormDataParameter(String,Class)
RestRequest.getFormDataParameter(String,Object,Class)
RestRequest.getFormDataParameters(String,Class)
RestRequest.getFormDataParameter(String,Type,Type...)
RestRequest.getFormDataParameters(String,Type,Type...)
RestRequest.getPathParameter(String,Class)
RestRequest.getPathParameter(String,Type,Type...)
RestRequest.getBody(Class)
RestRequest.getBody(Type,Type...)
Juno <IP_ADDRESS> is a moderate update.
The major addition is support for {@link org.apache.juneau.rest.remoteable Remoteable Services}, the ability to invoke server-side POJO methods through client-side proxy interfaces.
RestClient.setRemoteableServletUri(String)
RestServletJenaDefault
.
RestServletProperties.REST_allowMethodParam
has been enhanced to allow you to
explicitly specify which HTTP methods can be used in the &method
parameter.
RestRequest.getParser()
RestRequest.getReaderParser()
Juno <IP_ADDRESS> is a minor update.
Link
are now serialized using {@link org.apache.juneau.urlencoding.UrlEncodingSerializer}, so arbitrary POJOs can now be passed as arguments.
org.apache.juneau.transforms.Datefilter.ISO8601DTZP
and org.apache.juneau.transforms.Datefilter.SimpleP
.
HtmlDocSerializerContext.HTMLDOC_nowrap
setting for {@link org.apache.juneau.html.HtmlDocSerializer} class.
Adds ClassCastException
.
New behavior creates an empty array or Collection
.
UrlEncodingSerializer.serializeUrlPart(Object)
RestServletNls
class.
RestCall.setRedirectMaxAttempts(int)
method to prevent endless redirection loops.
RestCall#setRetryable(int,long,RetryOn)
method to automatically retry on failed connection attempts.
RestCallInterceptor.onRetry(RestCall,int,HttpRequest,HttpResponse)
method for listening in on retry attempts.
Juno <IP_ADDRESS> is a minor update.
( ) , $ = ~
.
RestClientListener
class.
Juno <IP_ADDRESS> is a moderate update.
UonParserContext.UON_whitespaceAware
property for controlling whether whitespace is ignored.
UrlEncodingContext.URLENC_expandedParams
property for controlling whether arrays/Collections
should be serialized/parsed as multi-part parameters.
&key=val1&key=val2
).
JsonSerializerContext.JSON_escapeSolidus
property for controlling whether slash characters should be escaped.
BeanPropertyMeta.add(BeanMap,Object)
method for adding values to Collection and array properties.
@Param.multipart()
@Query.multipart()
&Content
must now be specified as &content
.
&Method
must now be specified as &method
.
&debug
must now be specified as &debug=true
.
&plainText
must now be specified as &plainText=true
.
¬race
must now be specified as &noTrace=true
.
RestRequest.getParameters(String,Class)
RestRequest#getQueryParameters(String,Class)
Content-Type
through this method was inconsistent with the behavior in WAS/Tomcat.
&noTrace=true
now prevents any errors from being logged in log file.
ServletContext.getContextPath()
always ends with RestServletProperties.REST_allowMethodParam
is now RestServletJenaDefault
.
RestCall.peekInputStream()
allows you to read response bodies without interrupting execution flow.
HttpResponse
object for easier debugging.
RestClient.addListener(RestClientListener)
for registering request/response listeners.
RestClient.setClassLoader(ClassLoader)
method.
JazzRestClient
.
samples.ear
and samples.war
projects
have been replaced with an OSGi bundle with activated servlets in juno.samples
.
Juno <IP_ADDRESS> is a moderate update.
BeanRuntimeExceptions
weren't being thrown on subsequent calls to {@link org.apache.juneau.BeanContext#getClassMeta(Class)}.
BeanContext.getPrimitiveDefault(Class)
to new {@link org.apache.juneau.ClassMeta#getPrimitiveDefault()} method for performance reasons.
BeanContext.addTransforms(Class[])
RuntimeExceptions
to make the serializer easier to use for debugging.
HttpServlet.getParameter(String)
UrlEncodingSerializer
class from being able to parse the content. Updated code no longer inadvertantly calls this method.
RestRequest.getQueryParameter(String)
, RestRequest.hasQueryParameter(String)
, and RestRequest.hasAnyQueryParameters(String[])
methods that only look for parameters in the URL query string to prevent loading and parsing of URL-Encoded form posts.
@QParam
@HasQParam
&plainText
parameter can now specify a false value.
RestServlet.onPreCall(RestRequest)
and RestServlet#onPostCall(RestRequest,RestResponse)
methods
since the properties are already accessible through RestRequest.getProperties()
.
RestServletJenaDefault
.
RestResponseEntity
to {@link org.apache.juneau.rest.client.RestRequestEntity}.
RestClient#setProperty(String,Object)
RestClient#setProperties(ObjectMap)
RestClient#addNotBeanClasses(Class[])
RestClient.addTransforms(Class[])
RestClient#addImplClass(Class,Class)
RestClient.shutdown()
to {@link org.apache.juneau.rest.client.RestClient#close()} to mirror change in Apache API.
CodeFormatterResource
for quickly formatting Java and XML code samples in Javadocs.
UrlEncodedFormResource
for showing how to work with URL-Encoded form posts.
Juno <IP_ADDRESS> is a major update. There weren't very many code changes, but the source has been made a part of Jazz Foundation. This required some restructuring of the project. The project on Jazz Hub will eventually be discontinued. However, the libraries on IBM Community Source will continue to be updated regularly.
org.apache.juneau
- Core serializers and parsers.
org.apache.juneau.rest
- REST server component.
org.apache.juneau.rest.client
- REST client component.
org.apache.juneau.rest.labels.Link
class moved to Link
.
org.apache.juneau.rest.RestException
in {@link org.apache.juneau.encoders.Encoder} class changed to IOException
.
JazzRestClient
to handle introduction of SSO support in v6.
&plainText
debug feature was broken.
RestRequest
.
Juno <IP_ADDRESS> is a moderate update, focused primarily on performance improvements.
estimatedSize
parameter to the {@link org.apache.juneau.parser.Parser} parse methods to
optimize buffering when the input size is known beforehand.
BeanPropertyStore
class that handles creation of {@link org.apache.juneau.BeanContext} objects.
This allows BeanContext
objects to be considered immutable, and therefore cacheable/reusable by the framework.
While this was technically possible to cache these objects beforehand, it relied on a locking mechanism to prevent bean contexts
from being modified after being created. The new mechanism is much more straightforward.
RestClient#createHttpClient()
to allow customized subclasses to construct customized HTTP clients.
DefaultRestClient
class since it's now fully redundant with RestClient
.
RestClient.shutdown()
method for cleaning up the internal HTTP client when you're done using a REST client.
Juno <IP_ADDRESS> is a moderate update.
ParserContext.PARSER_debug
and SerializerContext.SERIALIZER_debug
.
settings for logging additional information for debugging problems.
StackOverflowErrors
. When SerializerContext.getProperties()
and
ParserContext.getProperties()
.
SerializerContext
and ParserContext
since these are now available through context properties, and are typically not used.
application/xml
.
Juno <IP_ADDRESS> is a moderate update.
beanContext
parameter was replaced with a PojoSwap#getBeanContext()
Img
';'
characters in input so that it can
parse strings of the form TumblrParserResource
in the samples war file showing how to combine the REST client and server APIs into a single
resource in order to download Tumblr blogs and convert the response into any supported response content type.
Juno <IP_ADDRESS> is a moderate update.
UrlEncodingSerializer.serializeUrlPart(Object)
RestRequest.getServletURIBuilder()
for construcing servlet-based URLs more efficiently.
CoreObject.setProperties(ObjectMap)
on serializer and parser subclasses.
Content-Encoding
andCharacter-Encoding
headers were being set when calling {@link org.apache.juneau.rest.RestResponse#getOutputStream()}.
These should not be set if interacting with the output streams at a low level.
RestResponse.sendRedirect(...)
methods due to the introduction of the {@link org.apache.juneau.rest.Redirect} class.
Juno <IP_ADDRESS> is a minor update.
RestServlet.getPath()
method.
SerializerContext.getJavaMethod()
and ParserContext.getJavaMethod()
to allow access to REST methods that invoked the serializers or parsers.
For example, can be used to access additional annotations on REST methods to perform special handing
during serialization or parsing.
BeanContext.addTransforms(Class[])
.
Previously, adding multiple conflicting filters resulted in random behavior.
Now filters are overridden when multiple matching filters are applied.
HtmlDocSerializerContext
properties to be set via Serializer.setProperty(String,Object)
.
Previously, these could only be defined through override properties (e.g. through REST class and method annotations).
Juno <IP_ADDRESS> is a moderate update.
BeanContext.INCLUDE_BEAN_FIELD_PROPERTIES
and BeanContext.INCLUDE_BEAN_METHOD_PROPERTIES
properties, since ignoring fields and methods
can be accomplished by setting the appropriate properties above to {@link org.apache.juneau.Visibility#NONE NONE}.
Also, the {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotation can now be used on non-public fields/getters/setters to override
the default behavior defined by the VISIBILITY
properties identified above. This is a convenient way of identifying protected or
private fields or methods as bean properties. Previously, you could only identify public fields/getters/setters using this annotation.
Introspector
class to determine bean properties. In the previous release, the method for determining bean properties was a mixture of Juno-based and Introspector-based.
Now it's either pure Juno-based or pure Introspector-based. The result is considerably cleaner code and consistent behavior.
@BeanProperty (hidden=true )
annotation
for ignoring bean properties. Can also be used on classes that look like beans so that they're not treated as beans.
Bean.subTypeProperty()
annotation.
The previous behavior was not strictly JSON-compliant since JSON objects are supposed to consist of unordered lists of key/value pairs.
While targeted for JSON, the restriction is also lifted for all other parsers.
<div id ='data' >
element to make it easier to extract the data portion of the page in Javascript in browsers.
$A{...}
$P{...}
RestServlet.createRequestVarResolver(RestRequest)
.
Juno <IP_ADDRESS> is a minor update.
&Accept-Language
from being used as a GET parameter.
RestServletProperties.REST_allowMethodParam
to be disabled by default.
Juno <IP_ADDRESS> is a minor update.
pathInfo
on child resources.
Juno <IP_ADDRESS> is a major update.
HttpClient
that performs
serialization and parsing using Juno parsers, but leaves all the details of the HTTP connection
to the Apache code. org.apache.juneau.rest.client.jazz
package and org.apache.juneau.rest.client.jazz.JazzRestClient
class
for performing REST operations against Jazz servers.ExtendedReaderParser
abstract class and moved methods into
{@link org.apache.juneau.parser.ReaderParser} class.
DataFormat
class from API since it was no longer necessary
due to API change above.
ParserStringReader
class.String
input.String
input, and tests show no significant performance differences.
org.apache.juneau.parser.Parser.parse(Object,int,ClassMeta)
convenience method added.
BeanContext.getClassMetaFromString(String)
."long[]"
, and so forth.
http://host/contextRoot/foo%2Fbar
).
BeanContext.setDefaultParser(ReaderParser)
method added for specifying
a default parser to use in a bean context (used when converting beans to Strings
using
BeanContext.convertToType(Object,Class)
.
Old behavior simply used the default JSON serializer in these cases.
RestRequest#getParameter(String,Class)
RestRequest.getMapParameter(String,Class,Class,Class)
and
RestRequest.getCollectionParameter(String,Class,Class)}
methods.
Juno <IP_ADDRESS> is a minor update.
org.apache.juneau.urlencoding.UrlEncodingParser.parseArgs(Reader,int,ClassMeta[])
.
name
parameter of ResourceDescription#ResourceDescription(String,String,String)
.
is now automatically URL-encoded so that the name can contain special characters (e.g. BeanContext.getClassMetaFromString(String)
.
Now supports primitive arrays such as Juno <IP_ADDRESS> is a minor update.
Juno <IP_ADDRESS> is a moderate update.
RestServlet.createRequestVarResolver(RestRequest)
for more information.
RestRequest.getVarResolver()
RestRequest.getServletURI()
RestRequest.getRequestParentURI()
RestResponse.sendRedirect(CharSequence)
RestServlet.createConfigFactory()
RestServlet.createConverters()
RestServlet.createDefaultRequestHeaders()
RestServlet.createDefaultResponseHeaders()
RestServlet.createEncoders()
RestServlet.createFilters()
RestServlet.createGuards()
RestServlet.createMimetypesFileTypeMap()
RestServlet.createParsers()
RestServlet.createProperties()
RestServlet.createRequestProperties(ObjectMap,RestRequest)
RestServlet.createRequestVarResolver(RestRequest)
RestServlet.createSerializers()
RestServlet.createUrlEncodingParser()
RestServletNls
to use ResourceDescription/MethodDescription
instead of RestResource/RestMethod
RestServletProperties.REST_htDocsFolder
.BeanFilter.setStopClass(Class)
ResultSetList.handleBlob(Blob)
ResultSetList.handleClob(Clob)
Juno <IP_ADDRESS> is a moderate update.
WriterSerializer s = new JsonSerializer();
addNotBeanClassPatterns(String...)
methods throughout API since these are now controlled by {@link org.apache.juneau.BeanContext#BEAN_notBeanPackages_add} / {@link org.apache.juneau.BeanContext#BEAN_notBeanPackages_remove} properties.
RestServletProperties
.
RestServletProperties.REST_trimTrailingUriSlashes
RestRequest.getRequestURI(boolean trimTrailingSlashes)
method which is now redundant with this property.
RestServletProperties.REST_pathInfoBlankForNull
RestRequest.getPathInfo(boolean returnBlankForNull)
method which is now redundant with this property.
maxDepth
setting is reached, and will instead simply ignore content below the specified depth.?x-response-headers={Refresh=1}
HtmlDocSerializerContext.HTML_REFRESH
setting that added a Refresh meta tag to HTML documents, since this can now be controlled through X-Response-Headers
.
PhotosResource
now includes a default entry.
Juno <IP_ADDRESS> is a moderate update.
org.apache.juneau.parser.Parser.parseMap(Object,int,Class,Class,Class)
org.apache.juneau.parser.Parser.parseCollection(Object,int,Class,Class)
Enums
through overriding toString()
and fromString()
on the enum class.Enum.valueOf()
to convert strings back into Enums
.Object
when the type is erased.
setFoo(Foo f)
, setFoo(Bar b)
), the {@link org.apache.juneau.BeanMap} API would sometime choose the wrong setter as the bean property setter. Accept
GET parameters with &Accept=text/json+simple
) wasn't working anymore.Accept
parameter is supposed to interpret spaces as &Accept=text/json%2Bsimple
.
Juno <IP_ADDRESS> is a moderate update.
Juno <IP_ADDRESS> is a minor update.
Bean.subTypes()
annotation in addition to subTypes
property.
Juno <IP_ADDRESS> is a moderate update.
Bean.subTypeProperty() subtypes
. @Bean (filter=xxx)
with new @Transform
org.apache.juneau.transforms.DateSwap.ISO8601DTP
org.apache.juneau.transforms.DateSwap.ISO8601DTZP
Juno <IP_ADDRESS> is a moderate update.
OutOfMemoryError
and performance issue caused by incorrect caching of class metadata.
WriterSerializer.serialize(Object,Writer)
convenience method for serializing directly to a writer.Juno <IP_ADDRESS> is a moderate update.
OPTIONS
pages through new method ResourceOptions.getChildren()
Juno <IP_ADDRESS> is a minor update.
@RestMethod .pattern()
to {@link org.apache.juneau.rest.annotation.RestMethod#path() @RestMethod.path()} for naming consistency.
Juno <IP_ADDRESS> is a minor update.
SqlQueryResource
class in the sample war for demonstrating the ResultSetList
DTO.
Servlet.init()
so that getProperties()
can be called during servlet initialization.
@Property .type
annotation with support for using system properties as resource properties.
Juno <IP_ADDRESS> is a major update.
AtomFeedResource
class added to sample war.
XmlFormat.CONTENT
enum value.XmlContentHandler
class and @Xml.contentHandler
annotation.@Xml .valAttr
annotation since it's now redundant with @Xml (format=CONTENT )
.
Serializer.serialize(Object,Object,SerializerContext)
method.
Juno <IP_ADDRESS> is a minor update.
@Xml
annotation was not being inherited by inner classes.
Juno <IP_ADDRESS> is a minor update.
@Property .nls()
annotation for specifying localized property values.AddressBookResource
class for an example.
&Content
query parameter was not always parsed correctly.Juno <IP_ADDRESS> is a minor update.
HtmlDocSerializerContext.HTMLDOC_navlinks
annotation for addint links to HTML page views.
HtmlDocSerializerContext
for clarity.
RestServlet.addDefaultProperties(ObjectMap,RestRequest)
method for programatically adding properties to the property map per request.
SerializerContext.SERIALIZER_uriAuthority
and SerializerContext.SERIALIZER_uriContext
properties were previously available.
RestServletProperties.REST_servletPath
RestServletProperties.REST_pathInfo
RestServletProperties.REST_method
@Attr
Juno <IP_ADDRESS> is a major update.
XmlSerializerContext.XML_autoDetectNamespaces
default changed to XmlSerializerContext.XML_namespaces
annotation.RestMethod.filters()
annotation for defining POJO filters at the method level.
RestMethod.serializersInherit()
and RestMethod.parsersInherit()
annotations for controlling how serializers and parsers (and associated filters and properties) are inherited from the class.addSerializers
and addParsers
annotations.
RestServletJenaDefault
servlet that includes serialization/parsing support for all Jena-based serializers and parsers.
DefaultJenaProvider
JAX-RS provider that includes serialization/parsing support for all Jena-based serializers and parsers.
RestServletChild
class.RestServlet.createConfigFactory()
RestServlet.createSerializers()
RestServlet.createParsers()
getBeanContext()
/ getSerializers()
/ getParsers()
methods.
RestCall.setDateHeader(String,Object)
method for setting ISO8601 datetime headers.
Juno <IP_ADDRESS> is a minor update.
RestServlet.onPreCall(RestRequest)
RestServlet.onPostCall(RestRequest,RestResponse)
SerializerContext.SERIALIZER_trimNullProperties
.Juno <IP_ADDRESS> is a moderate update.
The biggest change is the introduction of the {@link org.apache.juneau.jena.RdfSerializer} class that uses Jena to generate RDF/XML, RDF/XML-ABBREV, N-Tuple, N3, and Turtle output.
This code should be considered prototype-quality, and subject to change in the future.
There are plans of adding an equivalent RdfParser
class in the future, so the serializer logic may need to be tweaked to allow POJOs to be reconstituted correctly in the parser.
The RdfXmlSerializer
class should be considered deprecated for now.
However, I'm keeping it around, since it's considerably faster and uses far less memory than the Jena-based serializer since it serializes directly from POJOs to RDF/XML.
It may or may not be removed in the future depending on demand.
Juno <IP_ADDRESS> is a minor update.
IOutputStreamSerializer.serialize()
and IInputStreamParser.parse()
.
Juno <IP_ADDRESS> is a minor update.
@Properties
REST method parameter annotation that can be used to get the runtime properties map through a parameter instead of through {@link org.apache.juneau.rest.RestResponse}.
Juno <IP_ADDRESS> is a moderate update.
@Produces
annotation in place of ISerializer.getMediaTypes()
for specifying what media types a serializer produces.@Consumes
annotation in place of IParser.getMediaTypes()
for specifying what media types a parser consumes.Juno <IP_ADDRESS> is a major update.
The biggest change is that the RestSerializer
, RestParser
, RestSerializerGroup
, and RestParserGroup
classes have been eliminated entirely.
Instead, the existing {@link org.apache.juneau.serializer.Serializer}, {@link org.apache.juneau.parser.Parser}, {@link org.apache.juneau.serializer.SerializerGroup}, and {@link org.apache.juneau.parser.ParserGroup} classes of the core API have been augmented to replace them.
Adoptions will be required if you have previously used these classes.
Accept-Content
headers.ObjectFilter
).Accept-Encoding
header values.application/x-java-serialized-object
content.text/xml+soap
content.JsonMap
and JsonList
changed to {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} to better reflect that they're not limited to just JSON support.
PojoSwap
to {@link org.apache.juneau.utils.PojoQuery} to not confuse it with the new Filter API.
org.apache.juneau.rest.serializers
and org.apache.juneau.rest.parsers
packages.
RestCmdLine
(since it's essentially redundant with CURL).
Juno <IP_ADDRESS> is a minor update.
SerializerContext.SERIALIZER_uriContext
and SerializerContext.SERIALIZER_uriAuthority
serializer properties for specifying values for relative URIs.
java.net.URI
or java.net.URL
.
BeanProperty#uri
annotation to BeanProperty#beanUri
to make it clear that this property represents the URI of the bean itself instead of an arbitrary property containing a URI.
BeanProperty#id
annotation.
SerializerContext.SERIALIZER_uriContext
property set by default to web app context root.SerializerContext.SERIALIZER_uriAuthority
property set by default to the request scheme+hostname+port.Accept-Charset
header in Chrome that prevented HTML output from rendering correctly in that browser.Accept-Charset
handling should now be fully W3C compliant.
Juno <IP_ADDRESS> is a minor update.
BeanProperty.method
annotation, since it's now unnecessary.
PlainTextRestSerializer
class for serializing Readers
and InputStreams
can now be passed in as @Content
?debug
parameter.Juno <IP_ADDRESS> is a moderate update.
UrlEncodingRestSerializer
and UrlEncodingRestParser
classes.Accept
and Content-Type
RestServlet.renderError(HttpServletRequest,HttpServletResponse,RestException)
method to allow customized handling of response errors.
Juno <IP_ADDRESS> is a minor update.
RestServletProperties
class that defines all the class-level properties that can be set on the servlet.RestServlet.setProperty(String,Object)
method.RestServletProperties.REST_useStackTraceHashes
property to prevent the same stack trace from being logged multiple times.RestServletProperties.REST_renderResponseStackTraces
property for preventing stack traces in responses for security reasons.RestServlet.onError(HttpServletRequest,HttpServletResponse,RestException,boolean)
and RestServlet.onSuccess(RestRequest,RestResponse,long)
methods for plugging in your own logging and peformance monitoring.RestServlet.getInitParams()
method, since it's now redundant with {@link org.apache.juneau.rest.RestServlet#getProperties()}.Juno <IP_ADDRESS> is a moderate update.
ObjectMaps
directly to beans.OPTIONS
pages.Readers
and InputStreams
can be specified on @Content
@HasParam
Accept
headers to serializers.Juno <IP_ADDRESS> is a minor update.
Juno <IP_ADDRESS> is a major update.
@Xml.namespaces
<EMAIL_ADDRESS><EMAIL_ADDRESS>annotation.SerializerContext
ParserContext
@BeanProperty.hidden()
so that they don't get serialized.
ClassType
{@link org.apache.juneau.ClassMeta}<EMAIL_ADDRESS>@BeanProperty.filter
BeanContext.addTransforms(Class[])
.
@BeanProperty.beanUri
@BeanProperty.id
rdf:resource
attributes.
@RestResource.filters()
- Associate post-formatting filters on a resource level.@RestMethod.filters()
- Associate post-formatting filters on a method level.@Attr
@Param
@Content
Juno <IP_ADDRESS> is a minor update that fixes a small bug in <IP_ADDRESS>.
Juno <IP_ADDRESS> is a major update.
@RestChild
annotation for identifying child resources.traversable
and filterable
attributes added to {@link org.apache.juneau.rest.annotation.RestMethod @RestMethod} annotation.PojoResource
and FilteredRestResource
classes.
resourceUri
attributed added to RdfXmlSerializer
.Juno <IP_ADDRESS> is a minor update.
BeanContext.convertToType(Object,Class)
to be able to convert Strings
to classes with
fromString(String)
/valueOf(String)
static methods or T(String)
constructors.
Juno <IP_ADDRESS> is a minor update.
Juno <IP_ADDRESS> is a minor update.
org.apache.juneau.json
).
Enum
keys, and parsing Enum
strings.ObjectList.toXArray()
methods with a new elements(Class<T> type)
method that's more efficient and avoids creating an unnecessary array.
Juno <IP_ADDRESS> is a moderate update.
Version 5.0 marks a major release milestone for the Juno/JJSON library. It is now available for download from iRAM under the name "Juno (previously JJSON)". The Juno Starters Guide has been updated to reflect new functionality in this release.
Transform
BeanContext
class (and thus the Serializer and Parser classes too) through the BeanContext.addTransforms(Class[])
method.Transform
Cast
and BeanFilter
APIs which were considerably more complicated and puts them under a common API.
_class
attributes in parsable output.BeanMap
API.BeanMap
API code.
Reflection is used to determine the class types of property values on beans.
This information is now cached and persisted so that the reflection API calls to determine class types are only performed the first time a bean type is encountered.
RestServlets
.Accept-Encoding: gzip
) and charsets (e.g Accept-Charset: SJIS
) on both incoming and outgoing data.
It's all transparent from a developers perspective.
The developer simply working with POJOs, and all details about content types, encoding, charsets, and so forth are handled by the framework.
OPTIONS
pages for resources.
RestServlet
.
Enum
.
MyBeanList extends LinkedList<MyBean>
).