Welcome!

Industrial IoT Authors: John Katrick, Stackify Blog, Yeshim Deniz, Elizabeth White, SmartBear Blog

Related Topics: Java IoT, Industrial IoT, @CloudExpo

Java IoT: Blog Feed Post

Solving the XML Problem with Jackson | @CloudExpo #API #Java #JSON #Cloud

Jackson is a popular library for handling JSON in Java applications, quickly becoming the de-facto standard in the ecosystem

Solving the XML Problem with Jackson
By Eugen Paraschiv

Jackson is a popular library for handling JSON in Java applications, quickly becoming the de-facto standard in the ecosystem. Starting with version 2, it has also introduced a mature XML implementation alongside its established JSON support.

Adding Jackson XML to the Project
Adding the Jackson XML module to the project only needs a single dependency - the Jackson XML module itself:

<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.0</version>
</dependency>

And in Gradle:

compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.0"

This will automatically pull in all of the other Jackson dependencies that are needed:

Note that the Woodstox StAX library can be excluded and replaced with any other valid implementation of the StAX API.

Configuring the Jackson XML Module
Jackson is typically used by means of an ObjectMapper instance. In order to work with XML, we'll instead use the XmlMapper class. This is a direct extension of ObjectMapper and can be used as a replacement, with the exact same API we're already used to.

The absolute simplest way of working with this is to just use the default configuration:

ObjectMapper objectMapper = new XmlMapper();

However, if we need additional configuration, we can instead construct the Jackson Module manually and set it up as necessary:

JacksonXmlModule xmlModule = new JacksonXmlModule();
xmlModule.setDefaultUseWrapper(false);
ObjectMapper objectMapper = new XmlMapper(module);

As of version 2.9.0, the only configuration options for the XML Module are:

  • setDefaultUseWrapper - defines whether or not to use a wrapper for non-annotated List properties by default
  • setXMLTextElementName - defines the virtual name to use when processing character data sections - when not binding to Java beans

Due to the fact that the XmlMapper extends the standard ObjectMapper, we can essentially use all of the standard Jackson ObjectMapper configuration settings and APISs.

For example, we can configure it to produce indented output as follows:

objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

Note that some of these settings might not work with some XML implementations. For example, older versions of Jackson XML depended on Stax2Writer, which didn't support writing raw characters to the stream. This means that it doesn't support writing the raw newlines and indentations needed for the INDENT_OUTPUT feature to work.

Object Serialization
Jackson is best known for its ability to serialize POJOs into JSON and back, by means of standard conventions and - where necessary - special annotations to give clues to the Jackson library.

As already mentioned, the XmlMapper object directly replaced ObjectMapper, only it works in terms of XML instead of JSON. This means that the API is exactly the same, and it can be used as a direct replacement.

Writing XML
Writing XML is done using the various
writeValue methods that Jackson exposes. For example, marshalling some object to XML is done simply by using the writeValueAsString API:

String xml = objectMapper.writeValueAsString(input);

The standard versions of this all exist and work as expected:

  • Writing to a String
  • Writing to a Byte Array
  • Writing to a java.io.OutputStream - e.g. for streaming over a network connection
  • Writing to a java.io.Writer
  • Writing to a java.io.File

Reading XML
As we just explored, we the library handles writing to XML quite well.

We can also read XML, using the various readValue APIs that are part of provided by the ObjectMapper.

For example, reading some XML from an InputStream into a Java Bean:

MyBean bean = objectMapper.readValue(inputStream, MyBean.class);

Again, the standard versions of this all exist, and work as expected:

  • Reading from a String
  • Reading from a Byte Array
  • Reading from a java.io.InputStream - e.g. for streaming over a network connection
  • Reading from a java.io.Reader
  • Reading from a java.io.File

Jackson Annotations for Serialization
The Jackson XML module supports the full range of annotations that Jackson provides for annotating our POJOs
.

This means that we can have one single set of beans, with one set of annotations and, depending on the ObjectMapper instance, we select whether we get XML or JSON. That's a huge benefit when it comes to structuring our code, as we no longer have to worry about translating between different beans that represent essentially the same data just to get different serialization formats.

For example, given the following bean:

@JsonPropertyOrder({"age", "id", "name"})
public class Person {
@JsonProperty("_id")
private String id;

private String name;

private int age;

@JsonIgnore
private String note;
}

will produce this JSON:

{
"age":4,
"_id":"12345",
"name":"George"
}

And this XML:

<Person>
<age>4</age>
<_id>12345</_id>
<name>George</name>
</Person>

Additional Jackson Annotations for XML
The Jackson XML module adds some additional support for XML specific features.
These annotations allow us to control the XML namespace and local name for elements, including the root element, whether a field is rendered in an element or as plain text, whether the content of an element is rendered in a CData wrapper, and whether a collection should use a wrapper element or not.

@JacksonXmlProperty

@JacksonXmlProperty can be applied to any field in a bean to control the details of the element that is being rendered. This annotation allows us to determine the namespace, the local name, and whether the field is serialized as an Element or an Attribute. For example, the following bean:

For example, the following bean:

public class Person {
@JacksonXmlProperty(
isAttribute = true, namespace = "urn:stackify:jacksonxml", localName = "_id")
private String id;

@JacksonXmlProperty(namespace = "urn:stackify:jackson")
private String name;

private String note;
}

This generates the following XML output:

<Person xmlns:wstxns1="urn:stackify:jacksonxml"
wstxns1:_id="12345">
<wstxns2:name xmlns:wstxns2="urn:stackify:jackson">Graham</wstxns2:name>
<note>Hello</note>
</Person>

@JacksonXmlRootElement

The @JacksonXmlRootElement has a similar role to the @JacksonXmlProperty but for the root element of the entire document. This can only adjust the Namespace and Local name - since the root element can never be serialized as an attribute.

For example, let's look at this Java POJO:

@JacksonXmlRootElement(namespace = "urn:stackify:jacksonxml", localName = "PersonData") public class Person {
private String id;

private String name;

private String note;
}

When serialized, this will result in the following XML:

<PersonData xmlns="urn:stackify:jacksonxml">
<id xmlns="">12345</id>
<name xmlns="">Graham</name>
<note xmlns="">Hello</note>
</PersonData>

@JacksonXmlText

Next, let's have a look at the @JacksonXmlText annotation.

Simply put, this indicates that an element should be rendered as plain text without another element containing it.

For example, the following POJO:

public class Person {
private String id;

private String name;

@JacksonXmlText
private String note;
}

Will produce this simple XML output:

<Person>
<id>12345</id>
<name>Graham</name>
Hello
</Person>

Naturally, you do have to be careful using this annotation and make sure you're still generating valid XML.

@JacksonXmlCData

The @JacksonXmlCData annotation indicates that a CData wrapper should be placed around the content of the element. This can be used in conjunction with the @JacksonXmlText if desired to produce a CData wrapper without an element tag.

Let's have a look at a POJO using this annotation:

public class Person {
private String id;

@JacksonXmlCData
private String name;

@JacksonXmlText
@JacksonXmlCData
private String note;
}

This will result in the following XML:

<Person>
<id>12345</id>
<name><![CDATA[Graham]]></name>
<![CDATA[Hello]]>
</Person>

JacksonXmlElementWrapper

The @JacksonXmlElementWrapper annotation is used to override the default setting from setDefaultUseWrapper - as seen above. This can ensure that a collection either does or does not use a wrapper element, and can control what the wrapper element uses for namespace and local name.

When using wrapper elements, we get an additional element added which contains all of the elements from the collection, and when wrapper elements are not used then the individual collection elements are written directly inline:

class Wrapper {
@JacksonXmlElementWrapper(localName = "list")
private List names;
}

This will produce the following XML:

<Wrapper>
<list>
<names>John</names>
<names>Paul</names>
<names>George</names>
<names>Ringo</names>
</list>
</Wrapper>

Whereas, if the JacksonXmlElementWrapper is replaced with:

@JacksonXmlElementWrapper(useWrapping = false)

Then the XML produced won't contain the list element:

<Wrapper>
<names>John</names>
<names>Paul</names>
<names>George</names>
<names>Ringo</names>
</Wrapper>

Supporting JAXB Annotations

The Jackson XML module also has the ability to support the standard JAXB annotations on our beans - instead of needing the Jackson specific ones. This can be useful if we want to use Jackson for the actual XML Serialization but don't want to depend on it at compile time.

This can also be used to allow JAXB to generate our bean definitions from an XML Schema and have Jackson process them.

This functionality is an additional module that needs to be added in for it to work. It doesn't work out of the box like the Jackson annotations do. In order to configure this - we need to add the JaxbAnnotationModule to our ObjectMapper as follows:

objectMapper.registerModule(new JaxbAnnotationModule());

We can now write or generate a Java bean with JAXB annotations and simply process it with this XmlMapper.

For example, the following POJO:

@XmlRootElement(name = "employee")
@XmlAccessorType(XmlAccessType.FIELD)
public class EmployeeBean {
@XmlAttribute(name = "_id")
@XmlID
private String id;

@XmlElement
private String name;

@XmlElement
private String type;
}

Will produce the following XML when marshalled:

<employee _id="12345">
<name>Graham</name>
<type>Developer</type>
</employee>

Partial Reading and Writing
Jackson also has the powerful ability to actually jump into the middle of an existing XML file and either marshall or unmarshall XML to and from that file.

The functionality makes good use of the standard XMLStreamWriter class, and naturally of XMLStreamReader as well. This cool functionality gives us a lot of flexibility to work with existing XML documents and integrate with these cleanly and easily.

Generating XML
The XmlMapper is able to serialize an entire Java bean into a document that is currently being produced, allowing Jackson to integrate and construct the document along with other external actors. This also gives some ability to support constructs that Jackson cannot handle natively - for example, the XML Prolog.

In order to do this, the XmlMapper needs to be called to write values to the XMLStreamWriter object - the same as if we were writing to any other Writer:

StringWriter stringWriter = new StringWriter();
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
XMLStreamWriter sw = xmlOutputFactory.createXMLStreamWriter(stringWriter);

XmlMapper mapper = new XmlMapper();

sw.writeStartDocument();
sw.writeStartElement("root");

mapper.writeValue(sw, employeeBean);
sw.writeComment("Some insightful commentary here");
sw.writeEndElement();
sw.writeEndDocument();

This will produce the following XML:

<?xml version='1.0' encoding='UTF-8'?>
<root>
<employee _id="12345">
<name>Graham</name>
<type>Developer</type>
</employee>
<!--Some insightful commentary here-->
</root>

Here, the XML Prolog, root element, and the comment - are not produced by Jackson XML, but everything inside the EmployeeBean element is.

Consuming XML
The opposite of this is also possible - deserializing a Java bean from the middle of an XMLStreamReader.

This can be especially useful if we only care to have Java bean representations for data in the middle of a larger object - for example, if we are parsing an Atom wrapper around the data we are interested in.

In order to do this, the XmlMapper needs to be called to read values from the XMLStreamReader object - the same as if we were reading from any other Reader.

Let's have a look at a simple example. The following Java code will consume the XML generated above into an EmployeeBeen instance:

XMLInputFactory f = XMLInputFactory.newFactory();
XMLStreamReader sr = f.createXMLStreamReader(new FileInputStream(inputFile));

XmlMapper mapper = new XmlMapper();
sr.next(); // to point to <root>
sr.next(); // to point to root-element under root
EmployeeBeen employee = mapper.readValue(sr, EmployeeBeen.class);
sr.close();

Limitations of the Jackson XML Module
The XML module in Jackson is by no means designed to be an exact replacement for JAXB. There are certain constructs that will work subtly differently between JAXB and Jackson, and there is no guarantee that Jackson will produce identical XML to JAXB.

Note that, unlike with JSON, the outermost object must be a bean type - it can not be a primitive or wrapper type, an enumeration, or a collection. This is a direct result of how XML works - there's no way in XML to represent such a top-level value.

By default, Jackson will always use a wrapper element for collections, which is also different to how JAXB works. This is the major way that the XML produced by Jackson is not compatible with the XML produced by JAXB. Of course, the behavior can be configured, using the JacksonXmlElementWrapper annotation for one field or the setDefaultUseWrapper configuration setting on the XmlMapper globally.

Jackson also has no support for working with specific XML Schemas. It's designed for writing Java Beans first, rather than generating the Java code from pre-existing schemas. Note that this can be solved to an extent by using the JAXB annotation support and generating the beans using the standard xjc tool.

Equally, it has no support for some of the more advanced XML tools - such as XPath or XSLT. If we need this level of support then we should instead use a more full-featured XML solution.

Usage on Android
In the mobile space, Jackson XML works perfectly well on Android. However, the StAX API is not included in the Android JVM, so it needs to instead be bundled manually.

If we're using the Woodstox XML library that Jackson XML depends on by default - there's nothing extra to be done. If, however, we're using an alternative library - then we might need to add that dependency manually:

<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency</span>

And for Gradle:

compile "javax.xml.stream:stax-api:jar:1.0-2"

Summary
If you're looking for a mature, flexible way of supporting and working with both JSON and XML for the same data, the Jackson XML module is a fantastic library to leverage. It's not only a solid way to go on its own, but it also has the added benefit of being able to mostly reuse the same configuration for both XML as well as JSON.

Typically, this has to be handled using two different libraries with entirely separate configurations.

Finally, beyond flexibility and ease-of-use, the Jackson team has historically placed a strong emphasis on performance. And given that marshalling and unmarshalling of data is a large part of most web applications, choosing the right library to handle all of that work is critical. That, plus a performance monitoring tool such as Retrace will allow you to get the most out of your app.

The post Solving the XML Problem with Jackson appeared first on Stackify.

Read the original blog entry...

More Stories By Stackify Blog

Stackify offers the only developers-friendly solution that fully integrates error and log management with application performance monitoring and management. Allowing you to easily isolate issues, identify what needs to be fixed quicker and focus your efforts – Support less, Code more. Stackify provides software developers, operations and support managers with an innovative cloud based solution that gives them DevOps insight and allows them to monitor, detect and resolve application issues before they affect the business to ensure a better end user experience. Start your free trial now stackify.com

@ThingsExpo Stories
Nordstrom is transforming the way that they do business and the cloud is the key to enabling speed and hyper personalized customer experiences. In his session at 21st Cloud Expo, Ken Schow, VP of Engineering at Nordstrom, discussed some of the key learnings and common pitfalls of large enterprises moving to the cloud. This includes strategies around choosing a cloud provider(s), architecture, and lessons learned. In addition, he covered some of the best practices for structured team migration an...
Recently, WebRTC has a lot of eyes from market. The use cases of WebRTC are expanding - video chat, online education, online health care etc. Not only for human-to-human communication, but also IoT use cases such as machine to human use cases can be seen recently. One of the typical use-case is remote camera monitoring. With WebRTC, people can have interoperability and flexibility for deploying monitoring service. However, the benefit of WebRTC for IoT is not only its convenience and interopera...
SYS-CON Events announced today that Synametrics Technologies will exhibit at SYS-CON's 22nd International Cloud Expo®, which will take place on June 5-7, 2018, at the Javits Center in New York, NY. Synametrics Technologies is a privately held company based in Plainsboro, New Jersey that has been providing solutions for the developer community since 1997. Based on the success of its initial product offerings such as WinSQL, Xeams, SynaMan and Syncrify, Synametrics continues to create and hone inn...
Digital Transformation (DX) is not a "one-size-fits all" strategy. Each organization needs to develop its own unique, long-term DX plan. It must do so by realizing that we now live in a data-driven age, and that technologies such as Cloud Computing, Big Data, the IoT, Cognitive Computing, and Blockchain are only tools. In her general session at 21st Cloud Expo, Rebecca Wanta explained how the strategy must focus on DX and include a commitment from top management to create great IT jobs, monitor ...
The 22nd International Cloud Expo | 1st DXWorld Expo has announced that its Call for Papers is open. Cloud Expo | DXWorld Expo, to be held June 5-7, 2018, at the Javits Center in New York, NY, brings together Cloud Computing, Digital Transformation, Big Data, Internet of Things, DevOps, Machine Learning and WebRTC to one location. With cloud computing driving a higher percentage of enterprise IT budgets every year, it becomes increasingly important to plant your flag in this fast-expanding busin...
"Digital transformation - what we knew about it in the past has been redefined. Automation is going to play such a huge role in that because the culture, the technology, and the business operations are being shifted now," stated Brian Boeggeman, VP of Alliances & Partnerships at Ayehu, in this SYS-CON.tv interview at 21st Cloud Expo, held Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA.
In his session at 21st Cloud Expo, Raju Shreewastava, founder of Big Data Trunk, provided a fun and simple way to introduce Machine Leaning to anyone and everyone. He solved a machine learning problem and demonstrated an easy way to be able to do machine learning without even coding. Raju Shreewastava is the founder of Big Data Trunk (www.BigDataTrunk.com), a Big Data Training and consulting firm with offices in the United States. He previously led the data warehouse/business intelligence and B...
Cloud Expo | DXWorld Expo have announced the conference tracks for Cloud Expo 2018. Cloud Expo will be held June 5-7, 2018, at the Javits Center in New York City, and November 6-8, 2018, at the Santa Clara Convention Center, Santa Clara, CA. Digital Transformation (DX) is a major focus with the introduction of DX Expo within the program. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive ov...
A strange thing is happening along the way to the Internet of Things, namely far too many devices to work with and manage. It has become clear that we'll need much higher efficiency user experiences that can allow us to more easily and scalably work with the thousands of devices that will soon be in each of our lives. Enter the conversational interface revolution, combining bots we can literally talk with, gesture to, and even direct with our thoughts, with embedded artificial intelligence, whic...
Product connectivity goes hand and hand these days with increased use of personal data. New IoT devices are becoming more personalized than ever before. In his session at 22nd Cloud Expo | DXWorld Expo, Nicolas Fierro, CEO of MIMIR Blockchain Solutions, will discuss how in order to protect your data and privacy, IoT applications need to embrace Blockchain technology for a new level of product security never before seen - or needed.
Smart cities have the potential to change our lives at so many levels for citizens: less pollution, reduced parking obstacles, better health, education and more energy savings. Real-time data streaming and the Internet of Things (IoT) possess the power to turn this vision into a reality. However, most organizations today are building their data infrastructure to focus solely on addressing immediate business needs vs. a platform capable of quickly adapting emerging technologies to address future ...
With tough new regulations coming to Europe on data privacy in May 2018, Calligo will explain why in reality the effect is global and transforms how you consider critical data. EU GDPR fundamentally rewrites the rules for cloud, Big Data and IoT. In his session at 21st Cloud Expo, Adam Ryan, Vice President and General Manager EMEA at Calligo, examined the regulations and provided insight on how it affects technology, challenges the established rules and will usher in new levels of diligence arou...
SYS-CON Events announced today that Evatronix will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Evatronix SA offers comprehensive solutions in the design and implementation of electronic systems, in CAD / CAM deployment, and also is a designer and manufacturer of advanced 3D scanners for professional applications.
To get the most out of their data, successful companies are not focusing on queries and data lakes, they are actively integrating analytics into their operations with a data-first application development approach. Real-time adjustments to improve revenues, reduce costs, or mitigate risk rely on applications that minimize latency on a variety of data sources. In his session at @BigDataExpo, Jack Norris, Senior Vice President, Data and Applications at MapR Technologies, reviewed best practices to ...
"Evatronix provides design services to companies that need to integrate the IoT technology in their products but they don't necessarily have the expertise, knowledge and design team to do so," explained Adam Morawiec, VP of Business Development at Evatronix, in this SYS-CON.tv interview at @ThingsExpo, held Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA.
In his Opening Keynote at 21st Cloud Expo, John Considine, General Manager of IBM Cloud Infrastructure, led attendees through the exciting evolution of the cloud. He looked at this major disruption from the perspective of technology, business models, and what this means for enterprises of all sizes. John Considine is General Manager of Cloud Infrastructure Services at IBM. In that role he is responsible for leading IBM’s public cloud infrastructure including strategy, development, and offering m...
No hype cycles or predictions of a gazillion things here. IoT is here. You get it. You know your business and have great ideas for a business transformation strategy. What comes next? Time to make it happen. In his session at @ThingsExpo, Jay Mason, an Associate Partner of Analytics, IoT & Cybersecurity at M&S Consulting, presented a step-by-step plan to develop your technology implementation strategy. He also discussed the evaluation of communication standards and IoT messaging protocols, data...
Recently, REAN Cloud built a digital concierge for a North Carolina hospital that had observed that most patient call button questions were repetitive. In addition, the paper-based process used to measure patient health metrics was laborious, not in real-time and sometimes error-prone. In their session at 21st Cloud Expo, Sean Finnerty, Executive Director, Practice Lead, Health Care & Life Science at REAN Cloud, and Dr. S.P.T. Krishnan, Principal Architect at REAN Cloud, discussed how they built...
22nd International Cloud Expo, taking place June 5-7, 2018, at the Javits Center in New York City, NY, and co-located with the 1st DXWorld Expo will feature technical sessions from a rock star conference faculty and the leading industry players in the world. Cloud computing is now being embraced by a majority of enterprises of all sizes. Yesterday's debate about public vs. private has transformed into the reality of hybrid cloud: a recent survey shows that 74% of enterprises have a hybrid cloud ...
22nd International Cloud Expo, taking place June 5-7, 2018, at the Javits Center in New York City, NY, and co-located with the 1st DXWorld Expo will feature technical sessions from a rock star conference faculty and the leading industry players in the world. Cloud computing is now being embraced by a majority of enterprises of all sizes. Yesterday's debate about public vs. private has transformed into the reality of hybrid cloud: a recent survey shows that 74% of enterprises have a hybrid cloud ...