| <!-- | |
| ~ Licensed to the Apache Software Foundation (ASF) under one | |
| ~ or more contributor license agreements. See the NOTICE file | |
| ~ distributed with this work for additional information | |
| ~ regarding copyright ownership. The ASF licenses this file | |
| ~ to you under the Apache License, Version 2.0 (the | |
| ~ "License"); you may not use this file except in compliance | |
| ~ with the License. You may obtain a copy of the License at | |
| ~ | |
| ~ http://www.apache.org/licenses/LICENSE-2.0 | |
| ~ | |
| ~ Unless required by applicable law or agreed to in writing, | |
| ~ software distributed under the License is distributed on an | |
| ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| ~ KIND, either express or implied. See the License for the | |
| ~ specific language governing permissions and limitations | |
| ~ under the License. | |
| --> | |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" | |
| "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | |
| <html> | |
| <head> | |
| <meta http-equiv="content-type" content=""/> | |
| <title>Apache Axis2 JSON and REST with Spring Boot 3 and Apache Tomcat 11 User's Guide</title> | |
| </head> | |
| <body dir="ltr" lang="en-US"> | |
| <a name="_Toc96697849" id="_Toc96697849"></a> | |
| <h1 align="center">Apache Axis2 JSON and REST with Spring Boot 3 and Apache Tomcat 11 User's Guide</h1> | |
| <p>This guide covers writing and deploying JSON-RPC and REST services using | |
| Axis2 with | |
| <a href="https://spring.io/projects/spring-boot">Spring Boot 3</a> and | |
| <a href="https://spring.io/projects/spring-security">Spring Security</a> | |
| on <a href="https://tomcat.apache.org/">Apache Tomcat 11</a>. For the | |
| WildFly equivalent, see the | |
| <a href="json-springboot-userguide.html">WildFly guide</a>. | |
| For the Spring Boot Starter (one-dependency setup), see the | |
| <a href="spring-boot-starter.html">Starter guide</a>.</p> | |
| <p>More docs concerning Axis2 and JSON can be found in the <a href=" | |
| json_support_gson.html">Pure JSON Support documentation</a> and <a href=" | |
| json_gson_user_guide.html">JSON User Guide</a> | |
| </p> | |
| <a name="Introduction"></a> | |
| <h2>Introduction</h2> | |
| <p>This user guide is written based on the Axis2 Standard Binary | |
| Distribution. The Standard Binary Distribution can be directly <a | |
| href="../download.cgi">downloaded</a> or built using | |
| the Source Distribution. If | |
| you choose the latter, then the <a href="installationguide.html">Installation | |
| Guide</a> will instruct you on how to build Axis2 Standard Binary | |
| Distribution using the source.</p> | |
| <p>The source code for this guide provides a pom.xml for an entire demo WAR application built by maven. | |
| </p> | |
| <p>Please note that Axis2 is an open-source effort. If you feel the code | |
| could use some new features or fixes, please get involved and lend us a hand! | |
| The Axis developer community welcomes your participation.</p> | |
| <p>Let us know what you think! Send your feedback to "<a | |
| href="mailto:java-user@axis.apache.org?subject=[Axis2]">java-user@axis.apache.org</a>". | |
| (Subscription details are available on the <a href="../mail-lists.html">Axis2 site</a>.) Kindly | |
| prefix the subject of the mail with [Axis2].</p> | |
| <h2>Differences from the WildFly 32 Guide</h2> | |
| <p>This guide is based on the | |
| <a href="json-springboot-userguide.html">Apache Axis2 JSON and REST with Spring Boot 3 User's Guide</a>, | |
| which targets WildFly 32. The following table summarises all differences:</p> | |
| <table border="1" cellpadding="4"> | |
| <tr><th>Aspect</th><th>WildFly 32 / 39</th><th>Tomcat 11</th></tr> | |
| <tr> | |
| <td><strong>Context root</strong></td> | |
| <td><code>/axis2-json-api</code> (WAR name becomes context root automatically)</td> | |
| <td><code>/</code> (deployed into <code>webapps/ROOT/</code>); base URL is <code>http://localhost:8080/services/...</code></td> | |
| </tr> | |
| <tr> | |
| <td><strong>Deploy method</strong></td> | |
| <td>Copy WAR directory to <code>standalone/deployments/</code>, then <code>touch axis2-json-api.war.dodeploy</code></td> | |
| <td><code>cp -r target/deploy/axis2-json-api.war/* $CATALINA_HOME/webapps/ROOT/</code> then start Tomcat</td> | |
| </tr> | |
| <tr> | |
| <td><strong>WildFly-specific files</strong></td> | |
| <td><code>WEB-INF/jboss-deployment-structure.xml</code>, <code>WEB-INF/jboss-web.xml</code> required</td> | |
| <td>These files must <em>not</em> be present; <code>springbootdemo-tomcat11</code> omits them</td> | |
| </tr> | |
| <tr> | |
| <td><strong>DataSource auto-configuration</strong></td> | |
| <td>WildFly's JPA subsystem suppresses Spring Boot's DataSource auto-config automatically</td> | |
| <td>Must exclude explicitly in <code>@SpringBootApplication</code>: | |
| <code>exclude={DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class}</code></td> | |
| </tr> | |
| <tr> | |
| <td><strong>HTTP/2 configuration</strong></td> | |
| <td>Configured via WildFly subsystem</td> | |
| <td>Requires <code><UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/></code> in <code>server.xml</code> HTTPS connector; Java 9+ ALPN, no native library needed</td> | |
| </tr> | |
| <tr> | |
| <td><strong>JSON request format</strong></td> | |
| <td colspan="2">Identical for both servers: <code>{"methodName":[{"paramName":{...}}]}</code></td> | |
| </tr> | |
| </table> | |
| <p>All sample source code for this guide is located in | |
| the <b>"modules/samples/userguide/src/springbootdemo-tomcat11"</b> directory of <a | |
| href="../download.cgi">Axis2 standard binary distribution</a>.</p> | |
| <h2>See Also: Axis2/C 2.0.0</h2> | |
| <p> | |
| <a href="https://github.com/apache/axis-axis2-c-core/blob/master/docs/userguide/json-httpd-h2-userguide.md">Axis2/C 2.0.0</a> | |
| is in release vote and expected to ship around the same time as Axis2/Java 2.0.1. It provides | |
| equivalent services (BigDataH2, Login, TestWS) implemented in native C with Apache httpd and mod_h2. | |
| For most Java users this is of no interest. For those who need maximum throughput or minimal memory | |
| footprint, native C achieves 240MB peak for a 50MB JSON payload versus JVM heap overhead, and | |
| 26 MB/s JSON throughput with zero warm-up time. | |
| </p> | |
| <p> | |
| The performance headroom is sufficient to run the full HTTP/2 service stack on Android — the | |
| <a href="https://github.com/apache/axis-axis2-c-core/blob/master/docs/HTTP2_ANDROID.md">Axis2/C Android guide</a> | |
| covers a camera control service that uses this approach. | |
| This is a notable milestone: the previous Axis2/C release was 1.6 in 2009. | |
| </p> | |
| <h2>HTTP/2 Transport</h2> | |
| <p>Axis2's HTTP/2 support is integrated into the serialization pipeline — | |
| the <a href="json-streaming-formatter.html">streaming JSON formatter</a> | |
| flushes every 64 KB, producing HTTP/2 DATA frames during serialization, | |
| not after. This keeps server memory flat regardless of response size. | |
| For configuration details, see the | |
| <a href="http2-transport-additions.html">HTTP/2 Transport documentation</a> | |
| and the <a href="http2-integration-guide.html">HTTP/2 overview</a>.</p> | |
| <p>See also: <a href="openapi-rest-userguide.html">OpenAPI REST User Guide</a> | |
| for auto-generated API documentation.</p> | |
| <a name="tomcat11-http2"></a> | |
| <h2>Enabling HTTP/2 on Tomcat 11</h2> | |
| <p>Tomcat 11 supports HTTP/2 via NIO2 with Java 9+ ALPN — no native (APR) library is required. | |
| To enable HTTP/2, update the HTTPS connector in <code>$CATALINA_HOME/conf/server.xml</code>:</p> | |
| <pre> | |
| <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" | |
| maxThreads="200" SSLEnabled="true"> | |
| <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> | |
| <SSLHostConfig> | |
| <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" | |
| type="RSA" /> | |
| </SSLHostConfig> | |
| </Connector> | |
| </pre> | |
| <p>The <code><UpgradeProtocol></code> element activates HTTP/2 with ALPN negotiation. | |
| Clients that do not support HTTP/2 automatically fall back to HTTP/1.1 over TLS.</p> | |
| <p>To generate a self-signed keystore for development:</p> | |
| <pre> | |
| keytool -genkey -alias localhost -keyalg RSA -keysize 2048 \ | |
| -keystore $CATALINA_HOME/conf/localhost-rsa.jks \ | |
| -validity 365 -storepass changeit -keypass changeit \ | |
| -dname "CN=localhost, OU=Dev, O=Test, L=City, ST=State, C=US" | |
| </pre> | |
| <h2>Building and Deploying to Tomcat 11</h2> | |
| <p>Build the WAR with Maven:</p> | |
| <pre> | |
| cd modules/samples/userguide/src/userguide/springbootdemo-tomcat11 | |
| mvn clean install | |
| </pre> | |
| <p>The build produces an exploded WAR directory at | |
| <code>target/deploy/axis2-json-api.war/</code>. Deploy it to Tomcat 11 by | |
| copying the directory contents into the ROOT (or another) context:</p> | |
| <pre> | |
| # Deploy as root context | |
| $CATALINA_HOME/bin/shutdown.sh | |
| rm -rf $CATALINA_HOME/webapps/ROOT/* | |
| cp -r target/deploy/axis2-json-api.war/* $CATALINA_HOME/webapps/ROOT/ | |
| $CATALINA_HOME/bin/startup.sh | |
| </pre> | |
| <p><strong>Note:</strong> The build output is an exploded directory, not a zip | |
| file — do not use <code>jar -xf</code> or treat it as a compressed archive. | |
| The <code>cp -r</code> command is required so that <code>WEB-INF/conf/axis2.xml</code> | |
| and the service <code>.aar</code> files are included in the deployment.</p> | |
| <p>Verify deployment in the Tomcat manager or by checking the logs:</p> | |
| <pre> | |
| tail -f $CATALINA_HOME/logs/catalina.out | |
| </pre> | |
| <p>You should see the Spring Boot application context starting and Axis2 servlet registering | |
| without errors. Because the contents are deployed into <code>webapps/ROOT/</code>, the context | |
| root is <code>/</code> — service URLs begin with <code>http://localhost:8080/services/...</code>, | |
| <em>not</em> <code>/axis2-json-api/services/...</code> as on WildFly.</p> | |
| <h2>Getting Started</h2> | |
| <p>This user guide explains how to write and deploy a | |
| new JSON and REST based Web Service using Axis2, and how to invoke a Web Service client using JSON with Curl. | |
| </p> | |
| <p>All the sample code mentioned in this guide is located in | |
| the <b>"modules/samples/userguide/src/springbootdemo-tomcat11"</b> directory of <a | |
| href="../download.cgi">Axis2 standard binary | |
| distribution</a>.</p> | |
| <p> | |
| This guide supplies a pom.xml for building an exploded WAR with Spring Boot 3 - | |
| however this WAR does not have an embedded web server such as Tomcat. | |
| </p> | |
| <p> | |
| Testing was carried out on Apache Tomcat 11.0.20 with OpenJDK 21 and OpenJDK 25, by installing the WAR in its app server. | |
| </p> | |
| <p>Please deploy the result of the maven build via 'mvn clean install', axis2-json-api.war, into your servlet container and ensure that it installs without any errors.</p> | |
| <h2>Creating secure Web Services</h2> | |
| <p> | |
| Areas out of scope for this guide are JWT and JWE for token generation and validation, | |
| since they require elliptic curve cryptography. A sample token that is not meant for | |
| production is generated in this demo - with the intent that the following standards | |
| should be used in its place. This demo merely shows a place to implement these | |
| standards. | |
| </p> | |
| <p> | |
| https://datatracker.ietf.org/doc/html/rfc7519 | |
| </p> | |
| <p> | |
| https://datatracker.ietf.org/doc/html/rfc7516 | |
| </p> | |
| <p> | |
| Tip: com.nimbusds is recommended as an open-source Java implementation of these | |
| standards, for both token generation and validation. | |
| </p> | |
| <p> | |
| DB operations are also out of scope. There is a minimal DAO layer for authentication. | |
| Very limited credential validation is done. | |
| </p> | |
| <p> | |
| The NoOpPasswordEncoder Spring class included in this guide is meant for demos | |
| and testing only. Do not use this code as is in production. | |
| </p> | |
| <p> | |
| This guide provides three JSON based web services: LoginService, TestwsService, and the new | |
| <strong>BigDataH2Service</strong> which demonstrates HTTP/2 transport capabilities for enterprise | |
| big data processing. | |
| </p> | |
| <h3>BigDataH2Service - HTTP/2 Big Data Processing Service</h3> | |
| <p>The BigDataH2Service showcases HTTP/2 transport benefits for large JSON datasets:</p> | |
| <ul> | |
| <li><strong>Large Dataset Processing:</strong> Handles JSON datasets from small (1MB) to enterprise-scale (100MB+)</li> | |
| <li><strong>Automatic Optimization:</strong> Selects optimal processing mode based on dataset size</li> | |
| <li><strong>Memory Efficiency:</strong> Streaming and chunked processing for memory-constrained environments</li> | |
| <li><strong>Performance Metrics:</strong> Built-in monitoring for throughput, memory usage, and HTTP/2 optimization indicators</li> | |
| <li><strong>Security Validation:</strong> OWASP ESAPI input validation and HTTPS-only enforcement</li> | |
| </ul> | |
| <p> | |
| The login, if successful, will return a simple token not meant for anything beyond demos. | |
| The intent of this guide is to show a place that the JWT and JWE standards can be | |
| implemented. | |
| </p> | |
| <p> | |
| Axis2 JSON support is via POJO Objects. LoginRequest and LoginResponse are coded in the LoginService as the names would indicate. A flag in the supplied axis2.xml file, enableJSONOnly, | |
| disables Axis2 functionality not required for JSON and sets up the server to expect JSON. | |
| <h3>Security Benefits of enableJSONOnly</h3> | |
| <p>The <strong>enableJSONOnly</strong> parameter provides significant security hardening by enforcing strict JSON-only processing:</p> | |
| <ul> | |
| <li><strong>Content-Type Enforcement:</strong> Rejects requests without <code>"Content-Type: application/json"</code> header, preventing content-type confusion attacks</li> | |
| <li><strong>Protocol Restriction:</strong> Disables SOAP, XML, and other message formats that could introduce XXE (XML External Entity) vulnerabilities</li> | |
| <li><strong>Attack Surface Reduction:</strong> Eliminates unused Axis2 functionality, reducing potential security vulnerabilities in XML parsing and SOAP processing</li> | |
| <li><strong>Input Validation:</strong> Ensures only well-formed JSON payloads are accepted, preventing malformed request attacks</li> | |
| <li><strong>Request Filtering:</strong> Blocks non-JSON requests at the transport level, providing an additional security barrier</li> | |
| </ul> | |
| <p><strong>Security Best Practice:</strong> When combined with HTTPS-only enforcement (required for HTTP/2), | |
| enableJSONOnly creates a secure, hardened API endpoint that accepts only authenticated JSON requests over encrypted connections.</p> | |
| </p> | |
| <p> | |
| Also provided is a test service, TestwsService. It includes two POJO Objects as would | |
| be expected, TestwsRequest and TestwsResponse. This service attempts to return | |
| a String with some Javascript, that is HTML encoded by Axis2 and thereby | |
| eliminating the possibility of a Javascript engine executing the response i.e. a | |
| reflected XSS attack. | |
| </p> | |
| <p> | |
| Concerning Spring Security and Spring Boot 3, the Axis2Application class that | |
| extends <a href="https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.html">SpringBootServletInitializer</a> as typically | |
| done utilizes a List of <a href="https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/SecurityFilterChain.html">SecurityFilterChain</a> as a | |
| binary choice; A login url will match, otherwise invoke JWTAuthenticationFilter. All URL's | |
| to other services besides the login, will proceed after JWTAuthenticationFilter verifies the | |
| token. | |
| </p> | |
| <p> | |
| The JWTAuthenticationFilter class expects a token from the web services JSON client in | |
| the form of "Authorization: Bearer mytoken". | |
| </p> | |
| <p> | |
| The Axis2WebAppInitializer class supplied in this guide, is the config class | |
| that registers AxisServlet with Spring Boot 3. | |
| </p> | |
| <p> | |
| Axis2 web services are installed via a WEB-INF/services directory that contains | |
| files with an .aar extension for each service. These aar files are similar to | |
| jar files, and contain a services.xml that defines the web service behavior. | |
| The pom.xml supplied in this guide generates these files. | |
| </p> | |
| <p> | |
| Tip: don't expose methods in your web services that are not meant to be exposed, | |
| such as getters and setters. Axis2 determines the available methods by reflection. | |
| For JSON, the message name at the start of the JSON received by the Axis2 server | |
| defines the Axis2 operation to invoke. It is recommended that only one method per | |
| class be exposed as a starting point. The place to add method exclusion is the | |
| services.xml file: | |
| </p> | |
| <pre> | |
| <excludeOperations> | |
| <operation>setMyVar</operation> | |
| </excludeOperations> | |
| </pre> | |
| <p> | |
| The axis2.xml file can define <a href= "https://github.com/google/gson">GSON</a> or <a href= "https://github.com/square/moshi">Moshi</a> as the JSON engine. GSON was the original | |
| however development has largely ceased. Moshi is very similar and is widely considered | |
| to be the superior implementation in terms of performance. GSON will likely continue to | |
| be supported in Axis2 because it is helpful to have two JSON implementations to compare | |
| with for debugging. | |
| </p> | |
| <p> | |
| JSON based web services in the binary distribution of axis2.xml are not enabled by | |
| default. See the supplied axis2.xml of this guide, and note the places were it has | |
| "moshi". Just replace "moshi" with "gson" as a global search and replace to switch to | |
| GSON. | |
| </p> | |
| <p> | |
| Axis2 web services that are JSON based must be invoked from a client that sets an | |
| HTTP header as "Content-Type: application/json". In order for axis2 to properly | |
| handle JSON requests, this header behavior needs to be defined in the file | |
| WEB-INF/conf/axis2.xml. | |
| </p> | |
| <pre> | |
| <message name="requestMessage"> | |
| <messageFormatter contentType="application/json" | |
| class="org.apache.axis2.json.moshi.JsonFormatter"/> | |
| </pre> | |
| <p> | |
| Other required classes for JSON in the axis2.xml file include JsonRpcMessageReceiver, | |
| JsonInOnlyRPCMessageReceiver, JsonBuilder, JSONBasedDefaultDispatcher and JSONMessageHandler. | |
| </p> | |
| <h2>HTTP/2 Transport Configuration</h2> | |
| <p>To enable HTTP/2 transport for enterprise big data processing, add the following transport | |
| sender configuration to your axis2.xml file:</p> | |
| <pre> | |
| <transportSender name="h2" | |
| class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"> | |
| <parameter name="PROTOCOL">HTTP/2.0</parameter> | |
| <parameter name="maxConcurrentStreams">100</parameter> | |
| <parameter name="initialWindowSize">2097152</parameter> | |
| <parameter name="serverPushEnabled">false</parameter> | |
| <parameter name="connectionTimeout">30000</parameter> | |
| <parameter name="responseTimeout">300000</parameter> | |
| <parameter name="streamingBufferSize">65536</parameter> | |
| </transportSender> | |
| </pre> | |
| <h3>HTTP/2 Configuration Parameters</h3> | |
| <ul> | |
| <li><strong>maxConcurrentStreams:</strong> Maximum concurrent HTTP/2 streams (default: 100)</li> | |
| <li><strong>initialWindowSize:</strong> HTTP/2 flow control window size (default: 64KB, 2MB recommended for large payloads)</li> | |
| <li><strong>connectionTimeout:</strong> Connection establishment timeout in ms (default: 30000)</li> | |
| <li><strong>responseTimeout:</strong> Timeout for large payload processing (default: 300000 = 5 minutes)</li> | |
| <li><strong>streamingBufferSize:</strong> Buffer size for streaming operations (default: 65536 = 64KB)</li> | |
| </ul> | |
| <h3>Client Usage with cURL</h3> | |
| <p> | |
| Invoking the client for a login that returns a token can be done as follows: | |
| </p> | |
| <pre> | |
| curl -v -H "Content-Type: application/json" -X POST --data @login.dat http://localhost:8080/services/loginService | |
| </pre> | |
| <p> | |
| Where the contents of login.dat are: | |
| </p> | |
| <pre> | |
| {"doLogin":[{"arg0":{"email":"user@example.org","credentials":"userguide"}}]} | |
| </pre> | |
| <p> | |
| Response: | |
| </p> | |
| <pre> | |
| {"response":{"status":"OK","token":"95104Rn2I2oEATfuI90N","uuid":"99b92d7a-2799-4b20-b029-9fbd6108798a"}} | |
| </pre> | |
| <p> | |
| Invoking the client for a Test Service that validates a sample token can be done as | |
| follows: | |
| </p> | |
| <pre> | |
| curl -v -H "Authorization: Bearer 95104Rn2I2oEATfuI90N" -H "Content-Type: application/json" -X POST --data @test.dat http://localhost:8080/services/testws' | |
| </pre> | |
| <p> | |
| Where the contents of test.dat are below. arg0 is a var name | |
| and is used by Axis2 as part of its reflection based code: | |
| </p> | |
| <pre> | |
| {"doTestws":[{"arg0":{"messagein":hello}}]} | |
| </pre> | |
| <p> | |
| Response, HTML encoded to prevent XSS. For the results with encoding see src/site/xdoc/docs/json-springboot-tomcat11-userguide.xml. | |
| </p> | |
| <pre> | |
| {"response":{"messageout":"<script xmlns=\"http://www.w3.org/1999/xhtml\">alert('Hello');</script> \">","status":"OK"}} | |
| </pre> | |
| <h2>BigDataH2Service Example</h2> | |
| <p>The BigDataH2Service demonstrates HTTP/2 streaming for large JSON payloads:</p> | |
| <pre> | |
| curl -v -H "Authorization: Bearer $TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -X POST \ | |
| --data '{"processBigDataSet":[{"arg0":{"datasetId":"test_001","datasetSize":52428800}}]}' \ | |
| https://localhost:8443/services/BigDataH2Service | |
| </pre> | |
| <p>The service returns processing metrics including throughput (MB/s), | |
| memory usage, and record count. For the | |
| <a href="http2-java-client.html">HTTP/2 Java client</a> example | |
| showing how to stream large responses without buffering, see the | |
| sample code.</p> | |
| </body> | |
| </html> |