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

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new b70f52ca7 [ISSUE #3966] Fix issue #3966 (#4005)
b70f52ca7 is described below

commit b70f52ca78d3860567140347eecf77df62b721ae
Author: moremind <[email protected]>
AuthorDate: Tue Sep 27 23:13:30 2022 +0800

    [ISSUE #3966] Fix issue #3966 (#4005)
    
    * [ISSUE #3966] add prefix forward
    
    * [ISSUE #3966] add prefix forward
    
    * [ISSUE #3966] add prefix forward
    
    * [ISSUE #3966] add prefix forward
    
    * [ISSUE #3966] add prefix forward
    
    * [ISSUE #3966] add prefix forward
    
    * [ISSUE #3966] add prefix forward
---
 db/init/mysql/schema.sql                           |  3 ++
 db/init/oracle/schema.sql                          |  7 ++++
 db/init/pg/create-table.sql                        |  3 ++
 db/upgrade/2.5.0-upgrade-2.5.1-mysql.sql           |  5 +++
 db/upgrade/2.5.0-upgrade-2.5.1-oracle.sql          | 11 ++++++
 db/upgrade/2.5.0-upgrade-2.5.1-pg.sql              |  5 +++
 .../AbstractContextPathRegisterService.java        |  1 +
 .../src/main/resources/sql-script/h2/schema.sql    |  1 +
 .../core/constant/ShenyuClientConstants.java       |  5 +++
 .../init/SpringCloudClientEventListener.java       |  4 ++
 .../init/SpringMvcClientEventListener.java         |  6 +++
 .../apache/shenyu/common/constant/Constants.java   |  2 +
 .../rule/impl/ContextMappingRuleHandle.java        | 46 ++++++++++++++++------
 .../src/main/resources/application.yml             |  1 +
 .../src/main/resources/context/shenyu.xml          |  1 +
 .../plugin/context/path/ContextPathPlugin.java     |  6 ++-
 .../register/common/dto/MetaDataRegisterDTO.java   | 40 ++++++++++++++++++-
 .../shenyu/register/common/dto/URIRegisterDTO.java |  7 ++--
 18 files changed, 138 insertions(+), 16 deletions(-)

diff --git a/db/init/mysql/schema.sql b/db/init/mysql/schema.sql
index e83482c3c..397c297bd 100644
--- a/db/init/mysql/schema.sql
+++ b/db/init/mysql/schema.sql
@@ -852,6 +852,7 @@ INSERT INTO `plugin_handle` VALUES ('1529402613204172741', 
'38', 'password', 'pa
 INSERT INTO `plugin_handle` VALUES ('1529402613204172742', '8', 'loadBalance', 
'loadStrategy', 3, 2, 3, '{\"defaultValue\":\"roundRobin\",\"rule\":\"\"}', 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
 INSERT INTO `plugin_handle` VALUES ('1529402613204172743', '10', 
'flowRuleMaxQueueingTimeMs', 'flowRuleMaxQueueingTimeMs', 1, 2, 6, 
'{\"required\":\"0\",\"defaultValue\":\"500\"}', '2022-05-25 18:02:53', 
'2022-05-25 18:02:53');
 INSERT INTO `plugin_handle` VALUES ('1529402613204172744', '10', 
'flowRuleWarmUpPeriodSec', 'flowRuleWarmUpPeriodSec', 1, 2, 6, 
'{\"required\":\"0\",\"defaultValue\":\"10\"}', '2022-05-25 18:02:53', 
'2022-05-25 18:02:53');
+INSERT INTO `plugin_handle` VALUES ('1529402613204172745', '14', 
'addPrefixed', 'addPrefixed', 3, 2, 3, 
'{\"required\":\"1\",\"defaultValue\":\"false\"}', '2022-09-27 12:00:00', 
'2022-09-27 12:00:00');
 
 -- ----------------------------
 -- Table structure for resource
@@ -1441,6 +1442,8 @@ INSERT INTO `shenyu_dict` VALUES ('1529402613195784278', 
'saslMechanism', 'SASL_
 INSERT INTO `shenyu_dict` VALUES ('1529402613195784279', 'saslMechanism', 
'SASL_MECHANISM', 'OAUTHBEARER', 'OAUTHBEARER', '', 3, 1, '2022-09-02 
00:00:00', '2022-09-02 00:00:00');
 INSERT INTO `shenyu_dict` VALUES ('1529402613195784280', 'saslMechanism', 
'SASL_MECHANISM', 'SCRAM-SHA-256', 'SCRAM-SHA-256', '', 4, 1,'2022-09-02 
00:00:00', '2022-09-02 00:00:00');
 INSERT INTO `shenyu_dict` VALUES ('1529402613195784281', 'saslMechanism', 
'SASL_MECHANISM', 'SCRAM-SHA-512', 'SCRAM-SHA-512', '', 5, 1, '2022-09-02 
00:00:00', '2022-09-02 00:00:00');
+INSERT INTO `shenyu_dict` VALUES ('1529402613195784282', 'addPrefixed', 
'ADD_PREFIXED', 'open', 'true', '', 0, 1, '2022-09-27 12:00:00', '2022-09-27 
12:00:00');
+INSERT INTO `shenyu_dict` VALUES ('1529402613195784283', 'addPrefixed', 
'ADD_PREFIXED', 'close', 'false', '', 1, 1, '2022-09-27 12:00:00', '2022-09-27 
12:00:00');
 
 -- ----------------------------
 -- Table structure for user_role
diff --git a/db/init/oracle/schema.sql b/db/init/oracle/schema.sql
index 3db7d8e57..c62531b8f 100644
--- a/db/init/oracle/schema.sql
+++ b/db/init/oracle/schema.sql
@@ -1544,6 +1544,8 @@ values ('1518229897214468228', '10', 
'flowRuleMaxQueueingTimeMs', 'flowRuleMaxQu
 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type)) 
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT, 
EXT_OBJ)
 values ('1518229897214468229', '10', 'flowRuleWarmUpPeriodSec', 
'flowRuleWarmUpPeriodSec', 1, 2, 6, '{"required":"0","defaultValue":"10"}');
 
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type)) 
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT, 
EXT_OBJ)
+VALUES ('1518229897214468230', '14', 'addPrefixed', 'addPrefixed', 3, 2, 3, 
'{"required":"1","defaultValue":"false"}');
 
 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
 VALUES ('1529402613195784271', 'securityProtocol', 'SECURITY_PROTOCOL', 
'default', '', '', 0, 1);
@@ -1578,6 +1580,11 @@ VALUES ('1529402613195784280', 'saslMechanism', 
'SASL_MECHANISM', 'SCRAM-SHA-256
 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
 VALUES ('1529402613195784281', 'saslMechanism', 'SASL_MECHANISM', 
'SCRAM-SHA-512', 'SCRAM-SHA-512', '', 5, 1);
 
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
+VALUES ('1529402613195784282', 'addPrefixed', 'ADD_PREFIXED', 'open', 'true', 
'', 0, 1);
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
+VALUES ('1529402613195784283', 'addPrefixed', 'ADD_PREFIXED', 'close', 
'false', '', 1, 1);
 
 /** insert resource for resource */
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX("resource" (id)) */ INTO "resource"   
(id, parent_id, title, name, url, component, resource_type, sort, icon, 
is_leaf, is_route, perms, status) 
VALUES('1346775491550474240','','SHENYU.MENU.PLUGIN.LIST','plug','/plug','PluginList','0','0','dashboard','0','0','','1');
diff --git a/db/init/pg/create-table.sql b/db/init/pg/create-table.sql
index a9ec45e3f..9c2ec34ed 100644
--- a/db/init/pg/create-table.sql
+++ b/db/init/pg/create-table.sql
@@ -941,6 +941,7 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1529402613204172801', '38', 'passw
 INSERT INTO "public"."plugin_handle" VALUES ('1529402613204172802', '8', 
'loadBalance', 'loadStrategy', 3, 2, 3, 
'{"defaultValue":"roundRobin","rule":""}', '2022-06-30 21:00:00', '2022-06-30 
21:00:00');
 INSERT INTO "public"."plugin_handle" VALUES ('1529402613204172803', '10', 
'flowRuleMaxQueueingTimeMs', 'flowRuleMaxQueueingTimeMs', 1, 2, 6, 
'{"required":"0","defaultValue":"500"}', '2022-06-30 21:00:00', '2022-06-30 
21:00:00');
 INSERT INTO "public"."plugin_handle" VALUES ('1529402613204172804', '10', 
'flowRuleWarmUpPeriodSec', 'flowRuleWarmUpPeriodSec', 1, 2, 6, 
'{"required":"0","defaultValue":"10"}', '2022-06-30 21:00:00', '2022-06-30 
21:00:00');
+INSERT INTO "public"."plugin_handle" VALUES ('1529402613204172805', '14', 
'addPrefixed', 'addPrefixed', 3, 2, 3, 
'{"required":"1","defaultValue":"false"}', '2022-09-27 12:00:00', '2022-09-27 
12:00:00');
 
 
 -- ----------------------------
@@ -1600,6 +1601,8 @@ INSERT INTO "public"."shenyu_dict" VALUES 
('1529402613195784278', 'saslMechanism
 INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784279', 
'saslMechanism', 'SASL_MECHANISM', 'OAUTHBEARER', 'OAUTHBEARER', '', 3, 1, 
'2022-09-02 00:00:00', '2022-09-02 00:00:00');
 INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784280', 
'saslMechanism', 'SASL_MECHANISM', 'SCRAM-SHA-256', 'SCRAM-SHA-256', '', 4, 
1,'2022-09-02 00:00:00', '2022-09-02 00:00:00');
 INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784281', 
'saslMechanism', 'SASL_MECHANISM', 'SCRAM-SHA-512', 'SCRAM-SHA-512', '', 5, 1, 
'2022-09-02 00:00:00', '2022-09-02 00:00:00');
+INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784282', 
'addPrefixed', 'ADD_PREFIXED', 'open', 'true', '', 0, 1, '2022-09-27 12:00:00', 
'2022-09-27 12:00:00');
+INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784283', 
'addPrefixed', 'ADD_PREFIXED', 'close', 'false', '', 1, 1, '2022-09-27 
12:00:00', '2022-09-27 12:00:00');
 
 
 
diff --git a/db/upgrade/2.5.0-upgrade-2.5.1-mysql.sql 
b/db/upgrade/2.5.0-upgrade-2.5.1-mysql.sql
index f154f4001..a6296919a 100644
--- a/db/upgrade/2.5.0-upgrade-2.5.1-mysql.sql
+++ b/db/upgrade/2.5.0-upgrade-2.5.1-mysql.sql
@@ -89,3 +89,8 @@ INSERT INTO `plugin_handle` VALUES ('1529402613204172744', 
'10', 'flowRuleWarmUp
 /*create plugin resource and permission for admin #3964 */
 INSERT INTO "resource" VALUES 
('1572525965625266176','1346777449787125760','SHENYU.BUTTON.SYSTEM.RESOURCE','','','','2','6','','1','0','system:plugin:resource','1');
 INSERT INTO "permission" VALUES ('1572525965658820608', '1346358560427216896', 
'1572525965625266176');
+
+/* fix issue 3966 */
+INSERT INTO `plugin_handle` VALUES ('1529402613204172745', '14', 
'addPrefixed', 'addPrefixed', 3, 2, 3, 
'{\"required\":\"1\",\"defaultValue\":\"false\"}', '2022-09-27 12:00:00', 
'2022-09-27 12:00:00');
+INSERT INTO `shenyu_dict` VALUES ('1529402613195784282', 'addPrefixed', 
'ADD_PREFIXED', 'open', 'true', '', 0, 1, '2022-09-27 12:00:00', '2022-09-27 
12:00:00');
+INSERT INTO `shenyu_dict` VALUES ('1529402613195784283', 'addPrefixed', 
'ADD_PREFIXED', 'close', 'false', '', 1, 1, '2022-09-27 12:00:00', '2022-09-27 
12:00:00');
\ No newline at end of file
diff --git a/db/upgrade/2.5.0-upgrade-2.5.1-oracle.sql 
b/db/upgrade/2.5.0-upgrade-2.5.1-oracle.sql
index ee1f1018b..c5f030915 100644
--- a/db/upgrade/2.5.0-upgrade-2.5.1-oracle.sql
+++ b/db/upgrade/2.5.0-upgrade-2.5.1-oracle.sql
@@ -175,3 +175,14 @@ insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX("resource" (id)) */ 
INTO resource  (id, pa
 values 
('1572525965625266176','1346777449787125760','SHENYU.BUTTON.SYSTEM.RESOURCE','','','','2','6','','1','0','system:plugin:resource','1');
 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX (permission(id)) */ INTO permission (id, 
object_id, resource_id)
 VALUES ('1572525965658820608', '1346358560427216896', '1572525965625266176');
+
+
+/* fix issue 3966 */
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type)) 
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT, 
EXT_OBJ)
+VALUES ('1518229897214468230', '14', 'addPrefixed', 'addPrefixed', 3, 2, 3, 
'{"required":"1","defaultValue":"false"}');
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
+VALUES ('1529402613195784282', 'addPrefixed', 'ADD_PREFIXED', 'open', 'true', 
'', 0, 1);
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
+VALUES ('1529402613195784283', 'addPrefixed', 'ADD_PREFIXED', 'close', 
'false', '', 1, 1);
\ No newline at end of file
diff --git a/db/upgrade/2.5.0-upgrade-2.5.1-pg.sql 
b/db/upgrade/2.5.0-upgrade-2.5.1-pg.sql
index 700534d74..3daa1b73d 100644
--- a/db/upgrade/2.5.0-upgrade-2.5.1-pg.sql
+++ b/db/upgrade/2.5.0-upgrade-2.5.1-pg.sql
@@ -91,3 +91,8 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1529402613204172804', '10', 'flowR
 /*create plugin resource and permission for admin #3964 */
 INSERT INTO "public"."resource" VALUES 
('1572525965625266176','1346777449787125760','SHENYU.BUTTON.SYSTEM.RESOURCE','','','','2','6','','1','0','system:plugin:resource','1');
 INSERT INTO "public"."permission" VALUES ('1572525965658820608', 
'1346358560427216896', '1572525965625266176');
+
+/* fix issue 3966 */
+INSERT INTO "public"."plugin_handle" VALUES ('1529402613204172805', '14', 
'addPrefixed', 'addPrefixed', 3, 2, 3, 
'{"required":"1","defaultValue":"false"}', '2022-09-27 12:00:00', '2022-09-27 
12:00:00');
+INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784282', 
'addPrefixed', 'ADD_PREFIXED', 'open', 'true', '', 0, 1, '2022-09-27 12:00:00', 
'2022-09-27 12:00:00');
+INSERT INTO "public"."shenyu_dict" VALUES ('1529402613195784283', 
'addPrefixed', 'ADD_PREFIXED', 'close', 'false', '', 1, 1, '2022-09-27 
12:00:00', '2022-09-27 12:00:00');
\ No newline at end of file
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractContextPathRegisterService.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractContextPathRegisterService.java
index f515a82a1..edc8d0e05 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractContextPathRegisterService.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractContextPathRegisterService.java
@@ -32,6 +32,7 @@ public abstract class AbstractContextPathRegisterService 
extends AbstractShenyuC
         String contextPathSelectorId = 
getSelectorService().registerDefault(dto, PluginEnum.CONTEXT_PATH.getName(), 
"");
         ContextMappingRuleHandle handle = new ContextMappingRuleHandle();
         
handle.setContextPath(PathUtils.decoratorContextPath(dto.getContextPath()));
+        handle.setAddPrefixed(dto.getAddPrefixed());
         
getRuleService().registerDefault(buildContextPathDefaultRuleDTO(contextPathSelectorId,
 dto, handle.toJson()));
     }
 }
diff --git a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql 
b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
index ab6885cf5..13b827c21 100755
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -635,6 +635,7 @@ INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172929', '36', 'baseRetryBackoffMs', 'baseRetryBackoffMs', 1, 3, 
14, '{"required":"0","defaultValue":100}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172930', '36', 'maxRetryBackoffMs', 'maxRetryBackoffMs', 1, 3, 
15, '{"required":"0","defaultValue":50000}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172931', '8', 'loadBalance', 'loadStrategy', 3, 2, 3, 
'{"defaultValue":"roundRobin","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172932', '14', 'prefixForwardEnable', 'prefixForwardEnable', 1, 
2, 3, '{"defaultValue":"1","rule":""}');
 
 
 /** insert resource for resource */
diff --git 
a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/constant/ShenyuClientConstants.java
 
b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/constant/ShenyuClientConstants.java
index dbcce8348..2b2d84f5b 100644
--- 
a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/constant/ShenyuClientConstants.java
+++ 
b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/constant/ShenyuClientConstants.java
@@ -71,4 +71,9 @@ public final class ShenyuClientConstants {
      * the constant of SERVICE_NAME.
      */
     public static final String SERVICE_NAME = "SERVICE_NAME";
+
+    /**
+     * prefix forward status.
+     */
+    public static final String ADD_PREFIXED = "addPrefixed";
 }
diff --git 
a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
 
b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
index f29c50359..8f2994a6e 100644
--- 
a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
+++ 
b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
@@ -62,6 +62,8 @@ public class SpringCloudClientEventListener extends 
AbstractContextRefreshedEven
     private final Environment env;
     
     private final String servletContextPath;
+
+    private final boolean addPrefixed;
     
     private final List<Class<? extends Annotation>> mappingAnnotation = new 
ArrayList<>(3);
 
@@ -83,6 +85,7 @@ public class SpringCloudClientEventListener extends 
AbstractContextRefreshedEven
             LOG.error(errorMsg);
             throw new ShenyuClientIllegalArgumentException(errorMsg);
         }
+        this.addPrefixed = 
Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.ADD_PREFIXED, 
Boolean.FALSE.toString()));
         this.isFull = 
Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.IS_FULL, 
Boolean.FALSE.toString()));
         this.servletContextPath = 
env.getProperty("server.servlet.context-path", "");
         mappingAnnotation.add(ShenyuSpringCloudClient.class);
@@ -204,6 +207,7 @@ public class SpringCloudClientEventListener extends 
AbstractContextRefreshedEven
                                                    final String path, final 
Class<?> clazz, final Method method) {
         return MetaDataRegisterDTO.builder()
                 .contextPath(StringUtils.defaultIfBlank(getContextPath(), 
this.servletContextPath))
+                .addPrefixed(addPrefixed)
                 .appName(getAppName())
                 .serviceName(clazz.getName())
                 
.methodName(Optional.ofNullable(method).map(Method::getName).orElse(null))
diff --git 
a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
 
b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
index 10f8917e0..c4904f191 100644
--- 
a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
+++ 
b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
@@ -60,6 +60,8 @@ public class SpringMvcClientEventListener extends 
AbstractContextRefreshedEventL
     private final Boolean isFull;
     
     private final String protocol;
+
+    private final boolean addPrefixed;
     
     /**
      * Instantiates a new context refreshed event listener.
@@ -73,6 +75,8 @@ public class SpringMvcClientEventListener extends 
AbstractContextRefreshedEventL
         Properties props = clientConfig.getProps();
         this.isFull = 
Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.IS_FULL, 
Boolean.FALSE.toString()));
         this.protocol = props.getProperty(ShenyuClientConstants.PROTOCOL, 
ShenyuClientConstants.HTTP);
+        this.addPrefixed = 
Boolean.parseBoolean(props.getProperty(ShenyuClientConstants.ADD_PREFIXED,
+                Boolean.FALSE.toString()));
         mappingAnnotation.add(ShenyuSpringMvcClient.class);
         mappingAnnotation.add(RequestMapping.class);
     }
@@ -83,6 +87,7 @@ public class SpringMvcClientEventListener extends 
AbstractContextRefreshedEventL
         if (Boolean.TRUE.equals(isFull)) {
             getPublisher().publishEvent(MetaDataRegisterDTO.builder()
                     .contextPath(getContextPath())
+                    .addPrefixed(addPrefixed)
                     .appName(getAppName())
                     .path(PathUtils.decoratorPathWithSlash(getContextPath()))
                     .rpcType(RpcTypeEnum.HTTP.getName())
@@ -192,6 +197,7 @@ public class SpringMvcClientEventListener extends 
AbstractContextRefreshedEventL
                                                    final Method method) {
         return MetaDataRegisterDTO.builder()
                 .contextPath(getContextPath())
+                .addPrefixed(addPrefixed)
                 .appName(getAppName())
                 .serviceName(clazz.getName())
                 
.methodName(Optional.ofNullable(method).map(Method::getName).orElse(null))
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
index 22775d9c4..160c178bb 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
@@ -647,6 +647,8 @@ public interface Constants {
      */
     String DEFAULT_CLUSTER = "failover";
 
+    int PREFIX_FORWARD_ENABLE = 1;
+
     /**
      * String q.
      */
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/impl/ContextMappingRuleHandle.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/impl/ContextMappingRuleHandle.java
index a88389274..ada75f2a3 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/impl/ContextMappingRuleHandle.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/impl/ContextMappingRuleHandle.java
@@ -26,10 +26,30 @@ import java.util.Objects;
  */
 public class ContextMappingRuleHandle implements RuleHandle {
 
+    private boolean addPrefixed;
+
     private String contextPath;
 
     private String addPrefix;
 
+    /**
+     * get prefix forward status.
+     *
+     * @return prefix-forward status
+     */
+    public boolean getAddPrefixed() {
+        return addPrefixed;
+    }
+
+    /**
+     * set prefix forward.
+     *
+     * @param addPrefixed status
+     */
+    public void setAddPrefixed(final boolean addPrefixed) {
+        this.addPrefixed = addPrefixed;
+    }
+
     /**
      * get contextPath.
      *
@@ -57,6 +77,15 @@ public class ContextMappingRuleHandle implements RuleHandle {
         return addPrefix;
     }
 
+    /**
+     * set addPrefix.
+     *
+     * @param addPrefix addPrefix
+     */
+    public void setAddPrefix(final String addPrefix) {
+        this.addPrefix = addPrefix;
+    }
+
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
@@ -66,7 +95,8 @@ public class ContextMappingRuleHandle implements RuleHandle {
             return false;
         }
         ContextMappingRuleHandle that = (ContextMappingRuleHandle) o;
-        return Objects.equals(contextPath, that.contextPath) && 
Objects.equals(addPrefix, that.addPrefix);
+        return Objects.equals(contextPath, that.contextPath) && 
Objects.equals(addPrefix, that.addPrefix)
+                && Objects.equals(addPrefixed, that.addPrefixed);
     }
 
     @Override
@@ -78,20 +108,14 @@ public class ContextMappingRuleHandle implements 
RuleHandle {
                 + ", addPrefix='"
                 + addPrefix
                 + '\''
+                + "addPrefixed='"
+                + addPrefixed
+                + '\''
                 + '}';
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(contextPath, addPrefix);
-    }
-
-    /**
-     * set addPrefix.
-     *
-     * @param addPrefix addPrefix
-     */
-    public void setAddPrefix(final String addPrefix) {
-        this.addPrefix = addPrefix;
+        return Objects.hash(contextPath, addPrefix, addPrefixed);
     }
 }
diff --git 
a/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
 
b/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
index d9b665c56..8c5282c8d 100644
--- 
a/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
+++ 
b/shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml
@@ -55,6 +55,7 @@ shenyu:
     springCloud:
       props:
         contextPath: /springcloud
+        addPrefixed: false
 #        port: 8884
 
 logging:
diff --git 
a/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
 
b/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
index 838fb87fc..77feebcb7 100644
--- 
a/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
+++ 
b/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
@@ -47,6 +47,7 @@
                 <entry key="appName" value="springmvc"/>
                 <entry key="port" value="8289"/>
                 <entry key="isFull" value="false"/>
+                <entry key="addPrefixed" value="false"/>
             </map>
         </property>
     </bean>
diff --git 
a/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
 
b/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
index 7ef74fbe4..4fd0b916d 100644
--- 
a/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
@@ -98,7 +98,11 @@ public class ContextPathPlugin extends AbstractShenyuPlugin {
         if (StringUtils.isNoneBlank(contextPath)) {
             context.setContextPath(contextPath);
             context.setModule(contextPath);
-            realURI = context.getPath().substring(contextPath.length());
+            if (handle.getAddPrefixed()) {
+                realURI = context.getPath();
+            } else {
+                realURI = context.getPath().substring(contextPath.length());
+            }
         }
         String addPrefix = handle.getAddPrefix();
         if (StringUtils.isNoneBlank(addPrefix)) {
diff --git 
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/MetaDataRegisterDTO.java
 
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/MetaDataRegisterDTO.java
index bbbeb8f07..e0481c3ef 100644
--- 
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/MetaDataRegisterDTO.java
+++ 
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/MetaDataRegisterDTO.java
@@ -60,6 +60,8 @@ public class MetaDataRegisterDTO implements DataTypeParent {
 
     private long timeMillis;
 
+    private boolean addPrefixed;
+
     /**
      * Instantiates a new Meta data register dto.
      *
@@ -78,6 +80,7 @@ public class MetaDataRegisterDTO implements DataTypeParent {
      * @param port the port
      * @param pluginNames the plugin names
      * @param registerMetaData the register meta data
+     * @param addPrefixed the prefix forward status
      */
     public MetaDataRegisterDTO(final String appName, final String contextPath,
                                final String path, final String pathDesc,
@@ -86,7 +89,7 @@ public class MetaDataRegisterDTO implements DataTypeParent {
                                final String parameterTypes, final String 
rpcExt,
                                final boolean enabled, final String host,
                                final Integer port, final List<String> 
pluginNames,
-                               final boolean registerMetaData) {
+                               final boolean registerMetaData, final boolean 
addPrefixed) {
         this.appName = appName;
         this.contextPath = contextPath;
         this.path = path;
@@ -103,6 +106,7 @@ public class MetaDataRegisterDTO implements DataTypeParent {
         this.pluginNames = pluginNames;
         this.registerMetaData = registerMetaData;
         this.timeMillis = System.currentTimeMillis();
+        this.addPrefixed = addPrefixed;
     }
     
     /**
@@ -128,6 +132,7 @@ public class MetaDataRegisterDTO implements DataTypeParent {
         pluginNames = builder.pluginNames;
         registerMetaData = builder.registerMetaData;
         timeMillis = System.currentTimeMillis();
+        addPrefixed = builder.addPrefixed;
     }
     
     /**
@@ -432,6 +437,24 @@ public class MetaDataRegisterDTO implements DataTypeParent 
{
         this.timeMillis = timeMillis;
     }
 
+    /**
+     * get prefix forward status.
+     *
+     * @return prefix forward status
+     */
+    public boolean getAddPrefixed() {
+        return addPrefixed;
+    }
+
+    /**
+     * set prefix forward status.
+     *
+     * @param prefixForwardEnable prefixForwardEnabled
+     */
+    public void setAddPrefixed(final boolean prefixForwardEnable) {
+        this.addPrefixed = prefixForwardEnable;
+    }
+
     @Override
     public String toString() {
         return "MetaDataRegisterDTO{" 
@@ -467,6 +490,8 @@ public class MetaDataRegisterDTO implements DataTypeParent {
                 + registerMetaData
                 + ", timeMillis="
                 + timeMillis
+                + ", addPrefixed="
+                + addPrefixed
                 + '}';
     }
     
@@ -507,6 +532,8 @@ public class MetaDataRegisterDTO implements DataTypeParent {
 
         private long timeMillis;
 
+        private boolean addPrefixed;
+
         private Builder() {
         }
     
@@ -686,6 +713,17 @@ public class MetaDataRegisterDTO implements DataTypeParent 
{
             return this;
         }
 
+        /**
+         * prefixForward status.
+         *
+         * @param addPrefixed addPrefixed
+         * @return Builder builder
+         */
+        public Builder addPrefixed(final boolean addPrefixed) {
+            this.addPrefixed = addPrefixed;
+            return this;
+        }
+
         /**
          * build.
          *
diff --git 
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/URIRegisterDTO.java
 
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/URIRegisterDTO.java
index 6aafef34a..a0193191f 100644
--- 
a/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/URIRegisterDTO.java
+++ 
b/shenyu-register-center/shenyu-register-common/src/main/java/org/apache/shenyu/register/common/dto/URIRegisterDTO.java
@@ -41,6 +41,7 @@ public class URIRegisterDTO implements DataTypeParent {
     private Integer port;
 
     private EventType eventType;
+
     
     /**
      * Instantiates a new Uri register dto.
@@ -54,8 +55,8 @@ public class URIRegisterDTO implements DataTypeParent {
      * @param eventType the event type
      */
     public URIRegisterDTO(final String protocol, final String appName, final 
String contextPath,
-                          final String rpcType, final String host,
-                          final Integer port, final EventType eventType) {
+                          final String rpcType, final String host, final 
Integer port,
+                          final EventType eventType, final Integer 
prefixForwardEnable) {
         this.protocol = protocol;
         this.appName = appName;
         this.contextPath = contextPath;
@@ -389,7 +390,7 @@ public class URIRegisterDTO implements DataTypeParent {
             this.eventType = eventType;
             return this;
         }
-    
+
         /**
          * build.
          *

Reply via email to