{"id":135,"date":"2017-12-22T20:55:36","date_gmt":"2017-12-22T20:55:36","guid":{"rendered":"http:\/\/www.canchito-dev.com\/public\/blog\/?p=135"},"modified":"2021-05-02T13:49:08","modified_gmt":"2021-05-02T13:49:08","slug":"spring-boot-and-castor-marshalling-xml-using-o-x-mappers","status":"publish","type":"post","link":"https:\/\/www.canchito-dev.com\/public\/blog\/2017\/12\/22\/spring-boot-and-castor-marshalling-xml-using-o-x-mappers\/","title":{"rendered":"Spring Boot and Castor: Marshalling XML using O\/X mappers"},"content":{"rendered":"<p style=\"text-align: justify;\"><div class=\"perfect-pullquote vcard pullquote-align-full pullquote-border-placement-left\" style=\"font-size:14px !important;\"><blockquote><p style=\"font-size:14px !important;\"><\/p>\n<p style=\"text-align: justify;\">In this post, you will create a Spring project and use Castor XML mapping for\u00a0marshalling\/unmarshalling\u00a0Java\u00a0objects into an XML document.<\/p>\n<p style=\"text-align: justify;\"><\/p><\/blockquote><\/div><\/p>\n<div>\n  <a class=\"donate-with-crypto\"\n     href=\"https:\/\/commerce.coinbase.com\/checkout\/faf64f90-2e80-46ee-aeba-0fde14cbeb46\"><br \/>\n    Buy Me a Coffee<br \/>\n  <\/a><br \/>\n  <script src=\"https:\/\/commerce.coinbase.com\/v1\/checkout.js?version=201807\">\n  <\/script>\n<\/div>\n\n<h1 style=\"text-align: justify;\">Contribute Code<\/h1>\n<p style=\"text-align: justify;\">If you would like to become an active contributor to this project please follow these simple steps:<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"text-align: justify;\">Fork it<\/li>\n<li style=\"text-align: justify;\">Create your feature branch<\/li>\n<li style=\"text-align: justify;\">Commit your changes<\/li>\n<li style=\"text-align: justify;\">Push to the branch<\/li>\n<li style=\"text-align: justify;\">Create new Pull Request<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p class=\"sect1\"><strong>Source code<\/strong> can be downloaded from <a href=\"https:\/\/github.com\/canchito-dev\/marshalling-xml-using-ox-mappers\" target=\"_blank\" rel=\"noopener noreferrer\">github<\/a>.<\/p>\n<h1 class=\"sect1\">What you\u2019ll need<\/h1>\n<ul>\n<li>About 40 minutes<\/li>\n<li>A favorite IDE. In this post, we use:Eclipse IDE for Java DevelopersVersion: Mars.2 Release (4.5.2)<br \/>\nBuild id: 20160218-0600<\/li>\n<li><a href=\"http:\/\/www.oracle.com\/technetwork\/java\/javase\/downloads\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">JDK 7<\/a>\u00a0or later.\u00a0It can be made to work with JDK6, but it will need configuration tweaks. Please check the Spring Boot documentation<\/li>\n<li>An empty Spring project. You can follow the steps from <a href=\"http:\/\/canchito-dev.com\/public\/blog\/2017\/04\/16\/spring-initializer\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/li>\n<\/ul>\n<h1>Introduction<\/h1>\n<p style=\"text-align: justify;\">Sometimes, you might come to need an easy way to read or write an XML file, or a Web service reply in the form of XML. When this happens, <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> comes very handy.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> XML is an XML data binding framework, which deals data in an XML documents as object models which represent that data. This convertion from data to object and viceversa is refered as marshalling\/unmarshalling.<\/p>\n<p style=\"text-align: justify;\">For those who are not familiar with the above teminology, <em>&#8220;marshalling&#8221;<\/em> means converting an object to a stream or sequence of bytes. While <em>&#8220;unmarshalling&#8221;<\/em> means converting a stream to an object.<\/p>\n<p style=\"text-align: justify;\">The conversion between Java object and XML is done by the XML data binding framework, and consists of the following classes:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><code>org.exolab.castor.xml.Marshaller<\/code>: Worker class for converting a Java object to XML document.<\/li>\n<li style=\"text-align: justify;\"><code>org.exolab.castor.xml.Unmarshaller<\/code>: Worker class for converting XML document to Java object.<\/li>\n<li style=\"text-align: justify;\"><code>org.exolab.castor.xml.XMLContext<\/code>: A bootstrap class\u00a0used for configuration of the XML data binding framework and instantiation of the two worker objects.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">There are three modes in which Castor XML can be used for marshalling\/unmarshalling data to and from XML:<\/p>\n<ul>\n<li style=\"text-align: justify;\">introspection mode<\/li>\n<li style=\"text-align: justify;\">mapping mode<\/li>\n<li style=\"text-align: justify;\">descriptor mode (aka generation mode)<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">In this post, we will focus only in the mapping mode, in which a user-defined mapping file is provided to <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> XML. This user-defined mapping file is also an XML that allows the whole or partial definition of a customized mapping between Java classes (and their properties) and XML.<\/p>\n<p style=\"text-align: justify;\">For our example, we will read from an XML file and that same information will be written to a new XML document. We will do it in three samples:<\/p>\n<ul style=\"text-align: justify;\">\n<li style=\"text-align: justify;\">Marshal\/Unmarshal a very simple XML file composed of one root element and several child elements.<\/li>\n<li style=\"text-align: justify;\">Marshal\/Unmarshal a complex XML file composed of\u00a0one root element and several child elements, but one of the child elements is a list of elements.<\/li>\n<li style=\"text-align: justify;\">Marshal\/Unmarshal a complex XML file, but this time using custom field handler.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Even though the project has three examples, we will focus on explaining the most complex example: marshalling\/unmarshalling a complex XML file composed of\u00a0one root element and several child elements, and one of the child elements is a list of elements. During the unmarshalling process, we will use two custom field handler.<\/p>\n<h1 style=\"text-align: justify;\">Project&#8217;s Layout<\/h1>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-linenumbers=\"false\" data-enlighter-theme=\"enlighter\">src\/main\/java\r\n |\r\n +- com\r\n |  +- canchitodev\r\n |     +- example\r\n |        +- MarshallingXmlUsingOxMappersApplication.java\r\n |        +-\u00a0MarshallingXmlUsingOxMappersApplication.java\r\n |        +-\u00a0MarshallingXmlUsingOxMappersApplication.java\r\n |        |\r\n |        +- domain\r\n |        |  +- basic\r\n |        |     +- Platform.java\r\n |        |\r\n |        |  +- complex\r\n |        |     +- Game.java\r\n |        |     +- Games.java\r\n |        |     +- Platform.java\r\n |        |\r\n |        +- field\r\n |           +- handlers\r\n |           |  +- DateHandler.java\r\n |           |  +- PriceHandler.java\r\n |           |\r\n |           |  +- domain\r\n |                 +- Game.java\r\n |                 +- Games.java\r\n |                 +- Platform.java\r\nsrc\/main\/resources\r\n |\r\n +- basic\r\n |  +- basic-example.xml\r\n |  +- basic-mapping.xml\r\n |\r\n +- complex\r\n |  +- complex-example.xml\r\n |  +- complex-mapping.xml\r\n |\r\n +- field-convertion\r\n |  +- field-convertion-example.xml\r\n |  +- field-convertion-mapping.xml\r\n |\r\nsrc\/test\/java\r\n |\r\n +- com\r\n    +- canchitodev\r\n       +- example\r\n          +- MarshallingXmlUsingOxMappersApplicationTests.java\r\n<\/pre>\n<p style=\"text-align: justify;\">So let&#8217;s get started!<\/p>\n<h1>Getting Started<\/h1>\n<p style=\"text-align: justify;\">Once you have created an empty project and imported into your favorite IDE, it is time to modify the <code>pom.xml<\/code> file. If you have not created the project yet, you can follow the steps described in <a href=\"http:\/\/canchito-dev.com\/public\/blog\/2017\/04\/16\/spring-initializer\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<p style=\"text-align: justify;\">Let&#8217;s open the <code>pom.xml<\/code> file,\u00a0and add the dependencies needed by <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a>.<\/p>\n<p style=\"text-align: justify;\">First we add Castor&#8217;s and Xerces&#8217; version, that we will be using, as a property. Notice that we will use the latest current version at the moment of writing this post.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"classic\">&lt;properties&gt;\r\n  &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\r\n  &lt;project.reporting.outputEncoding&gt;UTF-8&lt;\/project.reporting.outputEncoding&gt;\r\n  &lt;java.version&gt;1.8&lt;\/java.version&gt;\r\n  &lt;castor.version&gt;1.4.1&lt;\/castor.version&gt;\r\n  &lt;xerces.version&gt;2.11.0&lt;\/xerces.version&gt;\r\n&lt;\/properties&gt;\r\n<\/pre>\n<p style=\"text-align: justify;\">Next, we add three dependencies (Spring Oxm, Castor &amp; Xerces). But do not remove the previously added ones.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"classic\">&lt;dependencies&gt;\t\t\r\n  &lt;!-- Marshalling XML using O\/X Mappers --&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-oxm&lt;\/artifactId&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;!-- Marshalling XML using O\/X Mappers --&gt;\r\n \r\n  &lt;!-- Castor - Data binding made easy --&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.codehaus.castor&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;castor-xml&lt;\/artifactId&gt;\r\n    &lt;version&gt;${castor.version}&lt;\/version&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.codehaus.castor&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;castor-codegen&lt;\/artifactId&gt;\r\n    &lt;version&gt;${castor.version}&lt;\/version&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;!-- Castor need this --&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;xerces&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;xercesImpl&lt;\/artifactId&gt;\r\n    &lt;version&gt;${xerces.version}&lt;\/version&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;!-- Castor - Data binding made easy --&gt;\r\n&lt;\/dependencies&gt;\r\n<\/pre>\n<p style=\"text-align: justify;\">That&#8217;s it. You have successfully included <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> into your project.<\/p>\n<h1 style=\"text-align: justify;\">Defining the XML<\/h1>\n<p style=\"text-align: justify;\">Here is a representation of the XML file that we will be unmarshalling. You can find it at\u00a0<code>src\/java\/resources\/field-convertion<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;Platform&gt;\r\n  &lt;Name&gt;Playstation 4&lt;\/Name&gt;\r\n  &lt;Developer&gt;Sony Interactive Entertainment&lt;\/Developer&gt;\r\n  &lt;Manufacturer&gt;Sony, Foxconn&lt;\/Manufacturer&gt;\r\n  &lt;ReleaseDate&gt;29\/11\/2013&lt;\/ReleaseDate&gt;\r\n  &lt;Price&gt;\u20ac399.99&lt;\/Price&gt;\r\n  &lt;Website&gt;http:\/\/playstation.com\/ps4\/&lt;\/Website&gt;\r\n  &lt;Games&gt;\r\n    &lt;Game&gt;\r\n      &lt;Name&gt;Uncharted 4: A Thief's End&lt;\/Name&gt;\r\n      &lt;ReleaseDate&gt;10\/05\/2016&lt;\/ReleaseDate&gt;\r\n      &lt;Price&gt;\u20ac35.90&lt;\/Price&gt;\r\n      &lt;URL&gt;https:\/\/www.unchartedthegame.com\/en-us\/&lt;\/URL&gt;\r\n      &lt;Developer&gt;Naughty Dog&lt;\/Developer&gt;\r\n      &lt;Publisher&gt;Sony Computer Entertainment&lt;\/Publisher&gt;\r\n    &lt;\/Game&gt;\r\n    &lt;Game&gt;\r\n      &lt;Name&gt;Batman: Arkham Knight&lt;\/Name&gt;\r\n      &lt;ReleaseDate&gt;23\/06\/2015&lt;\/ReleaseDate&gt;\r\n      &lt;Price&gt;\u20ac17.99&lt;\/Price&gt;\r\n      &lt;URL&gt;https:\/\/www.batmanarkhamknight.com\/&lt;\/URL&gt;\r\n      &lt;Developer&gt;Rocksteady Studios&lt;\/Developer&gt;\r\n      &lt;Publisher&gt;Warner Bros. Interactive Entertainment&lt;\/Publisher&gt;\r\n    &lt;\/Game&gt;\r\n    &lt;Game&gt;\r\n      &lt;Name&gt;Wolfenstein II: The New Colossus&lt;\/Name&gt;\r\n      &lt;ReleaseDate&gt;27\/10\/2017&lt;\/ReleaseDate&gt;\r\n      &lt;Price&gt;\u20ac69.99&lt;\/Price&gt;\r\n      &lt;URL\/&gt;\r\n      &lt;Developer&gt;MachineGames&lt;\/Developer&gt;\r\n      &lt;Publisher&gt;Bethesda Softworks&lt;\/Publisher&gt;\r\n    &lt;\/Game&gt;\r\n  &lt;\/Games&gt;\r\n&lt;\/Platform&gt;<\/pre>\n<h1 style=\"text-align: justify;\">Defining the Java Objects<\/h1>\n<p style=\"text-align: justify;\">As you might remember, we will focus this post on explaining how to\u00a0marshal\/unmarshal a complex XML file composed of\u00a0one root element and several child elements, and one of the child elements is a list of elements. During the unmarshalling process, we will use two custom field handler. All of the Java object that will be used are located in package <code>com.canchitodev.example.field.handlers.domain<\/code>.<\/p>\n<p>Based on the XML, we can see that there are three objects:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">public class Platform {\r\n  \r\n  private String name;\r\n  private String developer;\r\n  private String manufacturer;\r\n  private Date releaseDate;\r\n  private String price;\r\n  private String website;\r\n  private Games games;\r\n\r\n  public Platform() {}\r\n\r\n  public Platform(String name, String developer, String manufacturer, Date releaseDate, String price,\r\n      String website, Games games) {\r\n    this.name = name;\r\n    this.developer = developer;\r\n    this.manufacturer = manufacturer;\r\n    this.releaseDate = releaseDate;\r\n    this.price = price;\r\n    this.website = website;\r\n    this.games = games;\r\n  }\r\n\r\n  \/\/ Getters and Setters\r\n  \/\/ ...\r\n}<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">public class Games {\r\n  \r\n  private List&lt;Game&gt; game;\r\n\r\n  public Games() {\r\n    this.game = new ArrayList&lt;Game&gt;();\r\n  }\r\n\r\n  public Games(List&lt;Game&gt; game) {\r\n    this.game = game;\r\n  }\r\n\r\n  \/\/ Getters and Setters\r\n  \/\/ ...\r\n}<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">public class Game {\r\n\r\n  private String name;\r\n  private Date releaseDate;\r\n  private String price;\r\n  private String url;\r\n  private String developer;\r\n  private String publisher;\r\n  \r\n  public Game() {}\r\n\r\n  public Game(String name, Date releaseDate, String price, String url, String developer, String publisher) {\r\n    this.name = name;\r\n    this.releaseDate = releaseDate;\r\n    this.price = price;\r\n    this.url = url;\r\n    this.developer = developer;\r\n    this.publisher = publisher;\r\n  }\r\n\r\n  \/\/ Getters and Setters\r\n  \/\/ ...\r\n}<\/pre>\n<p>If you pay attention, we have created an object for each XML&#8217;s element that has child elements.<\/p>\n<h1 style=\"text-align: justify;\">Defining the XML Mapping<\/h1>\n<p style=\"text-align: justify;\">In order to use the XML mapping technique, we have to first define the mapping information. This is an XML document, which describes how the properties of the Java Object have to be translated into XML. However, the only contraint for the mapping file is that <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> must\u00a0unambiguously infer from it,\u00a0how a given XML element\/attribute has to be translated into the object model during unmarshalling.<\/p>\n<p>Put into simple words, the XML mapping file explains for each Java object how each of its fields have to be mapped into XML. For this, <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> considers each field as an abstraction of an object&#8217;s property. And by it, it can be accessed via public class variable or using accessor methods (setters and getters). Whenever <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> has to handle an object or XML data which information is not in the mapping file, it will follow its default behavior, by using Java&#8217;s Reflection API to introspect the Java object and determine what to do. Both methods can be simultaneously used.<\/p>\n<p style=\"text-align: justify;\"><strong>Note:<\/strong> <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> can\u2019t handle all possible mappings. In some complex cases, it may be\u00a0necessary to rely on an XSL transformation in conjunction with <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> to adapt the XML\u00a0document to a more friendly format.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;?xml version=\"1.0\"?&gt;\r\n&lt;!DOCTYPE mapping PUBLIC \"-\/\/EXOLAB\/Castor Mapping DTD Version 1.0\/\/EN\" \"http:\/\/castor.org\/mapping.dtd\"&gt;\r\n&lt;mapping&gt;\r\n    &lt;description&gt;\r\n    marshalling-xml-using-ox-mappers: Demo project for marshalling XML using O\/X Mappers with Castos\r\n    &lt;\/description&gt;\r\n    \r\n  \t&lt;class name=\"com.canchitodev.example.field.handlers.domain.Platform\"&gt;   \r\n  \t\t&lt;map-to xml=\"Platform\" \/&gt;\r\n        &lt;field name=\"name\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Name\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"developer\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Developer\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"manufacturer\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Manufacturer\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"releaseDate\" type=\"string\" handler=\"com.canchitodev.example.field.handlers.DateHandler\"&gt;\r\n            &lt;bind-xml name=\"ReleaseDate\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"price\" type=\"string\" handler=\"com.canchitodev.example.field.handlers.PriceHandler\"&gt;\r\n            &lt;bind-xml name=\"Price\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"website\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Website\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"Games\" type=\"com.canchitodev.example.field.handlers.domain.Games\"&gt;\r\n            &lt;bind-xml name=\"Games\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n   \t&lt;\/class&gt;\r\n   \t\r\n   \t&lt;class name=\"com.canchitodev.example.field.handlers.domain.Games\"&gt;   \r\n  \t\t&lt;map-to xml=\"Games\" \/&gt;\r\n        &lt;field name=\"Game\" type=\"com.canchitodev.example.field.handlers.domain.Game\" collection=\"arraylist\"&gt;\r\n        \t&lt;bind-xml name=\"Game\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n   \t&lt;\/class&gt;\r\n   \t\r\n   \t&lt;class name=\"com.canchitodev.example.field.handlers.domain.Game\"&gt;   \r\n  \t\t&lt;map-to xml=\"Game\" \/&gt;\r\n        &lt;field name=\"name\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Name\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"releaseDate\" type=\"string\" handler=\"com.canchitodev.example.field.handlers.DateHandler\"&gt;\r\n            &lt;bind-xml name=\"ReleaseDate\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"price\" type=\"string\" handler=\"com.canchitodev.example.field.handlers.PriceHandler\"&gt;\r\n            &lt;bind-xml name=\"Price\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"url\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"URL\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"developer\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Developer\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n        &lt;field name=\"publisher\" type=\"string\"&gt;\r\n            &lt;bind-xml name=\"Publisher\" node=\"element\" \/&gt;\r\n        &lt;\/field&gt;\r\n   \t&lt;\/class&gt;\r\n     \t\r\n &lt;\/mapping&gt;<\/pre>\n<h1 style=\"text-align: justify;\">Marshalling Behavior<\/h1>\n<p style=\"text-align: justify;\">When using <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a>&#8216;s XML framework, each XML element has to map to a Java class. Everytime <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> marshals an object, it will:<\/p>\n<ul style=\"text-align: justify;\">\n<li style=\"text-align: justify;\">if present, use the mapping information to find the name of the element to create;\u00a0or<\/li>\n<li style=\"text-align: justify;\">create a name using the name of the class, which is its default behavior<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Afterwards, the fields&#8217; information from the mapping file is used to decide the way a particular object&#8217;s property has to converted into into one\u00a0only one of the following:<\/p>\n<ul style=\"text-align: justify;\">\n<li style=\"text-align: justify;\">an attribute<\/li>\n<li style=\"text-align: justify;\">an element<\/li>\n<li style=\"text-align: justify;\">text content<\/li>\n<li style=\"text-align: justify;\">nothing, as we can choose to ignore a particular field<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">If no inforamtion for a given class in found in the mapping XML file, by default, <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> will\u00a0introspect\u00a0the class and apply a set of predefined rules to guess the fields and marshal them. The predefined rules are as follows:<\/p>\n<ul style=\"text-align: justify;\">\n<li style=\"text-align: justify;\">All primitive types, including the primitive type wrappers (Boolean, Short, etc\u2026) are marshalled as attributes.<\/li>\n<li style=\"text-align: justify;\">All other objects are marshalled as elements with either text content or element content.<\/li>\n<\/ul>\n<h1>Unmarshalling Behavior<\/h1>\n<p style=\"text-align: justify;\">During the unmarshalling process, if <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> finds an element, it will try to use the information found in the XML mapping file to determine which object to instantiate. When no mapping information is found, <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> will try to guess the name of the class to instantiate, by using the element&#8217;s name. Afterwards, it will use the\u00a0field information of the mapping file to handle the content of the element.<\/p>\n<p style=\"text-align: justify;\">If no inforamtion for a given class in found in the mapping XML file, by default, <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> will\u00a0introspect\u00a0the class in order to find out if there any method of the form\u00a0getXxxYyy()\/setXxxYyy(&lt;type&gt; x). This accessor will be associated with XML\u00a0element\/attribute named \u2018xxx-yyy\u2019.<\/p>\n<p style=\"text-align: justify;\">Before continuing, it is important to understand the <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a>&#8216;s marshalling\/unmarshalling behavior. <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a>&#8216;s XML framework is very well documented. I recommend reading the following links: (1) <a href=\"https:\/\/castor-data-binding.github.io\/castor\/reference-guide\/reference\/xml\/xml-framework.html\">XML Framework<\/a> and (2) <a href=\"https:\/\/castor-data-binding.github.io\/castor\/reference-guide\/reference\/xml\/xml-mapping.html\">XML Mapping<\/a>.<\/p>\n<h1 style=\"text-align: justify;\">Defining the Marshalling\/Unmarshalling Class<\/h1>\n<p>First we define the class for\u00a0handling marshalling\/unmarshalling of the XML. Notice that this class has both methods.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">public class XMLMarshalUtil {\r\n  \r\n  private Marshaller marshaller;\r\n    private Unmarshaller unmarshaller;\r\n    \r\n    public XMLMarshalUtil() {}\r\n    \r\n    public void setMarshaller(Marshaller marshaller) {\r\n        this.marshaller = marshaller;\r\n    }\r\n    \r\n    public void setUnmarshaller(Unmarshaller unmarshaller) {\r\n        this.unmarshaller = unmarshaller;\r\n    }\r\n\r\n    \/\/Converts Object to XML file\r\n    public void doMarshaling(String filename, Object graph) throws IOException {\r\n    \tOutputStream fos = null;\r\n        try {\r\n        \tfos = new FileOutputStream(filename);\r\n            marshaller.marshal(graph, new StreamResult(fos));\r\n        } finally {\r\n        \tif(fos != null)\r\n        \t\tfos.close();\r\n        }\r\n    }\r\n    \r\n    \/\/Converts Object to XML file\r\n    public void doMarshaling(OutputStream fos, Object graph) throws IOException {\r\n        try {\r\n            marshaller.marshal(graph, new StreamResult(fos));\r\n        } finally {\r\n        \tif(fos != null)\r\n        \t\tfos.close();\r\n        }\r\n    }\r\n    \r\n    \/\/Converts XML to Java Object\r\n    public Object doUnMarshaling(String filename) throws IOException {\r\n        InputStream fis = null;\r\n        try {\r\n            fis = new FileInputStream(filename);\r\n            return unmarshaller.unmarshal(new StreamSource(fis));\r\n        } finally {\r\n        \tif(fis != null)\r\n        \t\tfis.close();\r\n        }\r\n    }\r\n    \r\n    \/\/Converts XML to Java Object\r\n    public Object doUnMarshaling(InputStream fis) throws IOException {\r\n        try {\r\n            return unmarshaller.unmarshal(new StreamSource(fis));\r\n        } finally {\r\n        \tif(fis != null)\r\n        \t\tfis.close();\r\n        }\r\n    }\r\n}<\/pre>\n<p>Second, we define the bean that will return us an instance of the class for manipulating the XML.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Configuration\r\npublic class XMLMarshalBean {\r\n  \r\n  @Bean(name = \"xmlFieldConvertionHandler\")\r\n  public XMLMarshalUtil getXmlFieldConvertionHandler() throws IOException{\r\n    XMLMarshalUtil handler = new XMLMarshalUtil();\r\n    handler.setMarshaller(getXmlFieldConvertionMarshaller());\r\n    handler.setUnmarshaller(getXmlFieldConvertionMarshaller());\r\n    return handler;\r\n  }\r\n  \r\n  @Bean(name = \"xmlFieldConvertionMarshaller\")\r\n  public CastorMarshaller getXmlFieldConvertionMarshaller() throws IOException {\r\n    CastorMarshaller castorMarshaller = new CastorMarshaller();\r\n    castorMarshaller.setCastorProperties(this.castorProperties());\r\n    castorMarshaller.setMappingLocation(\r\n        new ClassPathResource(\"field-convertion\/field-convertion-mapping.xml\")\r\n    );\r\n    return castorMarshaller;\r\n  }\r\n  \r\n  private HashMap&lt;String, String&gt; castorProperties() {\r\n    \tHashMap&lt;String, String&gt; properties = new HashMap&lt;String, String&gt;();\r\n        properties.put(\"org.exolab.castor.indent\", \"true\");\r\n        properties.put(\"org.exolab.castor.debug\", \"true\");\r\n        return properties;\r\n    }\r\n}<\/pre>\n<h1 style=\"text-align: justify;\">Custom Field Handlers<\/h1>\n<p style=\"text-align: justify;\">There are occassions in which we need to deal with data format that are not nativably support by <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a>, or manipulate fields to get the desired output without changing the object model. To deal with this, <a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a> has several interesting interfaces. For this post, we will focus on\u00a0<code>org.exolab.castor.mapping.GeneralizedFieldHandler<\/code> interface. We have implemented two field handlers: (1) for converting a date from English date format to Spanish date format, and (2) for converting the price form Euro (\u20ac) to US Dollars (US$). Both field handlers can be found in package <code>com.canchitodev.example.field.handlers<\/code>.<\/p>\n<p>Here is the class for manipulating dates:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">\/**\r\n * The GeneralizedFieldHandler for the Date class\r\n * A org.exolab.castor.mapping.GeneralizedFieldHandler is an extension of FieldHandler interface where we simply write the conversion \r\n * methods and Castor will automatically handle the underlying get\/set operations. This allows us to re-use the same FieldHandler for \r\n * fields from different classes that require the same conversion.\r\n **\/\r\npublic class DateHandler extends GeneralizedFieldHandler  {\r\n  \r\n  private static final String SOURCE_FORMAT = \"dd\/MM\/yyyy\";\r\n\r\n  \/**\r\n     * Creates a new DateHandler instance\r\n     **\/\r\n  public DateHandler() {\r\n    super();\r\n  }\r\n\r\n  \/**\r\n     * This method is used to convert the value when the getValue method is called. The getValue method will\r\n     * obtain the actual field value from given 'parent' object.\r\n     * \r\n     * This convert method is then invoked with the field's value. The value returned from this method will be\r\n     * the actual value returned by getValue method.\r\n     *\r\n     * @param value the object value to convert after  performing a get operation\r\n     * @return the converted value.\r\n     **\/\r\n  @Override\r\n  public Object convertUponGet(Object value) {\r\n        SimpleDateFormat formatter = new SimpleDateFormat(SOURCE_FORMAT);\r\n    if (value == null) return formatter.format(new Date());\r\n        Date date = (Date)value;\r\n        return formatter.format(date);\r\n  }\r\n\r\n  \/**\r\n     * This method is used to convert the value when the setValue method is called. The setValue method will\r\n     * call this method to obtain the converted value.\r\n     * \r\n     * The converted value will then be used as the value to set for the field.\r\n     *\r\n     * @param value the object value to convert before performing a set operation\r\n     * @return the converted value.\r\n     **\/\r\n  @Override\r\n  public Object convertUponSet(Object value) {\r\n        SimpleDateFormat formatter = new SimpleDateFormat(SOURCE_FORMAT);\r\n        Date date = null;\r\n        try {\r\n            date = formatter.parse((String)value);\r\n        }\r\n        catch(ParseException px) {\r\n            throw new IllegalArgumentException(px.getMessage());\r\n        }\r\n        return date;\r\n  }\r\n\r\n  \/**\r\n     * Returns the class type for the field that this\r\n     * GeneralizedFieldHandler converts to and from. This should be the type that is used in the object model.\r\n     *\r\n     * @return the class type of of the field\r\n     **\/\r\n  @SuppressWarnings(\"rawtypes\")\r\n  @Override\r\n  public Class getFieldType() {\r\n    return Date.class;\r\n  }\r\n  \r\n  \/**\r\n     * Creates a new instance of the object described by this field.\r\n     *\r\n     * @param parent The object for which the field is created\r\n     * @return A new instance of the field's value\r\n     * @throws IllegalStateException This field is a simple type and cannot be instantiated\r\n     **\/\r\n    public Object newInstance(Object parent) throws IllegalStateException{\r\n        \/\/-- Since it's marked as a string...just return null,\r\n        \/\/-- it's not needed.\r\n        return null;\r\n    }\r\n}<\/pre>\n<p>And here is the class for doing the currency convertion:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">\/**\r\n * The GeneralizedFieldHandler for the Date class\r\n * A org.exolab.castor.mapping.GeneralizedFieldHandler is an extension of FieldHandler interface where we simply write the conversion \r\n * methods and Castor will automatically handle the underlying get\/set operations. This allows us to re-use the same FieldHandler for \r\n * fields from different classes that require the same conversion.\r\n **\/\r\npublic class PriceHandler extends GeneralizedFieldHandler  {\r\n  \r\n  private static final String EUROS_SIGN = \"\u20ac\";\r\n  private static final String DOLLARS_SIGN = \"$\";\r\n\r\n  \/**\r\n     * Creates a new DateHandler instance\r\n     **\/\r\n  public PriceHandler() {\r\n    super();\r\n  }\r\n\r\n  \/**\r\n     * This method is used to convert the value when the getValue method is called. The getValue method will\r\n     * obtain the actual field value from given 'parent' object.\r\n     * \r\n     * This convert method is then invoked with the field's value. The value returned from this method will be\r\n     * the actual value returned by getValue method.\r\n     *\r\n     * @param value the object value to convert after  performing a get operation\r\n     * @return the converted value.\r\n     **\/\r\n  @Override\r\n  public Object convertUponGet(Object value) {\r\n    if (value == null) return \"$0.00\";\r\n    \r\n    String price = (String) value;\r\n    price = price.replace(this.EUROS_SIGN, \"\");\r\n    \r\n    Double priceInDollars = (double) Math.round(Double.parseDouble(price) * 1.2);\r\n    return this.DOLLARS_SIGN + priceInDollars.toString();\r\n  }\r\n\r\n  \/**\r\n     * This method is used to convert the value when the setValue method is called. The setValue method will\r\n     * call this method to obtain the converted value.\r\n     * \r\n     * The converted value will then be used as the value to set for the field.\r\n     *\r\n     * @param value the object value to convert before performing a set operation\r\n     * @return the converted value.\r\n     **\/\r\n  @Override\r\n  public Object convertUponSet(Object value) {\r\n    return value;\r\n  }\r\n\r\n  \/**\r\n     * Returns the class type for the field that this\r\n     * GeneralizedFieldHandler converts to and from. This should be the type that is used in the object model.\r\n     *\r\n     * @return the class type of of the field\r\n     **\/\r\n  @SuppressWarnings(\"rawtypes\")\r\n  @Override\r\n  public Class getFieldType() {\r\n    return String.class;\r\n  }\r\n  \r\n  \/**\r\n     * Creates a new instance of the object described by this field.\r\n     *\r\n     * @param parent The object for which the field is created\r\n     * @return A new instance of the field's value\r\n     * @throws IllegalStateException This field is a simple type and cannot be instantiated\r\n     **\/\r\n    public Object newInstance(Object parent) throws IllegalStateException{\r\n        \/\/-- Since it's marked as a string...just return null,\r\n        \/\/-- it's not needed.\r\n        return null;\r\n    }\r\n}<\/pre>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/castor-data-binding.github.io\/castor\/\">Castor<\/a>&#8216;s XML framework is very well documented. I recommend reading the following <a href=\"https:\/\/castor-data-binding.github.io\/castor\/reference-guide\/reference\/xml\/xml-fieldhandlers.html\">link<\/a> in order to understand much better how to write custom field handlers.<\/p>\n<h1 style=\"text-align: justify;\">Let&#8217;s test it!!<\/h1>\n<p style=\"text-align: justify;\">The only thing left to do it to test our code. You can find a jUnit class with three functions for testing our three examples. Just remember to comment the <code>@Ignore<\/code> annotation.<\/p>\n<p style=\"text-align: justify;\"><\/p>\n<h1 style=\"text-align: justify;\">Summary<\/h1>\n<p style=\"text-align: justify;\">In this post, you will learned:<\/p>\n<ul>\n<li>Get familier with Castor XML mapping for reading\/writing XML documents.<\/li>\n<li style=\"text-align: justify;\">Convert an XML document to a Java object using Castor Unmarshaller.<\/li>\n<li style=\"text-align: justify;\">Write Java objects to an XML document using Castor Marshaller.<\/li>\n<li style=\"text-align: justify;\">Writing Castor XML custom field handlers.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Hope you enjoyed this post as much as I did writing it. Please leave your comments and feedback.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, you will create a Spring project and use Castor XML mapping for\u00a0marshalling\/unmarshalling\u00a0Java\u00a0objects into an XML document.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[29,3],"tags":[25,13,26,5,27,28],"class_list":["post-135","post","type-post","status-publish","format-standard","hentry","category-castor","category-spring","tag-castor","tag-java","tag-marshalling","tag-spring","tag-unmarshalling","tag-xml"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p8EwXo-2b","jetpack-related-posts":[{"id":372,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/07\/create-custom-service-tasks-for-flowable\/","url_meta":{"origin":135,"position":0},"title":"Create Custom Service Tasks for Flowable","author":"canchitodev","date":"June 7, 2020","format":false,"excerpt":"In\u00a0this\u00a0tutorial,\u00a0we\u00a0will\u00a0be\u00a0implementing\u00a0a\u00a0custom\u00a0service\u00a0task\u00a0in\u00a0Flowable\u00a0","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Spring Initializr","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=1050%2C600 3x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=1400%2C800 4x"},"classes":[]},{"id":419,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/27\/triggerable-custom-service-tasks-in-flowable\/","url_meta":{"origin":135,"position":1},"title":"Triggerable Custom Service Tasks in Flowable","author":"canchitodev","date":"June 27, 2020","format":false,"excerpt":"In this tutorial, we will be implementing a triggerable custom service task in Flowable. A triggerable task, is one that when it is reached, it is executes its business logic, but once done, it enters a wait state. In order to leave this state, it must be triggered.","rel":"","context":"In &quot;Flowable&quot;","block_context":{"text":"Flowable","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/flowable\/"},"img":{"alt_text":"CANCHITO-DEV: Spring Initializr","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=1050%2C600 3x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/initializr.png?resize=1400%2C800 4x"},"classes":[]},{"id":477,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/06\/27\/use-flowable-apps-with-a-custom-rest-api\/","url_meta":{"origin":135,"position":2},"title":"Use Flowable Apps with a Custom REST API","author":"canchitodev","date":"June 27, 2020","format":false,"excerpt":"In this post, you will learn how configure Flowable's apps to use your custom Spring Boot REST API as a backend engine. All this, in a dockerized environment.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Tomcat Main","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=700%2C400 2x"},"classes":[]},{"id":361,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2019\/07\/22\/spring-cloud-config-server-and-client-side-support-for-externalized-configuration\/","url_meta":{"origin":135,"position":3},"title":"Spring Cloud Config &#8211; Server and client-side support for externalized configuration","author":"canchitodev","date":"July 22, 2019","format":false,"excerpt":"Want to learn how to manage your application configuration in a distributed environment? Learn how to do it with Spring Cloud Config.","rel":"","context":"In &quot;Spring&quot;","block_context":{"text":"Spring","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/spring\/"},"img":{"alt_text":"CANCHITO-DEV: Spring Boot Config - Server and client-side support for externalized configuration","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2019\/07\/Spring-Boot-Config-Server-and-client-side-support-for-externalized-configuration.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2019\/07\/Spring-Boot-Config-Server-and-client-side-support-for-externalized-configuration.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2019\/07\/Spring-Boot-Config-Server-and-client-side-support-for-externalized-configuration.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2019\/07\/Spring-Boot-Config-Server-and-client-side-support-for-externalized-configuration.png?resize=700%2C400 2x"},"classes":[]},{"id":458,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2020\/05\/14\/deploying-flowable-in-a-docker-container-and-mysql-part-2\/","url_meta":{"origin":135,"position":4},"title":"Deploying Flowable in a Docker Container and MySQL (Part 2)","author":"canchitodev","date":"May 14, 2020","format":false,"excerpt":"This is the second part of our \"Deploying Flowable in a Docker Container and MySQL\" series. In this post, you will learn how to deploy Flowable's war files in a container running Tomcat, and connecting to another container running use MySQL database.","rel":"","context":"In &quot;BPM&quot;","block_context":{"text":"BPM","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/bpm\/"},"img":{"alt_text":"CANCHITO-DEV: Tomcat Main","src":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.canchito-dev.com\/public\/blog\/wp-content\/uploads\/2020\/05\/tomcat_main_page-1.png?resize=700%2C400 2x"},"classes":[]},{"id":263,"url":"https:\/\/www.canchito-dev.com\/public\/blog\/2018\/06\/11\/spring-boot-actuator-production-ready-features\/","url_meta":{"origin":135,"position":5},"title":"Spring Boot Actuator &#8211; Production-ready features","author":"canchitodev","date":"June 11, 2018","format":false,"excerpt":"In this post, we\u2019re going to introduce Spring Boot Actuator, by first covering the basics. Afterwards,\u00a0you will create a Spring project and learn how to use, configure and extend this monitoring tool.","rel":"","context":"In &quot;Actuator&quot;","block_context":{"text":"Actuator","link":"https:\/\/www.canchito-dev.com\/public\/blog\/category\/actuator\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/135","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/comments?post=135"}],"version-history":[{"count":26,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/135\/revisions"}],"predecessor-version":[{"id":551,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/posts\/135\/revisions\/551"}],"wp:attachment":[{"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/media?parent=135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/categories?post=135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.canchito-dev.com\/public\/blog\/wp-json\/wp\/v2\/tags?post=135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}