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
@Pojo
and@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
@Consumes
and@Produces
annotations. 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_allowHeaderParams
setting.allowMethodParam()- Replaces theRestContext.REST_allowMethodParam
setting.allowBodyParam()- Replaces theRestContext.REST_allowBodyParam
setting.renderResponseStackTraces()- Replaces theRestContext.REST_xxx
setting.useStackTraceHashes()- Replaces theRestContext.REST_useStackTraceHashes
setting.defaultCharset()- Replaces theRestContext.REST_defaultCharset
setting.paramFormat()- Replaces theRestContext.REST_paramFormat
setting.
-
New annotations on
@RestMethod:RestMethod.defaultCharset()- Replaces theRestContext.REST_defaultCharset
setting.RestMethod.paramFormat()- Replaces theRestContext.REST_paramFormat
setting.
-
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
?stylesheet
query parameter. -
New doc: Lifecycle Hooks
-
Eliminated the
RestServletJenaDefault
class to remove the Jena dependency class on thejuneau-rest-server
artifact. It's simple enough to simply extendBasicRestServlet
and add the RDF serializers and parsers.
juneau-microservice
-
The microservice has been significantly modified to be configured via a
jetty.xml
file for maximum flexibility instead of the hodge-podge of support in the config file. Top-level servlets should now be defined in the providedjetty.xml
file. -
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):