Skip to main content

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":

CategoryMaven ArtifactsDescriptionPrereqs
Juneau Corejuneau-marshallSerializers 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-marshallSerializers and parsers for: RDF/XML, RDF/XML-Abbrev, N-Triple, Turtle, N3Java 6, Apache Jena 2.7.1
juneau-dtoData Transfer Objects for: HTML5, Atom, Cognos, JSON-Schema, Swagger 2.0Java 6
juneau-svlSimple Variable Language APIJava 6
juneau-configConfiguration file APIJava 6
Juneau RESTjuneau-rest-serverREST Servlet APIJava 6, Servlet 3.1
juneau-rest-server-jaxrsOptional JAX-RS supportJava 6, JAX-RS 2.0
juneau-rest-clientREST Client APIJava 6, Apache HttpClient 4.5
Juneau Microservicejuneau-microservice-serverREST Microservice Server APIJava 8, Eclipse Jetty 9.4.3
juneau-microservice-templateDeveloper template projectJava 8, Eclipse Jetty 9.4.3
Examplesjuneau-examples-coreCore code examples
juneau-examples-restREST code examples
Juneau Alljuneau-allCombination of: juneau-marshall, juneau-dto, juneau-svl, juneau-config, juneau-rest-server, juneau-rest-clientJava 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 @Swaps annotation 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 Surrogate interface 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) and PojoSwap.unswap(BeanSession,Object,ClassMeta) can now throw arbitrary exceptions instead of having to wrap them in SerializeException/ParseException.

  • New CalendarUtils class that encapsulates serialization/parsing logic from CalendarSwap and DateSwap.

  • 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 to getClass() to retrieve the annotation value could not be called before calling the super() 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 HTML5 Form.toString() produces HTML.

juneau-rest-server

  • Revamped and simplified servlet and REST-call lifecycle handling through new @RestHook annotation.

    • The RestServlet.init(ServletConfig) method is now final and can no longer be extended. Instead, use HookEvent.INIT or HookEvent.POST_INIT for initialization.

    • The following methods on RestServlet have been removed:

      • init(RestConfig) - Use HookEvent.INIT instead.
      • onSuccess(RestRequest, RestResponse, long) - Use HookEvent.END_CALL instead.
      • onPreCall(RestRequest) - Use HookEvent.PRE_CALL instead.
      • onPostCall(RestRequest, RestResponse) - Use HookEvent.POST_CALL instead.
  • 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.

  • RestResourceResolver instances 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 the RestContext.REST_allowHeaderParams setting.
    • allowMethodParam() - Replaces the RestContext.REST_allowMethodParam setting.
    • allowBodyParam() - Replaces the RestContext.REST_allowBodyParam setting.
    • renderResponseStackTraces() - Replaces the RestContext.REST_xxx setting.
    • useStackTraceHashes() - Replaces the RestContext.REST_useStackTraceHashes setting.
    • defaultCharset() - Replaces the RestContext.REST_defaultCharset setting.
    • paramFormat() - Replaces the RestContext.REST_paramFormat setting.
  • New annotations on @RestMethod:

    • RestMethod.defaultCharset() - Replaces the RestContext.REST_defaultCharset setting.
    • RestMethod.paramFormat() - Replaces the RestContext.REST_paramFormat setting.
  • The following implementation classes can now be defined as non-static inner classes of servlets/resources:

    • Widget
    • RestConverter
    • RestGuard
    • ResponseHandler
    • RestCallHandler
    • RestInfoProvider
    • RestResourceResolver
    • RestLogger
    • HtmlDocTemplate
  • New tooltip template: Tooltip

  • New dark theme available:

    Dark Theme

  • 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 the juneau-rest-server artifact. It's simple enough to simply extend BasicRestServlet 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 provided jetty.xml file.

  • New methods on RestMicroservice:

    • addServlet(Servlet,String)
    • addServletAttribute(String,Object)
    • getServer()
    • getInstance()
    • getPort()
    • getContextPath()
    • getProtocol()
    • getHostName()
  • New methods on Microservice:

  • New class JettyLogger for directing Jetty logging to the java.util.logging framework.

  • New class DebugResource for 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):

    Pet Store Menu Example