This is an automated email from the ASF dual-hosted git repository. robertlazarski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git
commit d82edc013b0c7dffc4df85aa7c7193209e4a662f Author: Robert Lazarski <[email protected]> AuthorDate: Mon Apr 6 01:48:52 2026 -1000 springbootdemo-tomcat11: port OpenApiServlet, add axis2.version property, drop dead OpenApiController Three related fixes to make OpenAPI endpoints work on Tomcat 11: - Add OpenApiServlet.java (ported from springbootdemo WildFly module): HttpServlet delegating to SwaggerUIHandler for /openapi.json, /openapi.yaml, /swagger-ui — bypasses DispatcherServlet which is not wired in this WAR - Register OpenApiServlet in Axis2WebAppInitializer.addOpenApiServlet() so Tomcat routes GET /openapi.json to the correct handler instead of falling through to HTTPPostOnlyRejectionFilter - Delete dead OpenApiController.java: @GetMapping handlers are never invoked because DispatcherServlet is not configured in this WAR deployment - Add <axis2.version>2.0.1-SNAPSHOT</axis2.version> property and replace two hardcoded version strings in antrun .mar copy tasks with ${axis2.version} Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --- .../src/userguide/springbootdemo-tomcat11/pom.xml | 9 ++ .../configuration/Axis2WebAppInitializer.java | 15 +++- .../configuration/OpenApiController.java | 99 ---------------------- .../springboot/configuration/OpenApiServlet.java | 81 ++++++++++++++++++ 4 files changed, 102 insertions(+), 102 deletions(-) diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml index 47c06b0f9b..92a044730a 100644 --- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml +++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml @@ -42,6 +42,7 @@ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>17</java.version> <spring-boot.version>3.4.3</spring-boot.version> + <axis2.version>2.0.1-SNAPSHOT</axis2.version> </properties> <dependencies> @@ -370,6 +371,10 @@ <include name="axis2.xml"/> </fileset> </copy> + <mkdir dir="${project.build.directory}/deploy/axis2-json-api.war/WEB-INF/modules"/> + <copy file="${settings.localRepository}/org/apache/axis2/axis2-openapi/${axis2.version}/axis2-openapi-${axis2.version}.jar" + tofile="${project.build.directory}/deploy/axis2-json-api.war/WEB-INF/modules/openapi-${axis2.version}.mar" + overwrite="true"/> <unzip src="${project.build.directory}/axis2-json-api-0.0.1-SNAPSHOT.war" dest="${project.build.directory}/exploded"/> <jar jarfile="${project.build.directory}/exploded/WEB-INF/services/Login.aar"> <metainf file="resources-axis2/login_resources/services.xml"/> @@ -385,6 +390,10 @@ <include name="axis2.xml"/> </fileset> </copy> + <mkdir dir="${project.build.directory}/exploded/WEB-INF/modules"/> + <copy file="${settings.localRepository}/org/apache/axis2/axis2-openapi/${axis2.version}/axis2-openapi-${axis2.version}.jar" + tofile="${project.build.directory}/exploded/WEB-INF/modules/openapi-${axis2.version}.mar" + overwrite="true"/> </target> </configuration> <goals> diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java index 38e998b5d5..c7615aefe3 100644 --- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java +++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/Axis2WebAppInitializer.java @@ -51,11 +51,20 @@ public class Axis2WebAppInitializer implements ServletContextInitializer { // Create the 'root' Spring application context AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); - addAxis2Servlet(container, ctx); + addAxis2Servlet(container, ctx); + addOpenApiServlet(container); logger.warn("onStartup() completed ..."); } - - private void addAxis2Servlet(ServletContext container, AnnotationConfigWebApplicationContext ctx) { + + private void addOpenApiServlet(ServletContext container) { + ServletRegistration.Dynamic openApi = container.addServlet( + "OpenApiServlet", new OpenApiServlet()); + openApi.setLoadOnStartup(2); + openApi.addMapping("/openapi.json", "/openapi.yaml", "/swagger-ui"); + logger.warn("OpenApiServlet registered at /openapi.json, /openapi.yaml, /swagger-ui"); + } + + private void addAxis2Servlet(ServletContext container, AnnotationConfigWebApplicationContext ctx) { ServletRegistration.Dynamic dispatcher = container.addServlet( "AxisServlet", new AxisServlet()); diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiController.java b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiController.java deleted file mode 100644 index 1518b36c5c..0000000000 --- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiController.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - */ -package userguide.springboot.configuration; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.apache.axis2.context.ConfigurationContext; -import org.apache.axis2.openapi.OpenApiModule; -import org.apache.axis2.openapi.SwaggerUIHandler; -import org.apache.axis2.transport.http.AxisServlet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -/** - * Routes OpenAPI documentation requests to the Axis2 OpenAPI module handlers. - * - * The axis2-openapi module stores its handlers in ConfigurationContext during - * module init. AxisServlet stores ConfigurationContext in ServletContext under - * the key AxisServlet.CONFIGURATION_CONTEXT ("CONFIGURATION_CONTEXT"). This - * controller bridges Spring MVC routing to those handlers, enabling the standard - * OpenAPI endpoints alongside the Axis2 /services/* path. - * - * Endpoints served: - * GET /openapi.json - OpenAPI 3.0.1 specification (JSON) - * GET /openapi.yaml - OpenAPI 3.0.1 specification (YAML) - * GET /swagger-ui - Interactive Swagger UI documentation page - */ -@Controller -public class OpenApiController { - - private static final Log log = LogFactory.getLog(OpenApiController.class); - - @Autowired - private ServletContext servletContext; - - private SwaggerUIHandler getHandler() { - ConfigurationContext configContext = (ConfigurationContext) - servletContext.getAttribute(AxisServlet.CONFIGURATION_CONTEXT); - if (configContext == null) { - log.warn("AxisServlet ConfigurationContext not found in ServletContext — AxisServlet may not have started yet"); - return null; - } - SwaggerUIHandler handler = OpenApiModule.getSwaggerUIHandler(configContext); - if (handler == null) { - log.warn("OpenAPI module not initialized — ensure axis2-openapi is on the classpath and <module ref=\"openapi\"/> is in axis2.xml"); - } - return handler; - } - - @GetMapping("/openapi.json") - public void openApiJson(HttpServletRequest request, HttpServletResponse response) throws Exception { - SwaggerUIHandler handler = getHandler(); - if (handler == null) { - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "OpenAPI module not available"); - return; - } - handler.handleOpenApiJsonRequest(request, response); - } - - @GetMapping("/openapi.yaml") - public void openApiYaml(HttpServletRequest request, HttpServletResponse response) throws Exception { - SwaggerUIHandler handler = getHandler(); - if (handler == null) { - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "OpenAPI module not available"); - return; - } - handler.handleOpenApiYamlRequest(request, response); - } - - @GetMapping("/swagger-ui") - public void swaggerUi(HttpServletRequest request, HttpServletResponse response) throws Exception { - SwaggerUIHandler handler = getHandler(); - if (handler == null) { - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "OpenAPI module not available"); - return; - } - handler.handleSwaggerUIRequest(request, response); - } -} diff --git a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiServlet.java b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiServlet.java new file mode 100644 index 0000000000..4c6faf999f --- /dev/null +++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiServlet.java @@ -0,0 +1,81 @@ +/* + * 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. + */ +package userguide.springboot.configuration; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.openapi.OpenApiModule; +import org.apache.axis2.openapi.SwaggerUIHandler; +import org.apache.axis2.transport.http.AxisServlet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.IOException; + +/** + * Servlet that serves OpenAPI documentation endpoints by delegating to + * the Axis2 OpenAPI module's SwaggerUIHandler. + * + * Registered directly in Axis2WebAppInitializer at: + * /openapi.json - OpenAPI 3.0.1 specification (JSON) + * /openapi.yaml - OpenAPI 3.0.1 specification (YAML) + * /swagger-ui - Interactive Swagger UI documentation + */ +public class OpenApiServlet extends HttpServlet { + + private static final Log log = LogFactory.getLog(OpenApiServlet.class); + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + String uri = request.getRequestURI(); + log.info("OpenApiServlet.doGet() called for URI: " + uri); + + ConfigurationContext configContext = (ConfigurationContext) + getServletContext().getAttribute(AxisServlet.CONFIGURATION_CONTEXT); + if (configContext == null) { + log.warn("AxisServlet ConfigurationContext not found in ServletContext"); + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "OpenAPI module not available"); + return; + } + + SwaggerUIHandler handler = OpenApiModule.getSwaggerUIHandler(configContext); + if (handler == null) { + log.warn("OpenApiServlet: SwaggerUIHandler not found — ensure openapi module is in WEB-INF/modules"); + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "OpenAPI module not initialized"); + return; + } + + try { + if (uri.endsWith("/openapi.json")) { + handler.handleOpenApiJsonRequest(request, response); + } else if (uri.endsWith("/openapi.yaml")) { + handler.handleOpenApiYamlRequest(request, response); + } else if (uri.contains("/swagger-ui")) { + handler.handleSwaggerUIRequest(request, response); + } else { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + } + } catch (Exception e) { + log.error("OpenApiServlet error handling " + uri + ": " + e.getMessage(), e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + } + } +}
