This is an automated email from the ASF dual-hosted git repository.

wu-sheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-java.git


The following commit(s) were added to refs/heads/main by this push:
     new 67c9afa00c Add mixed-classpath scenario and Tomcat http.headers 
collection (#814)
67c9afa00c is described below

commit 67c9afa00cde91fb5fae6cc5a7d34d88e2579b7e
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Tue Jul 7 15:13:21 2026 +0800

    Add mixed-classpath scenario and Tomcat http.headers collection (#814)
    
    Two related follow-ups to the #812 servlet-commons unification, both about 
HTTP
    request-tag collection on the Tomcat/servlet path.
    
    1. spring-6.x-mixed-servlet-scenario — an end-to-end repro of the #13938 
field
       condition: a Jakarta Spring 6 WAR that ALSO carries 
javax.servlet-api:4.0.1 at
       compile scope, so both javax.servlet.* (from WEB-INF/lib) and 
jakarta.servlet.*
       (from the Tomcat 10.1 container) are loadable in the deployed webapp at 
once. The
       scenario asserts http.headers and http.params are still collected on the 
jakarta
       entry span, proving servlet-commons' runtime instanceof dispatch 
resolves the live
       request under a mixed classpath — previously only covered by the
       HttpRequestWrappersTest unit test. One version by design (the resolution 
is
       version-independent; version compatibility is already covered by 
spring-6.x-scenario).
    
    2. Tomcat http.headers — http.headers was emitted only by the Spring MVC 
plugin, so
       plugin.http.include_http_headers was a no-op for plain servlet apps 
served by the
       Tomcat plugin. Add INCLUDE_HTTP_HEADERS + HTTP_HEADERS_LENGTH_THRESHOLD 
to
       TomcatPluginConfig.Plugin.Http — the shared plugin.http.* namespace 
already used by
       the Spring MVC and HttpClient plugins, so no new config key and no 
agent.config
       change — and collect the configured request headers in 
TomcatInvokeInterceptor,
       guarded no-op when the config is empty. Proven on the dedicated Tomcat 
scenarios,
       where the Tomcat plugin owns the entry span: tomcat-9x (javax, Tomcat 9) 
and
       tomcat-10x (jakarta, Tomcat 10) now carry a mock_header header and a q1 
query param
       on their internal self-call and assert http.headers + http.params, which 
also fills
       the previously-missing jakarta http.params coverage.
---
 .github/workflows/plugins-jdk17-test.1.yaml        |   1 +
 CHANGES.md                                         |   1 +
 .../apm/plugin/tomcat/TomcatInvokeInterceptor.java |  28 ++
 .../apm/plugin/tomcat/TomcatPluginConfig.java      |  14 +
 .../config/expectedData.yaml                       | 379 +++++++++++++++++++++
 .../configuration.yml                              |   8 +-
 .../spring-6.x-mixed-servlet-scenario/pom.xml      | 143 ++++++++
 .../skywalking/apm/testcase/entity/User.java       |  53 +++
 .../testcase/implinterface/TestCaseController.java |  35 ++
 .../testcase/implinterface/TestCaseInterface.java  |  31 ++
 .../apm/testcase/inherit/ChildController.java      |  28 ++
 .../apm/testcase/inherit/ParentController.java     |  32 ++
 .../apm/testcase/restapi/RestCaseController.java   |  77 +++++
 .../resttemplate/RestTemplateController.java       |  85 +++++
 .../apm/testcase/spring3/CaseController.java       |  41 +++
 .../spring3/component/TestComponentBean.java       |  29 ++
 .../testcase/spring3/dao/TestRepositoryBean.java   |  29 ++
 .../testcase/spring3/service/TestServiceBean.java  |  38 +++
 .../src/main/resources/log4j2.xml                  |  30 ++
 .../src/main/webapp/WEB-INF/spring-mvc-servlet.xml |  30 ++
 .../src/main/webapp/WEB-INF/web.xml                |  35 ++
 .../support-version.list}                          |   8 +-
 .../tomcat-10x-scenario/config/expectedData.yaml   |   4 +-
 .../tomcat-10x-scenario/configuration.yml          |   2 +
 .../apm/testcase/tomcat10x/CaseServlet.java        |   5 +-
 .../tomcat-9x-scenario/config/expectedData.yaml    |   4 +-
 .../scenarios/tomcat-9x-scenario/configuration.yml |   2 +
 .../apm/testcase/tomcat9x/CaseServlet.java         |   5 +-
 28 files changed, 1168 insertions(+), 9 deletions(-)

diff --git a/.github/workflows/plugins-jdk17-test.1.yaml 
b/.github/workflows/plugins-jdk17-test.1.yaml
index e4f7144dfd..7738b85f44 100644
--- a/.github/workflows/plugins-jdk17-test.1.yaml
+++ b/.github/workflows/plugins-jdk17-test.1.yaml
@@ -71,6 +71,7 @@ jobs:
       matrix:
         case:
           - spring-6.x-scenario
+          - spring-6.x-mixed-servlet-scenario
           - spring-boot-3.x-scenario
           - struts2.7-scenario
           - resteasy-6.x-scenario
diff --git a/CHANGES.md b/CHANGES.md
index 48310efdab..4daf294f74 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,6 +6,7 @@ Release Notes.
 ------------------
 
 * Fix `plugin.http.include_http_headers` not working on Spring Boot 3.x / 
Jakarta EE (apache/skywalking#13938).
+* Support `plugin.http.include_http_headers` in the Tomcat plugin, collecting 
the configured request headers as the `http.headers` tag on Tomcat entry spans 
(e.g. RESTEasy on Tomcat), consistent with the Spring MVC plugin. Honors the 
shared `plugin.http.http_headers_length_threshold`.
 * Unify the Tomcat plugins into a single `tomcat` plugin (Tomcat 7 - 10) and 
the Jetty server plugins into a single `jetty-server` plugin (Jetty 9 - 11), 
each supporting both `javax.servlet` and `jakarta.servlet`. Breaking change: 
plugin names `tomcat-7.x/8.x` and `tomcat-10.x` are replaced by `tomcat`, and 
`jetty-server-9.x` and `jetty-server-11.x` by `jetty-server`; update 
`plugin.exclude_plugins` if you reference the old names.
 * Add a Jetty 12 server plugin (`jetty-server-12.x`). Jetty 12 removed the 
`HttpChannel` handle target and moved request handling to the async 
`Server#handle(Request, Response, Callback)` core API, so it needs a separate 
plugin from the merged `jetty-server`.
 * Add a Struts 7 plugin (`struts2-7.x`) for Jakarta Struts, whose 
`DefaultActionInvocation` moved to `org.apache.struts2`.
diff --git 
a/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatInvokeInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatInvokeInterceptor.java
index 9cb009199a..8208a2a4c6 100644
--- 
a/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatInvokeInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatInvokeInterceptor.java
@@ -37,8 +37,11 @@ import org.apache.skywalking.apm.util.StringUtil;
 import org.apache.tomcat.util.http.Parameters;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class TomcatInvokeInterceptor implements 
InstanceMethodsAroundInterceptor {
@@ -64,6 +67,10 @@ public class TomcatInvokeInterceptor implements 
InstanceMethodsAroundInterceptor
         if (TomcatPluginConfig.Plugin.Tomcat.COLLECT_HTTP_PARAMS) {
             collectHttpParam(request, span);
         }
+
+        if 
(!CollectionUtil.isEmpty(TomcatPluginConfig.Plugin.Http.INCLUDE_HTTP_HEADERS)) {
+            collectHttpHeaders(request, span);
+        }
     }
 
     @Override
@@ -115,4 +122,25 @@ public class TomcatInvokeInterceptor implements 
InstanceMethodsAroundInterceptor
             Tags.HTTP.PARAMS.set(span, tagValue);
         }
     }
+
+    private void collectHttpHeaders(Request request, AbstractSpan span) {
+        final List<String> headersList = new 
ArrayList<>(TomcatPluginConfig.Plugin.Http.INCLUDE_HTTP_HEADERS.size());
+        TomcatPluginConfig.Plugin.Http.INCLUDE_HTTP_HEADERS.stream()
+            .filter(headerName -> request.getHeaders(headerName) != null)
+            .forEach(headerName -> {
+                Enumeration<String> headerValues = 
request.getHeaders(headerName);
+                List<String> valueList = Collections.list(headerValues);
+                if (!CollectionUtil.isEmpty(valueList)) {
+                    headersList.add(headerName + "=" + valueList);
+                }
+            });
+
+        if (!headersList.isEmpty()) {
+            String tagValue = String.join("\n", headersList);
+            tagValue = 
TomcatPluginConfig.Plugin.Http.HTTP_HEADERS_LENGTH_THRESHOLD > 0 ?
+                StringUtil.cut(tagValue, 
TomcatPluginConfig.Plugin.Http.HTTP_HEADERS_LENGTH_THRESHOLD) :
+                tagValue;
+            Tags.HTTP.HEADERS.set(span, tagValue);
+        }
+    }
 }
diff --git 
a/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatPluginConfig.java
 
b/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatPluginConfig.java
index 0a1d713cf9..8a99337863 100644
--- 
a/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatPluginConfig.java
+++ 
b/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat/TomcatPluginConfig.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.apm.plugin.tomcat;
 
+import java.util.List;
 import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
 
 public class TomcatPluginConfig {
@@ -38,6 +39,19 @@ public class TomcatPluginConfig {
              * for the sake of performance
              */
             public static int HTTP_PARAMS_LENGTH_THRESHOLD = 1024;
+
+            /**
+             * When {@link Http#INCLUDE_HTTP_HEADERS} declares header names, 
this threshold controls the length
+             * limitation of all header values. use negative values to keep 
and send the complete headers.
+             * Note. this config item is added for the sake of performance.
+             */
+            public static int HTTP_HEADERS_LENGTH_THRESHOLD = 2048;
+
+            /**
+             * It controls what header data should be collected, this is for 
security purpose, values must be in lower
+             * case. Shares the {@code plugin.http.include_http_headers} 
config key with the other HTTP server plugins.
+             */
+            public static List<String> INCLUDE_HTTP_HEADERS;
         }
     }
 }
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/config/expectedData.yaml
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000..992a34dafd
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/config/expectedData.yaml
@@ -0,0 +1,379 @@
+# 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.
+segmentItems:
+- serviceName: spring-6.x-mixed-servlet-scenario
+  segmentSize: ge 10
+  segments:
+  - segmentId: not null
+    spans:
+    - operationName: HEAD:/healthCheck
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/healthCheck'}
+      - {key: http.method, value: HEAD}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: 
test.apache.skywalking.apm.testcase.spring3.component.TestComponentBean.componentMethod
+      parentSpanId: 1
+      spanId: 2
+      spanLayer: Unknown
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 93
+      isError: false
+      spanType: Local
+      peer: ''
+      skipAnalysis: 'false'
+    - operationName: 
test.apache.skywalking.apm.testcase.spring3.dao.TestRepositoryBean.doSomeStuff
+      parentSpanId: 1
+      spanId: 3
+      spanLayer: Unknown
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 93
+      isError: false
+      spanType: Local
+      peer: ''
+      skipAnalysis: 'false'
+    - operationName: 
test.apache.skywalking.apm.testcase.spring3.service.TestServiceBean.doSomeBusiness
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Unknown
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 93
+      isError: false
+      spanType: Local
+      peer: ''
+      skipAnalysis: 'false'
+    - operationName: GET:/case/spring3
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/case/spring3'}
+      - {key: http.method, value: GET}
+      - {key: http.headers, value: 'mock_header=[mock_value]'}
+      - {key: http.status_code, value: '200'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 1, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: 'POST:/create/'
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/create/'}
+      - {key: http.method, value: POST}
+      - {key: http.status_code, value: '201'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 2, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: 'GET:/get/{id}'
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/get/1'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 3, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: 'PUT:/update/{id}'
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/update/1'}
+      - {key: http.method, value: PUT}
+      - {key: http.status_code, value: '200'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 4, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: 'DELETE:/delete/{id}'
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/delete/1'}
+      - {key: http.method, value: DELETE}
+      - {key: http.status_code, value: '204'}
+      refs:
+      - {parentEndpoint:  GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 5, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: GET:/inherit/child/test
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/inherit/child/test'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 6, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: GET:/impl/requestmapping
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/impl/requestmapping'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 7, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: 'GET:/impl/restmapping'
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/impl/restmapping'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      refs:
+      - {parentEndpoint: GET:/case/resttemplate, networkAddress: 
'localhost:8080', refType: CrossProcess,
+        parentSpanId: 8, parentTraceSegmentId: not null, 
parentServiceInstance: not
+          null, parentService: spring-6.x-mixed-servlet-scenario, traceId: not 
null}
+      skipAnalysis: 'false'
+  - segmentId: not null
+    spans:
+    - operationName: /spring-6.x-mixed-servlet-scenario/case/spring3
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 12
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: http.method, value: GET}
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/case/spring3'}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/create/
+      parentSpanId: 0
+      spanId: 2
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 13
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/create/'}
+      - {key: http.method, value: POST}
+      - {key: http.status_code, value: '201'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/get/1
+      parentSpanId: 0
+      spanId: 3
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 13
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/get/1'}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/update/1
+      parentSpanId: 0
+      spanId: 4
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 13
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/update/1'}
+      - {key: http.method, value: PUT}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/delete/1
+      parentSpanId: 0
+      spanId: 5
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 13
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/delete/1'}
+      - {key: http.method, value: DELETE}
+      - {key: http.status_code, value: '204'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/inherit/child/test
+      parentSpanId: 0
+      spanId: 6
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 12
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: http.method, value: GET}
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/inherit/child/test'}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/impl/requestmapping
+      parentSpanId: 0
+      spanId: 7
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 12
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: http.method, value: GET}
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/impl/requestmapping'}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: /spring-6.x-mixed-servlet-scenario/impl/restmapping
+      parentSpanId: 0
+      spanId: 8
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 12
+      isError: false
+      spanType: Exit
+      peer: localhost:8080
+      tags:
+      - {key: http.method, value: GET}
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/impl/restmapping'}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
+    - operationName: GET:/case/resttemplate
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 14
+      isError: false
+      spanType: Entry
+      peer: ''
+      tags:
+      - {key: url, value: 
'http://localhost:8080/spring-6.x-mixed-servlet-scenario/case/resttemplate'}
+      - {key: http.method, value: GET}
+      - key: http.params
+        value: |-
+          q1=[v1]
+          chinese=[中文]
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
diff --git a/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/configuration.yml
similarity index 63%
copy from test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
copy to 
test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/configuration.yml
index fac58bdfd1..8ca8d8b42b 100644
--- a/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
+++ b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/configuration.yml
@@ -15,5 +15,9 @@
 # limitations under the License.
 
 type: tomcat
-entryService: 
http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario
-healthCheck: http://localhost:8080/tomcat-10x-scenario/case/healthCheck
+entryService: 
'"http://localhost:8080/spring-6.x-mixed-servlet-scenario/case/resttemplate?q1=v1&chinese=%e4%b8%ad%e6%96%87";'
+healthCheck: 
http://localhost:8080/spring-6.x-mixed-servlet-scenario/healthCheck
+runningMode: with_optional
+withPlugins: apm-spring-annotation-plugin-*.jar;apm-*-6.x-plugin-*.jar
+environment:
+  - CATALINA_OPTS="-Dskywalking.plugin.http.include_http_headers=mock_header 
-Dskywalking.plugin.springmvc.collect_http_params=true"
diff --git a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/pom.xml 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/pom.xml
new file mode 100644
index 0000000000..4cd3b19779
--- /dev/null
+++ b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/pom.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.skywalking</groupId>
+    <artifactId>spring-6.x-mixed-servlet-scenario</artifactId>
+    <version>5.0.0</version>
+
+    <packaging>war</packaging>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <compiler.version>17</compiler.version>
+        <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
+        <test.framework.version>6.0.0</test.framework.version>
+        <test.framework>spring</test.framework>
+    </properties>
+
+    <name>skywalking-spring-6.x-mixed-servlet-scenario</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.14.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.9.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.10.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <version>2.19.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>2.19.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+        <!--
+          The point of this scenario (issue #13938): a Jakarta Spring 6 app 
that ALSO carries the
+          legacy javax.servlet-api transitively. At 'compile' scope this jar 
lands in WEB-INF/lib,
+          so both javax.servlet.* and jakarta.servlet.* are loadable in the 
deployed webapp at once
+          (jakarta from Tomcat 10.1's container libs, javax from WEB-INF/lib - 
Tomcat only skips the
+          jakarta copy, not javax). servlet-commons' runtime instanceof 
dispatch must still resolve
+          the live jakarta request and collect http.headers / http.params. Do 
NOT change the scope
+          to provided - that would remove the mixed classpath and defeat the 
test.
+        -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>spring-6.x-mixed-servlet-scenario</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>3.3.1</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <parameters>true</parameters>
+                    <source>${compiler.version}</source>
+                    <target>${compiler.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>spring-snapshots</id>
+            <url>https://repo.spring.io/snapshot</url>
+        </pluginRepository>
+        <pluginRepository>
+            <id>spring-milestones</id>
+            <url>https://repo.spring.io/milestone</url>
+        </pluginRepository>
+    </pluginRepositories>
+</project>
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/entity/User.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/entity/User.java
new file mode 100644
index 0000000000..e7fb1871e5
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/entity/User.java
@@ -0,0 +1,53 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.entity;
+
+public class User {
+
+    private int id;
+    private String userName;
+
+    public User(int id) {
+        this.id = id;
+    }
+
+    public User(int id, String userName) {
+        this.id = id;
+        this.userName = userName;
+    }
+
+    public User() {
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/implinterface/TestCaseController.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/implinterface/TestCaseController.java
new file mode 100644
index 0000000000..7a95a9318a
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/implinterface/TestCaseController.java
@@ -0,0 +1,35 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.implinterface;
+
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class TestCaseController implements TestCaseInterface {
+
+    @Override
+    public String implRequestMappingAnnotationTestCase() {
+        return "implRequestMappingAnnotationTestCase";
+    }
+
+    @Override
+    public String implRestAnnotationTestCase() {
+        return "implRestAnnotationTestCase";
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/implinterface/TestCaseInterface.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/implinterface/TestCaseInterface.java
new file mode 100644
index 0000000000..4fea97b7b1
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/implinterface/TestCaseInterface.java
@@ -0,0 +1,31 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.implinterface;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RequestMapping("/impl")
+public interface TestCaseInterface {
+    @RequestMapping(path = "/requestmapping")
+    String implRequestMappingAnnotationTestCase();
+
+    @GetMapping("/restmapping")
+    String implRestAnnotationTestCase();
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/inherit/ChildController.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/inherit/ChildController.java
new file mode 100644
index 0000000000..27ddf54c76
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/inherit/ChildController.java
@@ -0,0 +1,28 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.inherit;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/inherit/child")
+public class ChildController extends ParentController {
+
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/inherit/ParentController.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/inherit/ParentController.java
new file mode 100644
index 0000000000..16b928100d
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/inherit/ParentController.java
@@ -0,0 +1,32 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.inherit;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/inherit/parent")
+public class ParentController {
+
+    @RequestMapping("test")
+    public String test(Integer param) {
+        return "parent-a" + param;
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/restapi/RestCaseController.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/restapi/RestCaseController.java
new file mode 100644
index 0000000000..6792ecb712
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/restapi/RestCaseController.java
@@ -0,0 +1,77 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.restapi;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.util.UriComponentsBuilder;
+import test.apache.skywalking.apm.testcase.entity.User;
+
+@RestController
+public class RestCaseController {
+
+    private static final Map<Integer, User> USERS = new 
ConcurrentHashMap<Integer, User>();
+
+    @GetMapping(value = "/get/{id}")
+    @ResponseBody
+    private ResponseEntity<User> getUser(@PathVariable("id") int id) throws 
InterruptedException {
+        User currentUser = new User(id, "a");
+        return ResponseEntity.ok(currentUser);
+    }
+
+    @PostMapping(value = "/create/")
+    @ResponseBody
+    public ResponseEntity<Void> createUser(@RequestBody User user,
+        UriComponentsBuilder ucBuilder) throws InterruptedException {
+        USERS.put(user.getId(), user);
+        HttpHeaders headers = new HttpHeaders();
+        
headers.setLocation(ucBuilder.path("/get/{id}").buildAndExpand(user.getId()).toUri());
+        return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
+    }
+
+    @PutMapping(value = "/update/{id}")
+    @ResponseBody
+    public ResponseEntity<User> updateUser(@PathVariable("id") int id,
+        @RequestBody User user) throws InterruptedException {
+        User currentUser = new User(id, user.getUserName());
+        return ResponseEntity.ok(currentUser);
+    }
+
+    @DeleteMapping(value = "/delete/{id}")
+    @ResponseBody
+    public ResponseEntity<Void> deleteUser(@PathVariable("id") int id) throws 
InterruptedException {
+        User currentUser = USERS.get(id);
+        if (currentUser == null) {
+            return ResponseEntity.noContent().build();
+        }
+        USERS.remove(id);
+        return ResponseEntity.noContent().build();
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/resttemplate/RestTemplateController.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/resttemplate/RestTemplateController.java
new file mode 100644
index 0000000000..62b93ac01a
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/resttemplate/RestTemplateController.java
@@ -0,0 +1,85 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.resttemplate;
+
+import java.io.IOException;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.http.HttpEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+import test.apache.skywalking.apm.testcase.entity.User;
+
+@RestController
+public class RestTemplateController {
+
+    private static final String SUCCESS = "Success";
+
+    private static final Logger LOGGER = 
LogManager.getLogger(RestTemplateController.class);
+
+    private static final String URL = 
"http://localhost:8080/spring-6.x-mixed-servlet-scenario";;
+
+    @RequestMapping("/case/resttemplate")
+    @ResponseBody
+    public String restTemplate() throws IOException {
+        Request request = new Request.Builder().header("mock_header", 
"mock_value").url(URL + "/case/spring3").build();
+        Response response = new OkHttpClient().newCall(request).execute();
+        LOGGER.info(response.toString());
+
+        // Create user
+        HttpEntity<User> userEntity = new HttpEntity<>(new User(1, "a"));
+        new RestTemplate().postForEntity(URL + "/create/", userEntity, 
Void.class);
+
+        // Find User
+        new RestTemplate().getForEntity(URL + "/get/{id}", User.class, 1);
+
+        //Modify user
+        HttpEntity<User> updateUserEntity = new HttpEntity<>(new User(1, "b"));
+        new RestTemplate().put(URL + "/update/{id}", updateUserEntity, 
userEntity.getBody().getId(), 1);
+
+        //Delete user
+        new RestTemplate().delete(URL + "/delete/{id}", 1);
+
+        Request inheritRequest = new Request.Builder().url(URL + 
"/inherit/child/test").build();
+        response = new OkHttpClient().newCall(inheritRequest).execute();
+        LOGGER.info(response.toString());
+
+        Request implRequestMappingRequest = new Request.Builder().url(URL + 
"/impl/requestmapping").build();
+        response = new 
OkHttpClient().newCall(implRequestMappingRequest).execute();
+        LOGGER.info(response.toString());
+
+        Request implRestMappingRequest = new Request.Builder().url(URL + 
"/impl/restmapping").build();
+        response = new 
OkHttpClient().newCall(implRestMappingRequest).execute();
+        LOGGER.info(response.toString());
+
+        return SUCCESS;
+    }
+
+    @RequestMapping("/healthCheck")
+    @ResponseBody
+    public String healthCheck() {
+        return SUCCESS;
+    }
+
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/CaseController.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/CaseController.java
new file mode 100644
index 0000000000..501c691579
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/CaseController.java
@@ -0,0 +1,41 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.spring3;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import test.apache.skywalking.apm.testcase.spring3.service.TestServiceBean;
+
+@Controller
+public class CaseController {
+
+    private static final String SUCCESS = "Success";
+
+    @Autowired
+    private TestServiceBean testServiceBean;
+
+    @RequestMapping(value = "/case/spring3")
+    @ResponseBody
+    public String updateUser() {
+        testServiceBean.doSomeBusiness("test");
+        return SUCCESS;
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/component/TestComponentBean.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/component/TestComponentBean.java
new file mode 100644
index 0000000000..274aaf490e
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/component/TestComponentBean.java
@@ -0,0 +1,29 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.spring3.component;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestComponentBean {
+
+    public String componentMethod(String name) {
+        return name + "-" + "dealWith-component";
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/dao/TestRepositoryBean.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/dao/TestRepositoryBean.java
new file mode 100644
index 0000000000..84f871ef55
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/dao/TestRepositoryBean.java
@@ -0,0 +1,29 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.spring3.dao;
+
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class TestRepositoryBean {
+
+    public String doSomeStuff(String name) {
+        return name + "-dealWithRepository";
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/service/TestServiceBean.java
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/service/TestServiceBean.java
new file mode 100644
index 0000000000..811fe11648
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring3/service/TestServiceBean.java
@@ -0,0 +1,38 @@
+/*
+ * 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 test.apache.skywalking.apm.testcase.spring3.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import test.apache.skywalking.apm.testcase.spring3.dao.TestRepositoryBean;
+import test.apache.skywalking.apm.testcase.spring3.component.TestComponentBean;
+
+@Service
+public class TestServiceBean {
+    @Autowired
+    private TestComponentBean componentBean;
+
+    @Autowired
+    private TestRepositoryBean repositoryBean;
+
+    public void doSomeBusiness(String name) {
+        componentBean.componentMethod(name);
+        repositoryBean.doSomeStuff(name);
+    }
+}
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/resources/log4j2.xml
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..b5cda5ae8a
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_ERR">
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd 
HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="WARN">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml
new file mode 100644
index 0000000000..b8a2885d3e
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/webapp/WEB-INF/spring-mvc-servlet.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"; 
xmlns:context="http://www.springframework.org/schema/context";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:mvc="http://www.springframework.org/schema/mvc";
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                           http://www.springframework.org/schema/context
+                           
http://www.springframework.org/schema/context/spring-context-3.0.xsd
+                           http://www.springframework.org/schema/mvc
+                           
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd";>
+    <context:component-scan 
base-package="test.apache.skywalking.apm.testcase"/>
+    <mvc:annotation-driven/>
+</beans>
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/webapp/WEB-INF/web.xml
 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..e64a37771f
--- /dev/null
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ 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.
+  ~
+  -->
+
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd";
+         version="3.1">
+    <display-name>skywalking-spring-6.x-mixed-servlet-scenario</display-name>
+
+    <servlet>
+        <servlet-name>spring-mvc</servlet-name>
+        
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>spring-mvc</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/support-version.list
similarity index 69%
copy from test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
copy to 
test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/support-version.list
index fac58bdfd1..845ea5eb10 100644
--- a/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
+++ 
b/test/plugin/scenarios/spring-6.x-mixed-servlet-scenario/support-version.list
@@ -14,6 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-type: tomcat
-entryService: 
http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario
-healthCheck: http://localhost:8080/tomcat-10x-scenario/case/healthCheck
+# Single version by design: this scenario tests the mixed javax+jakarta 
CLASSPATH
+# condition (issue #13938), which is resolved by servlet-commons' runtime 
instanceof
+# dispatch and is independent of the Spring version. Version compatibility 
across
+# 6.0/6.1/6.2 is already covered by spring-6.x-scenario. Do NOT expand this 
list.
+6.2.19
diff --git a/test/plugin/scenarios/tomcat-10x-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/tomcat-10x-scenario/config/expectedData.yaml
index dc03590cdd..030fc841ae 100644
--- a/test/plugin/scenarios/tomcat-10x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/tomcat-10x-scenario/config/expectedData.yaml
@@ -34,6 +34,8 @@ segmentItems:
       tags:
       - {key: url, value: 
'http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario'}
       - {key: http.method, value: POST}
+      - {key: http.params, value: 'q1=[v1]'}
+      - {key: http.headers, value: 'mock_header=[mock_value]'}
       - {key: http.status_code, value: "200"}
       refs:
       - {parentEndpoint: 'GET:/tomcat-10x-scenario/case/tomcat-10x-scenario', 
networkAddress: 'localhost:8080',
@@ -55,7 +57,7 @@ segmentItems:
       peer: localhost:8080
       skipAnalysis: false
       tags:
-      - {key: url, value: 
'http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario'}
+      - {key: url, value: 
'http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario?q1=v1'}
       - {key: http.method, value: POST}
       - {key: http.status_code, value: "200"}
     - operationName: GET:/tomcat-10x-scenario/case/tomcat-10x-scenario
diff --git a/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml 
b/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
index fac58bdfd1..f28e57d9e7 100644
--- a/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
+++ b/test/plugin/scenarios/tomcat-10x-scenario/configuration.yml
@@ -17,3 +17,5 @@
 type: tomcat
 entryService: 
http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario
 healthCheck: http://localhost:8080/tomcat-10x-scenario/case/healthCheck
+environment:
+  - CATALINA_OPTS="-Dskywalking.plugin.http.include_http_headers=mock_header 
-Dskywalking.plugin.tomcat.collect_http_params=true"
diff --git 
a/test/plugin/scenarios/tomcat-10x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat10x/CaseServlet.java
 
b/test/plugin/scenarios/tomcat-10x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat10x/CaseServlet.java
index 441f4e0e0b..78da65ec8a 100644
--- 
a/test/plugin/scenarios/tomcat-10x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat10x/CaseServlet.java
+++ 
b/test/plugin/scenarios/tomcat-10x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat10x/CaseServlet.java
@@ -37,7 +37,10 @@ public class CaseServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
-            HttpPost httpPost = new 
HttpPost("http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario";);
+            // Carry a query param and a header so the receiving Tomcat entry 
span (doPost) exercises
+            // the tomcat-plugin's http.params + http.headers collection (see 
configuration.yml).
+            HttpPost httpPost = new 
HttpPost("http://localhost:8080/tomcat-10x-scenario/case/tomcat-10x-scenario?q1=v1";);
+            httpPost.setHeader("mock_header", "mock_value");
             ResponseHandler<String> responseHandler = response -> {
                 HttpEntity entity = response.getEntity();
                 return entity != null ? EntityUtils.toString(entity) : null;
diff --git a/test/plugin/scenarios/tomcat-9x-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/tomcat-9x-scenario/config/expectedData.yaml
index 10bd8bee30..2737cc9ca5 100644
--- a/test/plugin/scenarios/tomcat-9x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/tomcat-9x-scenario/config/expectedData.yaml
@@ -34,6 +34,8 @@ segmentItems:
       tags:
       - {key: url, value: 
'http://localhost:8080/tomcat-9x-scenario/case/tomcat-9x-scenario'}
       - {key: http.method, value: POST}
+      - {key: http.params, value: 'q1=[v1]'}
+      - {key: http.headers, value: 'mock_header=[mock_value]'}
       - {key: http.status_code, value: "200"}
       refs:
       - {parentEndpoint: 'GET:/tomcat-9x-scenario/case/tomcat-9x-scenario', 
networkAddress: 'localhost:8080',
@@ -55,7 +57,7 @@ segmentItems:
       peer: localhost:8080
       skipAnalysis: false
       tags:
-      - {key: url, value: 
'http://localhost:8080/tomcat-9x-scenario/case/tomcat-9x-scenario'}
+      - {key: url, value: 
'http://localhost:8080/tomcat-9x-scenario/case/tomcat-9x-scenario?q1=v1'}
       - {key: http.method, value: POST}
       - {key: http.status_code, value: "200"}
     - operationName: GET:/tomcat-9x-scenario/case/tomcat-9x-scenario
diff --git a/test/plugin/scenarios/tomcat-9x-scenario/configuration.yml 
b/test/plugin/scenarios/tomcat-9x-scenario/configuration.yml
index 523a817486..b345aba8f7 100644
--- a/test/plugin/scenarios/tomcat-9x-scenario/configuration.yml
+++ b/test/plugin/scenarios/tomcat-9x-scenario/configuration.yml
@@ -17,3 +17,5 @@
 type: tomcat
 entryService: http://localhost:8080/tomcat-9x-scenario/case/tomcat-9x-scenario
 healthCheck: http://localhost:8080/tomcat-9x-scenario/case/healthCheck
+environment:
+  - CATALINA_OPTS="-Dskywalking.plugin.http.include_http_headers=mock_header 
-Dskywalking.plugin.tomcat.collect_http_params=true"
diff --git 
a/test/plugin/scenarios/tomcat-9x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat9x/CaseServlet.java
 
b/test/plugin/scenarios/tomcat-9x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat9x/CaseServlet.java
index 9b47be8639..e9dc5969c9 100644
--- 
a/test/plugin/scenarios/tomcat-9x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat9x/CaseServlet.java
+++ 
b/test/plugin/scenarios/tomcat-9x-scenario/src/main/java/org/apache/skywalking/apm/testcase/tomcat9x/CaseServlet.java
@@ -37,7 +37,10 @@ public class CaseServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
-            HttpPost httpPost = new 
HttpPost("http://localhost:8080/tomcat-9x-scenario/case/tomcat-9x-scenario";);
+            // Carry a query param and a header so the receiving Tomcat entry 
span (doPost) exercises
+            // the tomcat-plugin's http.params + http.headers collection (see 
configuration.yml).
+            HttpPost httpPost = new 
HttpPost("http://localhost:8080/tomcat-9x-scenario/case/tomcat-9x-scenario?q1=v1";);
+            httpPost.setHeader("mock_header", "mock_value");
             ResponseHandler<String> responseHandler = response -> {
                 HttpEntity entity = response.getEntity();
                 return entity != null ? EntityUtils.toString(entity) : null;

Reply via email to