| <!DOCTYPE html> |
| <!-- |
| | Generated by Apache Maven Doxia Site Renderer 1.7.4 at 2018-11-16 |
| | Rendered using Apache Maven Fluido Skin 1.6 |
| --> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <meta name="Date-Revision-yyyymmdd" content="20181116" /> |
| <meta http-equiv="Content-Language" content="en" /> |
| <title>Apache Axis2 – New JSON support in Apache Axis2</title> |
| <link rel="stylesheet" href="../css/apache-maven-fluido-1.6.min.css" /> |
| <link rel="stylesheet" href="../css/site.css" /> |
| <link rel="stylesheet" href="../css/print.css" media="print" /> |
| <script type="text/javascript" src="../js/apache-maven-fluido-1.6.min.js"></script> |
| </head> |
| <body class="topBarDisabled"> |
| <div class="container-fluid"> |
| <div id="banner"> |
| <div class="pull-left"><a href="http://www.apache.org/" id="bannerLeft"><img src="http://www.apache.org/images/asf_logo_wide.png" alt="Apache Axis2"/></a></div> |
| <div class="pull-right"><a href=".././" id="bannerRight"><img src="../images/axis.jpg" /></a></div> |
| <div class="clear"><hr/></div> |
| </div> |
| |
| <div id="breadcrumbs"> |
| <ul class="breadcrumb"> |
| <li id="publishDate">Last Published: 2018-11-16<span class="divider">|</span> |
| </li> |
| <li id="projectVersion">Version: 1.7.9<span class="divider">|</span></li> |
| <li class=""><a href="http://www.apache.org" class="externalLink" title="Apache">Apache</a><span class="divider">/</span></li> |
| <li class=""><a href="../index.html" title="Axis2/Java">Axis2/Java</a><span class="divider">/</span></li> |
| <li class="active ">New JSON support in Apache Axis2</li> |
| </ul> |
| </div> |
| <div class="row-fluid"> |
| <div id="leftColumn" class="span2"> |
| <div class="well sidebar-nav"> |
| <ul class="nav nav-list"> |
| <li class="nav-header">Axis2/Java</li> |
| <li><a href="../index.html" title="Home"><span class="none"></span>Home</a> </li> |
| <li><a href="../download.html" title="Downloads"><span class="none"></span>Downloads</a> </li> |
| <li><a href="javascript:void(0)" title="Release Notes"><span class="icon-chevron-down"></span>Release Notes</a> |
| <ul class="nav nav-list"> |
| <li><a href="../release-notes/1.6.1.html" title="1.6.1"><span class="none"></span>1.6.1</a> </li> |
| <li><a href="../release-notes/1.6.2.html" title="1.6.2"><span class="none"></span>1.6.2</a> </li> |
| <li><a href="../release-notes/1.6.3.html" title="1.6.3"><span class="none"></span>1.6.3</a> </li> |
| <li><a href="../release-notes/1.6.4.html" title="1.6.4"><span class="none"></span>1.6.4</a> </li> |
| <li><a href="../release-notes/1.7.0.html" title="1.7.0"><span class="none"></span>1.7.0</a> </li> |
| <li><a href="../release-notes/1.7.1.html" title="1.7.1"><span class="none"></span>1.7.1</a> </li> |
| <li><a href="../release-notes/1.7.2.html" title="1.7.2"><span class="none"></span>1.7.2</a> </li> |
| <li><a href="../release-notes/1.7.3.html" title="1.7.3"><span class="none"></span>1.7.3</a> </li> |
| <li><a href="../release-notes/1.7.4.html" title="1.7.4"><span class="none"></span>1.7.4</a> </li> |
| <li><a href="../release-notes/1.7.5.html" title="1.7.5"><span class="none"></span>1.7.5</a> </li> |
| <li><a href="../release-notes/1.7.6.html" title="1.7.6"><span class="none"></span>1.7.6</a> </li> |
| <li><a href="../release-notes/1.7.7.html" title="1.7.7"><span class="none"></span>1.7.7</a> </li> |
| <li><a href="../release-notes/1.7.8.html" title="1.7.8"><span class="none"></span>1.7.8</a> </li> |
| <li><a href="../release-notes/1.7.9.html" title="1.7.9"><span class="none"></span>1.7.9</a> </li> |
| </ul> |
| </li> |
| <li><a href="../modules/index.html" title="Modules"><span class="none"></span>Modules</a> </li> |
| <li><a href="../tools/index.html" title="Tools"><span class="none"></span>Tools</a> </li> |
| <li class="nav-header">Documentation</li> |
| <li><a href="../docs/toc.html" title="Table of Contents"><span class="none"></span>Table of Contents</a> </li> |
| <li><a href="../docs/installationguide.html" title="Installation Guide"><span class="none"></span>Installation Guide</a> </li> |
| <li><a href="../docs/quickstartguide.html" title="QuickStart Guide"><span class="none"></span>QuickStart Guide</a> </li> |
| <li><a href="../docs/userguide.html" title="User Guide"><span class="none"></span>User Guide</a> </li> |
| <li><a href="../docs/jaxws-guide.html" title="JAXWS Guide"><span class="none"></span>JAXWS Guide</a> </li> |
| <li><a href="../docs/pojoguide.html" title="POJO Guide"><span class="none"></span>POJO Guide</a> </li> |
| <li><a href="../docs/spring.html" title="Spring Guide"><span class="none"></span>Spring Guide</a> </li> |
| <li><a href="../docs/webadminguide.html" title="Web Administrator's Guide"><span class="none"></span>Web Administrator's Guide</a> </li> |
| <li><a href="../docs/migration.html" title="Migration Guide (from Axis1)"><span class="none"></span>Migration Guide (from Axis1)</a> </li> |
| <li class="nav-header">Resources</li> |
| <li><a href="../faq.html" title="FAQ"><span class="none"></span>FAQ</a> </li> |
| <li><a href="../articles.html" title="Articles"><span class="none"></span>Articles</a> </li> |
| <li><a href="http://wiki.apache.org/ws/FrontPage/Axis2/" class="externalLink" title="Wiki"><span class="none"></span>Wiki</a> </li> |
| <li><a href="../refLib.html" title="Reference Library"><span class="none"></span>Reference Library</a> </li> |
| <li><a href="../apidocs/index.html" title="Online Java Docs"><span class="none"></span>Online Java Docs</a> </li> |
| <li class="nav-header">Get Involved</li> |
| <li><a href="../overview.html" title="Overview"><span class="none"></span>Overview</a> </li> |
| <li><a href="../svn.html" title="Checkout the Source"><span class="none"></span>Checkout the Source</a> </li> |
| <li><a href="../mail-lists.html" title="Mailing Lists"><span class="none"></span>Mailing Lists</a> </li> |
| <li><a href="../release-process.html" title="Release Process"><span class="none"></span>Release Process</a> </li> |
| <li><a href="../guidelines.html" title="Developer Guidelines"><span class="none"></span>Developer Guidelines</a> </li> |
| <li><a href="../siteHowTo.html" title="Build the Site"><span class="none"></span>Build the Site</a> </li> |
| <li class="nav-header">Project Information</li> |
| <li><a href="../team-list.html" title="Project Team"><span class="none"></span>Project Team</a> </li> |
| <li><a href="../issue-tracking.html" title="Issue Tracking"><span class="none"></span>Issue Tracking</a> </li> |
| <li><a href="http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/" class="externalLink" title="Source Code"><span class="none"></span>Source Code</a> </li> |
| <li><a href="../thanks.html" title="Acknowledgements"><span class="none"></span>Acknowledgements</a> </li> |
| <li class="nav-header">Apache</li> |
| <li><a href="http://www.apache.org/licenses/LICENSE-2.0.html" class="externalLink" title="License"><span class="none"></span>License</a> </li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html" class="externalLink" title="Sponsorship"><span class="none"></span>Sponsorship</a> </li> |
| <li><a href="http://www.apache.org/foundation/thanks.html" class="externalLink" title="Thanks"><span class="none"></span>Thanks</a> </li> |
| <li><a href="http://www.apache.org/security/" class="externalLink" title="Security"><span class="none"></span>Security</a> </li> |
| </ul> |
| <hr /> |
| <div id="poweredBy"> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a> |
| </div> |
| </div> |
| </div> |
| <div id="bodyColumn" class="span10" > |
| |
| |
| <h1>New JSON support in Apache Axis2</h1> |
| |
| <p>This documentation explains how the existing JSON support in Apache Axis2 have been improved with two new |
| methods named, Native approach and XML stream API based approach. Here it initially explains about the |
| drawbacks of the old JSON support, how to overcome those drawbacks with the new approaches and, how to use |
| those approaches to send pure JSON objects without converting it to any XML representations. XML Stream API |
| based approach addresses the namespace problem with pure JSON support, and provides a good solution for |
| that.</p> |
| |
| |
| <div class="section"> |
| <h2><a name="Introduction"></a>Introduction</h2> |
| |
| |
| <p>Apache Axis2 is an efficient third generation SOAP processing web services engine. JSON (JavaScript |
| Object Notation) is a lightweight data-interchange format and, an alternative for XML which is easily |
| human readable and writable as well as it can be parsed and generated easily for machines.</p> |
| |
| |
| <p>The existing JSON implementation in Apache Axis2/Java supports badgerfish format of the JSON object, |
| which is an XML representation of JSON object. With this approach, it first completely converts the |
| badgerfish JSON string to the relevant XML format in the server side and, treats it as a normal SOAP |
| message. The current JSON implementation also supports Mapped JSON, which is another XML representation |
| of the JSON object, if we set xmlToJsonNamespaceMap parameter in the services.xml file of the service. |
| The main problem with Mapped JSON format is, at the client side it is not aware of the namespaces which |
| is used in server side to validate the request. Therefore with current implementation, it is required |
| to do modifications to the existing services to use this mapped format support. The current JSON |
| implementations of Axis2 are slower than the existing SOAP support too. Therefore the existing JSON |
| support doesn't expose its advantages at all.</p> |
| |
| |
| <p>However this JSON support can be improved to support pure JSON objects without using any format to |
| convert it into a XML, as JSON is a light weighted alternative to XML. Thre are two new approaches |
| have been used with google-gson library, a rich library to convert a JSON string to a Java object |
| and vice-versa, in order to improve the existing JSON support in Apache Axis2/java.</p> |
| |
| |
| <p>Gson[1] is a Java library that can be used to convert Java Objects into their JSON representation. |
| It can be also used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary |
| Java objects including pre-existing objects for which you do not have the source code.</p> |
| |
| |
| <p>There are a few open source projects, capable of converting Java objects into JSON. However, most of |
| them require to place Java annotations in all classes; something that cannot be done if we do not have |
| access to the source code. Most of them also do not fully support the use of Java Generics. Gson has |
| considered both of these facts as very important design goals and, the following are some of the |
| advantages of using Gson to convert JSON into Java objects and vice-versa.</p> |
| |
| |
| <ul> |
| |
| <li>It provides simple toJSON() and fromJSON() methods to convert Java objects into JSON objects and |
| vice-versa.</li> |
| |
| <li>It allows pre-existing unmodifiable objects to be converted into/from JSON objects.</li> |
| |
| <li>It has the extensive support of Java Generics.</li> |
| |
| <li>It allows custom representations for objects.</li> |
| |
| <li>It supports arbitrarily complex objects (with deep inheritance hierarchies and extensive use of |
| generic types).</li> |
| </ul> |
| |
| |
| <p>As mentioned above, these two new approaches have been introduced to overcome the above explained |
| problems in the existing JSON implementation (Badgerfish and Mapped) of Axis2. The first one, the |
| Native approach, has been implemented with completely pure JSON support throughout the axis2 message |
| processing process while with the second approach which is XML stream API based approach, an |
| XMLStreamReader/XMLStreamWriter implementation using google-gson with the help of XMLSchema is being |
| implemented. The detailed description on the two approaches is given out in the next sections of the |
| documentation.</p> |
| </div> |
| |
| <a name="native_approach"></a> |
| <div class="section" id="native_approach"> |
| <h2><a name="Native_Approach"></a>Native Approach</h2> |
| |
| |
| <p>With this approach you can expose your POJO service to accept pure JSON request other than converting to |
| any representation or format. You just need to send a valid JSON string request to the service url and, |
| in the url you should have addressed the operation as well as the service. Because in this scenario Axis2 |
| uses URI based operation dispatcher to dispatch the correct operation. in |
| <a href="json_gson_user_guide.html#native_approach">here</a> you can |
| find the complete user guide for this native approach.</p> |
| |
| |
| <p>The Native approach is being implemented to use pure JSON throughout the axis2 message processing |
| process. In Axis2 as the content-type header is used to specify the type of data in the message body, |
| and depending on the content type, the wire format varies. Therefore, we need to have a mechanism to |
| format the message depending on content type. We know that any kind of message is represented in Axis2 |
| using AXIOM, and when we serialize the message, it needs to be formatted based on content type. |
| MessageFormatters exist to do that job for us. We can specify MessageFormatters along with the content |
| type in axis2.xml. On the other hand, a message coming into Axis2 may or may not be XML, but for it to |
| go through Axis2, an AXIOM element needs to be created. As a result, MessageBuilders are employed to |
| construct the message depending on the content type.</p> |
| |
| |
| <p>After building the message it gets pass through AXIS2 execution chain to execute the message. If the |
| message has gone through the execution chain without having any problem, then the engine will hand over |
| the message to the message receiver in order to do the business logic invocation. After this, it is up |
| to the message receiver to invoke the service and send the response. So according to the Axis2 |
| architecture to accomplish this approach it is required to implement three main components, a |
| MessageBuilder, a MessageReceiver and a MessageFormatter, where in this Native implementation those are |
| JSONBuilder, JSONRPCMessageReceiver and JSONFomatter, to handle the pure JSON request and invoke the |
| service and return a completely pure JSON string as a response. In the builder, it creates and returns |
| a dummy SOAP envelop to process over execution chain, while storing input json stream and a boolean |
| flag IS_JSON_STREAM as a property of input MessageContext. The next one is JSONRPCMessageReceiver which |
| is an extended subclass of RPCMessageReceiver. In here it checks IS_JSON_STREAM property value, if it is |
| 'true' then it processes InputStream stored in input MessageContext, using JsonReader in google-gson API. |
| Then it invokes request service operation by Gson in google-gson API which uses Java reflection to invoke |
| the service. To write the response to wire, it stores the returned object and return java bean type, as |
| properties of output MessageContext. If IS_JSON_STREAM is 'false' or null then it is handed over to its |
| super class RPCMessageReceiver, in order to handle the request. This means, using JSONRPCMessageReceiver |
| as the message receiver of your service you can send pure JSON messages as well as SOAP requests too. |
| There is a JSONRPCInOnly-MessageReceiver which extends RPCInOnlyMessageReceiver class, to handle In-Only |
| JSON requests too. In JSONformatter it gets return object and the java bean type, and writes response as |
| a pure JSON string to the wire using JsonWriter in google-gson API. The native approach doesn’t support |
| namespaces. If you need namespace support with JSON then go through XML Stream API based approach.</p> |
| |
| |
| </div> |
| |
| <a name="xml_stream_api_base_approach"></a> |
| <div class="section" id="xml_stream_api_base_approach"> |
| <h2><a name="XML_Stream_API_Base_Approach"></a>XML Stream API Base Approach</h2> |
| |
| |
| |
| <p> As you can see the native approach can only be used with POJO services but if you need to expose your |
| services which is generated by using ADB or xmlbeans databinding then you need to use this XML Stream |
| API based approach. With this approach you can send pure JSON requests to the relevant services. |
| Similar to the native approach you need to add operation name after the service name to use uri based |
| operation dispatch to dispatch the request operation. |
| <a href="json_gson_user_guide.html#xml_stream_api_base_approach">Here</a> you can see the user guide |
| for this XML Stream API based approach.</p> |
| |
| |
| <p>As mentioned in Native approach, Apache Axis2 uses AXIOM to process XML. If it can be implement a way to |
| represent JSON stream as an AXIOM object which provides relevant XML infoset while processing JSON |
| stream on fly, that would be make JSON, in line with Axis2 architecture and will support the services |
| which have written on top of xmlstream API too.</p> |
| |
| |
| <p>There are a few libraries like jettison , Json-lib etc. which already provide this |
| XMLStreaReader/XMLStreamWriter interfaces for JSON. There is no issue in converting JSON to XML, as we |
| can use jettison for that, but when it comes to XML to JSON there is a problem. How could we identify |
| the XML element which represent JSON array type? Yes we can identify it if there is two or more |
| consecutive XML elements as jettison does, but what happen if the expected JSON array type has only one |
| value? Then there is only one XML element. If we use Json-lib then xml element should have an attribute |
| name called "class" value to identify the type of JSON. As you can see this is not a standard way and |
| we cannot use this with Axis2 as well. Hence we can't use above libraries to convert XML to JSON |
| accurately without distort expected JSON string even it has one value JSON array type.</p> |
| |
| |
| <p>Therefore with this new improvement Axis2 have it's own way to handle incoming JSON requests and |
| outgoing JSON responses. It uses GsonXMLStreamReader and GsonXMLStreamWriter which are implementations |
| of XMLStreamReader/XMLStreamWriter, to handle this requests and responses. To identify expected request |
| OMElement structure and namespace uri, it uses XmlSchema of the request and response operations. With |
| the XmlSchema it can provide accurate XML infoset of the JSON message. To get the relevant XMLSchema |
| for the operation, it uses element qname of the message. At the MessageBuilder level Axis2 doesn't know |
| the element qname hence it can't get the XmlSchema of the operation. To solve this issue Axis2 uses a |
| new handler call JSONMessageHandler, which executes after the RequestURIOperationDispatcher handler. |
| In the MessageBuilder it creates GsonXMLStreamReader parsing JsonReader instance which is created using |
| inputStream and stores it in input MessageContext as a message property and returns a default SOAP |
| envelop. Inside the JSONMessageHandler it checks for this GsonXMLStreamReader property, if it is not |
| null and messageReceiver of the operation is not an instance of JSONRPCMessageReceiver, it gets the |
| element qname and relevant XMLSchema list from the input MessageContext and pass it to |
| GsonXMLStreamReader. After that it creates StAXOMBuilder passing this GsonXMLStreamReader as the |
| XMLStreamReader and get the document element. Finally set this document element as child of default |
| SOAP body. If Axis2 going to process XMLSchema for every request this would be a performance issue. |
| To solve this, Axis2 uses an intermediate representation(XmlNode) of operation XmlSchema list and store |
| it inside the ConfigurationContext with element qname as a property to use it for a next request |
| which will come to the same operation. Hence it only processes XmlSchema only once for each operation.</p> |
| |
| |
| <p>Same thing happens in the JsonFormatter, as it uses GsonXMLStreamWriter to write response to wire and |
| uses intermediate representation to identify the structure of outgoing OMElement. As we know the |
| structure here we can clearly identify expected JSON response. Even expected JSON string have a JSON |
| Array type which has only one value. </p> |
| |
| |
| <p>In addition, XML Stream API based approach supports namespace uri where it get namespaces from the |
| operation XMLSchema and provides it when it is asked. </p> |
| |
| |
| |
| </div> |
| |
| |
| |
| |
| </div> |
| </div> |
| </div> |
| <hr/> |
| <footer> |
| <div class="container-fluid"> |
| <div class="row-fluid"> |
| <p>Copyright ©2004–2018 |
| <a href="https://www.apache.org/">The Apache Software Foundation</a>. |
| All rights reserved.</p> |
| </div> |
| </div> |
| </footer> |
| </body> |
| </html> |