Release 6.4.0
Date: Oct 5, 2017
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: JSON, XML, HTML, UON, URL-Encoding, MessagePack, SOAP/XML, CSV, BSON (coming soon), YAML (coming soon), Protobuf (coming soon) | Java 6 |
juneau-marshall | Serializers and parsers for: RDF/XML, RDF/XML-Abbrev, N-Triple, Turtle, N3 | Java 6, Apache Jena 2.7.1 | |
juneau-dto | Data Transfer Objects for: HTML5, Atom, Cognos, JSON-Schema, Swagger 2.0 | Java 6 | |
juneau-svl | Simple Variable Language API | Java 6 | |
juneau-config | Configuration file API | Java 6 | |
| Juneau REST | juneau-rest-server | REST Servlet API | Java 6, Servlet 3.1 |
juneau-rest-server-jaxrs | Optional JAX-RS support | Java 6, JAX-RS 2.0 | |
juneau-rest-client | REST Client API | Java 6, Apache HttpClient 4.5 | |
| Juneau Microservice | juneau-microservice-server | REST Microservice Server API | Java 8, Eclipse Jetty 9.4.3 |
juneau-microservice-template | Developer template project | Java 8, Eclipse Jetty 9.4.3 | |
| Examples | juneau-examples-core | Core code examples | |
juneau-examples-rest | REST code examples | ||
| Juneau All | juneau-all | Combination of: juneau-marshall, juneau-dto, juneau-svl, juneau-config, juneau-rest-server, juneau-rest-client | Java 6, Servlet 3.1, Apache HttpClient 4.5 |
juneau-marshall
-
Improvements to swap support.
-
New @Swap annotation. Replaces the
@Pojoand@BeanProperty(swap)annotations. -
Support for per-media-type swaps.
Programmatic example:
@Swap(MyJsonOnlySwap.class)
public class MyPojo {}
public class MyJsonOnlySwap extends PojoSwap<MyPojo,String> {
public MediaType[] forMediaTypes() {
return MediaType.forStrings("*/json");
}
public String swap(BeanSession session, MyPojo o) throws Exception {
return "It's JSON!";
}Annotated example:
@Swap(impl=ToStringSwap.class, mediaTypes="*/json")
public class MyBean { ... }
public class ToStringSwap extends PojoSwap<Object,String> {
public String swap(BeanSession session, Object o) throws Exception {
return o.toString();
}
} -
Support for templated swaps which provide additional context information for a swap. The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker:
// Our abstracted templated swap class.
public abstract class FreeMarkerSwap extends PojoSwap<Object,Reader> {
public MediaType[] forMediaTypes() {
return MediaType.forStrings("*/html");
}
public Reader swap(BeanSession session, Object o, String template) throws Exception {
return getFreeMarkerReader(template, o); // Some method that creates raw HTML.
}
}@Swap(impl=FreeMarkerSwap.class, template="MyPojo.div.ftl")
public class MyPojo {} -
New
@Swapsannotation for defining multiple swaps against the same POJO when they're differentiated by media types:@Swaps(
{
@Swap(MyJsonSwap.class),
@Swap(MyXmlSwap.class),
@Swap(MyOtherSwap.class)
}
)
public class MyPojo {}
-
-
New
Surrogateinterface for identifying surrogate classes. -
Serializers can now serialize to StringBuilders.
-
Serializers now serialize the contents of Readers and InputStreams directly to the output stream or writer. When used with conjunction with
PojoSwaps, this can be used to provide customized output for specific content types.@Pojo(swap=MyBeanSwap.class)
public class MyBean {...}
public class MyBeanSwap extends PojoSwap<MyBean,Object> {
public Object swap(BeanSession session, MyPojo o) throws Exception {
MediaType mt = session.getMediaType();
if (mt.hasSubType("json"))
return new StringReader("{foo:'bar'}"); // Custom JSON output
return o; // Otherwise treat as normal bean
}
}
// Produces "{foo:'bar'}"
String json = SimpleJsonSerializer.DEFAULT.toString(new MyBean());This feature helps with the implementation of language-agnostic template support such as for using FreeMaker to serialize POJOs to HTML.
-
SerializerSession and ParserSession objects are now reusable if used within the same thread.
// Old way (still works)
JsonSerializer.DEFAULT.serialize(writer1, pojo1);
JsonSerializer.DEFAULT.serialize(writer2, pojo2);
// Same but using a session object
SerializerSession session = JsonSerializer.DEFAULT.createSession();
try {
session.serialize(writer1, pojo1);
session.serialize(writer2, pojo2);
} finally {
session.close();
}This is mostly an internal change and doesn't affect the existing APIs.
-
PojoSwap.swap(BeanSession,Object)andPojoSwap.unswap(BeanSession,Object,ClassMeta)can now throw arbitrary exceptions instead of having to wrap them inSerializeException/ParseException. -
New
CalendarUtilsclass that encapsulates serialization/parsing logic fromCalendarSwapandDateSwap. -
New annotation @Html(anchorText).
-
New methods on
ObjectList:ObjectList.get(int,Class)ObjectList.get(int,Type,Type...)ObjectList.getMap(int,Class,Class)ObjectList.getList(int,Class)
-
New methods on
ObjectMap:ObjectMap.get(String,Class)ObjectMap.get(String,Type,Type...)ObjectMap.getWithDefault(String,Object)ObjectMap.getWithDefault(String,Object,Class)ObjectMap.getWithDefault(String,Object,Type,Type...)ObjectMap.getSwapped(String,PojoSwap)ObjectMap.getAt(String,Class)ObjectMap.getAt(String,Type,Type...)ObjectMap.getMap(String,Class,Class,Map)ObjectMap.getList(String,Class,List)
-
New methods on
PojoRest:PojoRest.get(String,Class)PojoRest.get(String,Type,Type...)PojoRest.getWithDefault(String,Object)PojoRest.getWithDefault(String,Object,Class)PojoRest.getWithDefault(String,Object,Type,Type...)
-
Fixed bug where BeanSession.getMediaType() wasn't returning a value.
-
Eliminated the
@Consumesand@Producesannotations. The supported media types are now passed in through the constructors. This was changed to eliminate a performance issue where a field could not be set as final because the call togetClass()to retrieve the annotation value could not be called before calling thesuper()method. -
New class:
PojoMerge -
New doc:
2.6.2 - @Pojo annotation -
New doc:
2.6.5 - Serializing Readers and InputStreams
juneau-dto
-
HtmlElementMixed.children(Object...) can now take in collections of objects.
-
The DTO beans can now be serialized to strings of their typical language by calling the
toString()method. For example,Swagger.toString()produces JSON and the HTML5Form.toString()produces HTML.
juneau-rest-server
-
Revamped and simplified servlet and REST-call lifecycle handling through new
@RestHookannotation.-
The
RestServlet.init(ServletConfig)method is now final and can no longer be extended. Instead, useHookEvent.INITorHookEvent.POST_INITfor initialization. -
The following methods on
RestServlethave been removed:init(RestConfig)- UseHookEvent.INITinstead.onSuccess(RestRequest, RestResponse, long)- UseHookEvent.END_CALLinstead.onPreCall(RestRequest)- UseHookEvent.PRE_CALLinstead.onPostCall(RestRequest, RestResponse)- UseHookEvent.POST_CALLinstead.
-
-
Simplified MenuItemWidget. Exposes an abstract method
getContent(RestRequest)that can return raw HTML via readers or char-sequences, or any other object (such as HTML5 beans) that will get converted to HTML using HtmlSerializer.DEFAULT. -
RestResourceResolverinstances are now inherited from parent resources to child resources unless explicitly overridden at the child level. It's also been changed to an interface. -
New annotations on
@RestResource:resourceResolver()- Allows you to specify a resource resolver on the servlet context to make it easier to work with dependency injection frameworks.contextPath()- Allows you to override the context path value inherited from the servlet container.allowHeaderParams()- Replaces theRestContext.REST_allowHeaderParamssetting.allowMethodParam()- Replaces theRestContext.REST_allowMethodParamsetting.allowBodyParam()- Replaces theRestContext.REST_allowBodyParamsetting.renderResponseStackTraces()- Replaces theRestContext.REST_xxxsetting.useStackTraceHashes()- Replaces theRestContext.REST_useStackTraceHashessetting.defaultCharset()- Replaces theRestContext.REST_defaultCharsetsetting.paramFormat()- Replaces theRestContext.REST_paramFormatsetting.
-
New annotations on
@RestMethod:RestMethod.defaultCharset()- Replaces theRestContext.REST_defaultCharsetsetting.RestMethod.paramFormat()- Replaces theRestContext.REST_paramFormatsetting.
-
The following implementation classes can now be defined as non-static inner classes of servlets/resources:
- Widget
RestConverterRestGuardResponseHandlerRestCallHandlerRestInfoProviderRestResourceResolverRestLogger- HtmlDocTemplate
-
New tooltip template: Tooltip
-
New dark theme available:

-
Stylesheet selection now stored in HTTP session when passed in via
?stylesheetquery parameter. -
New doc: Lifecycle Hooks
-
Eliminated the
RestServletJenaDefaultclass to remove the Jena dependency class on thejuneau-rest-serverartifact. It's simple enough to simply extendBasicRestServletand add the RDF serializers and parsers.
juneau-microservice
-
The microservice has been significantly modified to be configured via a
jetty.xmlfile for maximum flexibility instead of the hodge-podge of support in the config file. Top-level servlets should now be defined in the providedjetty.xmlfile. -
New methods on
RestMicroservice:addServlet(Servlet,String)addServletAttribute(String,Object)getServer()getInstance()getPort()getContextPath()getProtocol()getHostName()
-
New methods on Microservice:
-
New class
JettyLoggerfor directing Jetty logging to the java.util.logging framework. -
New class
DebugResourcefor viewing and generating Jetty thread dumps through REST calls.
org.apache.juneau.rest.examples
-
New example of adding a menu-item widget to the Pet Store resource (including tooltips):

Share feedback or follow-up questions for this page directly through GitHub.