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 a7569b44d [type:refactor] refactor rule match cache (#4446)
a7569b44d is described below

commit a7569b44ded6fa773055984173de8a276746c66f
Author: moremind <[email protected]>
AuthorDate: Mon Mar 13 14:08:12 2023 +0800

    [type:refactor] refactor rule match cache (#4446)
    
    * [type:refactor] refactor cache match restful
    
    * [type:refactor] refactor cache match restful
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * [type:refactor] refactor match cache
    
    * [type:refactor] refactor match cache
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * add static resource
    
    * add static resource
    
    * [type:refactor] refactor rule match cache
    
    * [type:refactor] refactor rule match cache
    
    * [type:refactor] refactor rule match cache
    
    * [type:refactor] refactor rule match cache
    
    * [type:refactor] refactor rule match cache
    
    * [type:refactor] refactor rule match cache
    
    * fix ci
    
    ---------
    
    Co-authored-by: xiaoyu <[email protected]>
---
 db/init/mysql/schema.sql                           |  2 +
 db/init/oracle/schema.sql                          | 26 ++++++-----
 db/init/pg/create-table.sql                        |  4 ++
 db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql           |  8 ++++
 db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql          |  8 ++++
 db/upgrade/2.5.1-upgrade-2.6.0-pg.sql              |  9 ++++
 .../org/apache/shenyu/admin/model/dto/RuleDTO.java | 45 +++++++++++++++++--
 .../apache/shenyu/admin/model/dto/SelectorDTO.java | 47 ++++++++++++++++++--
 .../apache/shenyu/admin/model/entity/RuleDO.java   | 50 ++++++++++++++++++++--
 .../shenyu/admin/model/entity/SelectorDO.java      | 50 ++++++++++++++++++++--
 .../org/apache/shenyu/admin/model/vo/RuleVO.java   | 32 ++++++++++++--
 .../apache/shenyu/admin/model/vo/SelectorVO.java   | 35 +++++++++++++--
 .../AbstractShenyuClientRegisterServiceImpl.java   |  1 +
 .../apache/shenyu/admin/utils/SelectorUtil.java    |  1 +
 .../src/main/resources/mappers/rule-sqlmap.xml     | 32 ++++++++++----
 .../src/main/resources/mappers/selector-sqlmap.xml | 14 ++++++
 .../src/main/resources/sql-script/h2/schema.sql    |  2 +
 .../src/main/resources/static/index.2c016d57.js    |  1 +
 .../{index.98c5ed36.css => index.7904889c.css}     |  6 +--
 .../src/main/resources/static/index.e0e89752.js    |  1 -
 shenyu-admin/src/main/resources/static/index.html  |  4 +-
 .../admin/controller/RuleControllerTest.java       |  4 +-
 .../admin/controller/SelectorControllerTest.java   |  4 +-
 .../apache/shenyu/admin/mapper/RuleMapperTest.java |  1 +
 .../shenyu/admin/mapper/SelectorMapperTest.java    |  1 +
 .../admin/service/DataPermissionServiceTest.java   |  4 +-
 .../org/apache/shenyu/common/dto/RuleData.java     | 48 +++++++++++++++++++--
 .../org/apache/shenyu/common/dto/SelectorData.java | 46 ++++++++++++++++++--
 shenyu-e2e/pom.xml                                 |  1 +
 .../e2e/testcase/common/ResourceDataTemplate.java  |  2 +
 .../e2e/client/admin/model/data/RuleData.java      |  9 ++--
 .../e2e/client/admin/model/data/SelectorData.java  |  3 +-
 .../shenyu/e2e/client/admin/AdminClientTest.java   |  5 +++
 .../shenyu/plugin/base/AbstractShenyuPlugin.java   | 18 ++++++--
 .../shenyu/plugin/base/cache/MatchDataCache.java   |  1 +
 .../apache/shenyu/plugin/base/trie/ShenyuTrie.java |  2 +-
 .../plugin/base/AbstractShenyuPluginTest.java      | 12 +++++-
 .../web/controller/LocalPluginController.java      |  7 +++
 38 files changed, 475 insertions(+), 71 deletions(-)

diff --git a/db/init/mysql/schema.sql b/db/init/mysql/schema.sql
index 94678e48e..c525d9fb7 100644
--- a/db/init/mysql/schema.sql
+++ b/db/init/mysql/schema.sql
@@ -1588,6 +1588,7 @@ CREATE TABLE `rule`  (
   `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT 
NULL COMMENT 'rule name',
   `enabled` tinyint(0) NOT NULL COMMENT 'whether to open (0 close, 1 open) ',
   `loged` tinyint(0) NOT NULL COMMENT 'whether to log or not (0 no print, 1 
print) ',
+  `match_restful` tinyint(0) NOT NULL COMMENT 'whether to match restful(0 
cache, 1 not cache)',
   `sort` int(0) NOT NULL COMMENT 'sort',
   `handle` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL 
DEFAULT NULL COMMENT 'processing logic (here for different plug-ins, there will 
be different fields to identify different processes, all data in JSON format is 
stored)',
   `date_created` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 
'create time',
@@ -1634,6 +1635,7 @@ CREATE TABLE `selector`  (
   `enabled` tinyint(0) NOT NULL COMMENT 'whether to open (0 close, 1 open) ',
   `loged` tinyint(0) NOT NULL COMMENT 'whether to print the log (0 no print, 1 
print) ',
   `continued` tinyint(0) NOT NULL COMMENT 'whether to continue execution',
+  `match_restful` tinyint(0) NOT NULL COMMENT 'whether to match restful(0 
cache, 1 not cache)',
   `date_created` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 
'create time',
   `date_updated` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE 
CURRENT_TIMESTAMP(3) COMMENT 'update time',
   PRIMARY KEY (`id`) USING BTREE
diff --git a/db/init/oracle/schema.sql b/db/init/oracle/schema.sql
index 0bec3c5f3..2e77f455b 100644
--- a/db/init/oracle/schema.sql
+++ b/db/init/oracle/schema.sql
@@ -123,6 +123,7 @@ create table selector
     enabled      NUMBER(3) not null,
     loged        NUMBER(3) not null,
     continued    NUMBER(3) not null,
+    match_restful NUMBER(3) not null,
     date_created timestamp(3) default SYSDATE not null,
     date_updated timestamp(3) default SYSDATE not null
 );
@@ -147,6 +148,8 @@ comment on column SELECTOR.loged
   is 'whether to print the log (0 not print, 1 print)';
 comment on column SELECTOR.continued
   is 'whether to continue execution';
+comment on column SELECTOR.match_restful
+  is 'whether to match restful(0 cache, 1 not cache)';
 comment on column SELECTOR.date_created
   is 'create time';
 comment on column SELECTOR.date_updated
@@ -184,16 +187,17 @@ comment on column SELECTOR_CONDITION.date_updated
 
 create table rule
 (
-    id           VARCHAR2(128) not null PRIMARY KEY,
-    selector_id  VARCHAR2(128) not null,
-    match_mode   NUMBER(10) not null,
-    name         VARCHAR2(128) not null,
-    enabled      NUMBER(3) not null,
-    loged        NUMBER(3) not null,
-    sort         NUMBER(10) not null,
-    handle       VARCHAR2(1024),
-    date_created timestamp(3) default SYSDATE not null,
-    date_updated timestamp(3) default SYSDATE not null
+    id            VARCHAR2(128) not null PRIMARY KEY,
+    selector_id   VARCHAR2(128) not null,
+    match_mode    NUMBER(10) not null,
+    name          VARCHAR2(128) not null,
+    enabled       NUMBER(3) not null,
+    loged         NUMBER(3) not null,
+    match_restful NUMBER(3) not null,
+    sort          NUMBER(10) not null,
+    handle        VARCHAR2(1024),
+    date_created  timestamp(3) default SYSDATE not null,
+    date_updated  timestamp(3) default SYSDATE not null
 );
 -- Add comments to the columns
 comment on column RULE.id
@@ -208,6 +212,8 @@ comment on column RULE.enabled
   is 'whether to open (0 not open, 1 open)';
 comment on column RULE.loged
   is 'whether to log or not (0 not print, 1 print)';
+comment on column RULE.match_restful
+  is 'whether to match restful(0 cache, 1 not cache)';
 comment on column RULE.sort
   is 'sort';
 comment on column RULE.handle
diff --git a/db/init/pg/create-table.sql b/db/init/pg/create-table.sql
index 6e5f8a170..ec58afa9e 100644
--- a/db/init/pg/create-table.sql
+++ b/db/init/pg/create-table.sql
@@ -1761,6 +1761,7 @@ CREATE TABLE "public"."rule" (
   "name" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
   "enabled" int2 NOT NULL,
   "loged" int2 NOT NULL,
+  "match_restful" int2 NOT NULL,
   "sort" int4 NOT NULL,
   "handle" varchar(1024) COLLATE "pg_catalog"."default",
   "date_created" timestamp(6) NOT NULL DEFAULT timezone('UTC-8'::text, 
(now())::timestamp(0) without time zone),
@@ -1773,6 +1774,7 @@ COMMENT ON COLUMN "public"."rule"."match_mode" IS 
'matching mode (0 and 1 or)';
 COMMENT ON COLUMN "public"."rule"."name" IS 'rule name';
 COMMENT ON COLUMN "public"."rule"."enabled" IS 'whether to open (0 close, 1 
open) ';
 COMMENT ON COLUMN "public"."rule"."loged" IS 'whether to log or not (0 no 
print, 1 print) ';
+COMMENT ON COLUMN "public"."rule"."match_restful" IS 'whether to match 
restful(0 cache, 1 not cache)';
 COMMENT ON COLUMN "public"."rule"."sort" IS 'sort';
 COMMENT ON COLUMN "public"."rule"."handle" IS 'processing logic (here for 
different plug-ins, there will be different fields to identify different 
processes, all data in JSON format is stored)';
 COMMENT ON COLUMN "public"."rule"."date_created" IS 'create time';
@@ -1825,6 +1827,7 @@ CREATE TABLE "public"."selector" (
   "enabled" int2 NOT NULL,
   "loged" int2 NOT NULL,
   "continued" int2 NOT NULL,
+  "match_restful" int2 NOT NULL,
   "date_created" timestamp(6) NOT NULL DEFAULT timezone('UTC-8'::text, 
(now())::timestamp(0) without time zone),
   "date_updated" timestamp(6) NOT NULL DEFAULT timezone('UTC-8'::text, 
(now())::timestamp(0) without time zone)
 )
@@ -1839,6 +1842,7 @@ COMMENT ON COLUMN "public"."selector"."handle" IS 
'processing logic (here for di
 COMMENT ON COLUMN "public"."selector"."enabled" IS 'whether to open (0 close, 
1 open) ';
 COMMENT ON COLUMN "public"."selector"."loged" IS 'whether to print the log (0 
no print, 1 print) ';
 COMMENT ON COLUMN "public"."selector"."continued" IS 'whether to continue 
execution';
+COMMENT ON COLUMN "public"."selector"."match_restful" IS 'whether to match 
restful(0 cache, 1 not cache)';
 COMMENT ON COLUMN "public"."selector"."date_created" IS 'create time';
 COMMENT ON COLUMN "public"."selector"."date_updated" IS 'update time';
 
diff --git a/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql 
b/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql
index 3fb707da1..5dd77702b 100644
--- a/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql
+++ b/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql
@@ -16,6 +16,14 @@
 
 -- this file works for MySQL.
 
+ALTER TABLE selector ADD COLUMN match_restful TINYINT(0) NOT NULL
+COMMENT 'whether to match restful(0 cache, 1 not cache)';
+COMMIT;
+
+ALTER TABLE rule ADD COLUMN match_restful TINYINT(0) NOT NULL
+COMMENT 'whether to match restful(0 cache, 1 not cache)';
+COMMIT;
+
 /* insert plugin_handle data for plugin CryptorRequest */
 INSERT INTO `plugin_handle` VALUES ('1630760188111376384', '24', 'mapType', 
'mapType', 3, 2, 3, 
'{\"required\":\"0\",\"defaultValue\":\"all\",\"rule\":\"\"}', '2023-03-01 
10:41:41', '2023-03-01 10:42:21');
 /* insert plugin_handle data for plugin cryptorResponse */
diff --git a/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql 
b/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql
index b46713f5c..8cf71ecd5 100644
--- a/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql
+++ b/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql
@@ -16,6 +16,14 @@
 
 -- this file works for Oracle, can not use "`" syntax.
 
+ALTER TABLE selector ADD match_restful NUMBER(3) not null;
+COMMENT ON COLUMN SELECTOR.match_restful IS 'whether to match restful(0 cache, 
1 not cache)';
+COMMIT;
+
+ALTER TABLE rule ADD match_restful NUMBER(3) not null;
+COMMENT ON COLUMN RULE.match_restful IS 'whether to match restful(0 cache, 1 
not cache)';
+COMMIT;
+
 /* insert plugin_handle data for plugin CryptorRequest */
 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 ('1630760188111376384', '24', 'mapType', 'mapType', 3, 2, 3, 
'{\"required\":\"0\",\"defaultValue\":\"all\",\"rule\":\"\"}');
diff --git a/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql 
b/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql
index f95c12074..cd518027f 100644
--- a/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql
+++ b/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql
@@ -16,6 +16,15 @@
 
 -- this file works for PostgreSQL, can not use "`" syntax.
 
+ALTER TABLE selector ADD COLUMN match_restful int2 NOT NULL;
+COMMENT ON COLUMN "public"."rule"."match_restful" IS 'whether to match 
restful(0 cache, 1 not cache)';
+COMMIT;
+
+ALTER TABLE rule ADD COLUMN match_restful int2 NOT NULL;
+COMMENT ON COLUMN "public"."rule"."match_restful" IS 'whether to match 
restful(0 cache, 1 not cache)';
+COMMIT;
+
+
 /* insert plugin_handle data for plugin CryptorRequest */
 INSERT INTO "public"."plugin_handle" VALUES ('1630760188111376384', '24', 
'mapType', 'mapType', 3, 2, 3, 
'{\"required\":\"0\",\"defaultValue\":\"all\",\"rule\":\"\"}', '2023-03-01 
10:41:41', '2023-03-01 10:42:21');
 /* insert plugin_handle data for plugin cryptorResponse */
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/RuleDTO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/RuleDTO.java
index 87bab4453..261161d5b 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/RuleDTO.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/RuleDTO.java
@@ -91,6 +91,9 @@ public final class RuleDTO implements Serializable {
     @NotEmpty
     private List<@Valid RuleConditionDTO> ruleConditions;
     
+    @NotNull
+    private Boolean matchRestful;
+    
     public RuleDTO() {
     }
     
@@ -102,7 +105,8 @@ public final class RuleDTO implements Serializable {
                    final Boolean loged,
                    @NotNull final Integer sort,
                    final String handle,
-                   @Valid final List<RuleConditionDTO> ruleConditions) {
+                   @Valid final List<RuleConditionDTO> ruleConditions,
+                   @NotNull final Boolean matchRestful) {
         this.id = id;
         this.selectorId = selectorId;
         this.matchMode = matchMode;
@@ -112,6 +116,7 @@ public final class RuleDTO implements Serializable {
         this.sort = sort;
         this.handle = handle;
         this.ruleConditions = ruleConditions;
+        this.matchRestful = matchRestful;
     }
     
     /**
@@ -276,6 +281,24 @@ public final class RuleDTO implements Serializable {
         this.ruleConditions = ruleConditions;
     }
     
+    /**
+     * get match restful.
+     *
+     * @return getMatchRestful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     /**
      * builder method.
      *
@@ -302,12 +325,13 @@ public final class RuleDTO implements Serializable {
                 && Objects.equals(loged, ruleDTO.loged)
                 && Objects.equals(sort, ruleDTO.sort)
                 && Objects.equals(handle, ruleDTO.handle)
-                && Objects.equals(ruleConditions, ruleDTO.ruleConditions);
+                && Objects.equals(ruleConditions, ruleDTO.ruleConditions)
+                && Objects.equals(matchRestful, ruleDTO.getMatchRestful());
     }
     
     @Override
     public int hashCode() {
-        return Objects.hash(id, selectorId, matchMode, name, enabled, loged, 
sort, handle, ruleConditions);
+        return Objects.hash(id, selectorId, matchMode, name, enabled, loged, 
sort, handle, ruleConditions, matchRestful);
     }
     
     public static final class RuleDTOBuilder {
@@ -330,6 +354,8 @@ public final class RuleDTO implements Serializable {
         
         private List<RuleConditionDTO> ruleConditions;
         
+        private Boolean matchRestful;
+        
         private RuleDTOBuilder() {
         }
         
@@ -431,6 +457,17 @@ public final class RuleDTO implements Serializable {
             this.ruleConditions = ruleConditions;
             return this;
         }
+    
+        /**
+         * match restful.
+         *
+         * @param matchRestful matchRestful
+         * @return RuleDTOBuilder
+         */
+        public RuleDTOBuilder matchRestful(final Boolean matchRestful) {
+            this.matchRestful = matchRestful;
+            return this;
+        }
         
         /**
          * build method.
@@ -438,7 +475,7 @@ public final class RuleDTO implements Serializable {
          * @return build object.
          */
         public RuleDTO build() {
-            return new RuleDTO(id, selectorId, matchMode, name, enabled, 
loged, sort, handle, ruleConditions);
+            return new RuleDTO(id, selectorId, matchMode, name, enabled, 
loged, sort, handle, ruleConditions, matchRestful);
         }
     }
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/SelectorDTO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/SelectorDTO.java
index cc9ab8a1c..9e0baca7a 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/SelectorDTO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/SelectorDTO.java
@@ -105,6 +105,9 @@ public final class SelectorDTO implements Serializable {
      */
     private List<SelectorConditionDTO> selectorConditions;
     
+    @NotNull
+    private Boolean matchRestful;
+    
     public SelectorDTO() {
     }
     
@@ -118,7 +121,8 @@ public final class SelectorDTO implements Serializable {
                        final Boolean loged,
                        @NotNull final Boolean continued,
                        final String handle,
-                       @Valid final List<SelectorConditionDTO> 
selectorConditions) {
+                       @Valid final List<SelectorConditionDTO> 
selectorConditions,
+                       @NotNull final Boolean matchRestful) {
         this.id = id;
         this.pluginId = pluginId;
         this.name = name;
@@ -130,6 +134,7 @@ public final class SelectorDTO implements Serializable {
         this.continued = continued;
         this.handle = handle;
         this.selectorConditions = selectorConditions;
+        this.matchRestful = matchRestful;
     }
     
     /**
@@ -330,6 +335,24 @@ public final class SelectorDTO implements Serializable {
         this.selectorConditions = selectorConditions;
     }
     
+    /**
+     * get match restful.
+     *
+     * @return match restful value
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful value.
+     *
+     * @param matchRestful match restful value
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     /**
      * builder method.
      *
@@ -358,12 +381,14 @@ public final class SelectorDTO implements Serializable {
                 && Objects.equals(loged, that.loged)
                 && Objects.equals(continued, that.continued)
                 && Objects.equals(handle, that.handle)
-                && Objects.equals(selectorConditions, that.selectorConditions);
+                && Objects.equals(selectorConditions, that.selectorConditions)
+                && Objects.equals(matchRestful, that.matchRestful);
     }
     
     @Override
     public int hashCode() {
-        return Objects.hash(id, pluginId, name, matchMode, type, sort, 
enabled, loged, continued, handle, selectorConditions);
+        return Objects.hash(id, pluginId, name, matchMode, type, sort, 
enabled, loged, continued, handle,
+                selectorConditions, matchRestful);
     }
     
     public static final class SelectorDTOBuilder {
@@ -390,6 +415,8 @@ public final class SelectorDTO implements Serializable {
         
         private List<SelectorConditionDTO> selectorConditions;
         
+        private Boolean matchRestful;
+        
         private SelectorDTOBuilder() {
         }
         
@@ -513,6 +540,17 @@ public final class SelectorDTO implements Serializable {
             this.selectorConditions = selectorConditions;
             return this;
         }
+    
+        /**
+         * match restful.
+         *
+         * @param matchRestful the matchRestful value
+         * @return SelectorDTOBuilder
+         */
+        public SelectorDTOBuilder matchRestful(final Boolean matchRestful) {
+            this.matchRestful = matchRestful;
+            return this;
+        }
         
         /**
          * build method.
@@ -520,7 +558,8 @@ public final class SelectorDTO implements Serializable {
          * @return build object.
          */
         public SelectorDTO build() {
-            return new SelectorDTO(id, pluginId, name, matchMode, type, sort, 
enabled, loged, continued, handle, selectorConditions);
+            return new SelectorDTO(id, pluginId, name, matchMode, type, sort, 
enabled, loged, continued, handle,
+                    selectorConditions, matchRestful);
         }
     }
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java
index 9c5ea3e93..e06bad12b 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java
@@ -70,6 +70,11 @@ public final class RuleDO extends BaseDO {
      * process logic.
      */
     private String handle;
+    
+    /**
+     * match restful.
+     */
+    private Boolean matchRestful;
 
     public RuleDO() {
     }
@@ -80,7 +85,8 @@ public final class RuleDO extends BaseDO {
                   final Boolean enabled,
                   final Boolean loged,
                   final Integer sort,
-                  final String handle) {
+                  final String handle,
+                  final Boolean matchRestful) {
         this.selectorId = selectorId;
         this.matchMode = matchMode;
         this.name = name;
@@ -88,6 +94,7 @@ public final class RuleDO extends BaseDO {
         this.loged = loged;
         this.sort = sort;
         this.handle = handle;
+        this.matchRestful = matchRestful;
     }
 
     /**
@@ -215,7 +222,25 @@ public final class RuleDO extends BaseDO {
     public void setHandle(final String handle) {
         this.handle = handle;
     }
-
+    
+    /**
+     * get match restful uri.
+     *
+     * @return matchRestful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     /**
      * builder method.
      *
@@ -242,6 +267,7 @@ public final class RuleDO extends BaseDO {
                     .loged(item.getLoged())
                     .sort(item.getSort())
                     .handle(item.getHandle())
+                    .matchRestful(item.getMatchRestful())
                     .dateUpdated(currentTime)
                     .build();
             if (StringUtils.isEmpty(item.getId())) {
@@ -274,6 +300,7 @@ public final class RuleDO extends BaseDO {
                 .enabled(ruleDO.getEnabled())
                 .loged(ruleDO.getLoged())
                 .handle(ruleDO.getHandle())
+                .matchRestful(ruleDO.getMatchRestful())
                 .conditionDataList(conditionDataList)
                 .beforeConditionDataList(beforeConditionDataList)
                 .build();
@@ -310,12 +337,13 @@ public final class RuleDO extends BaseDO {
                 && Objects.equals(enabled, ruleDO.enabled)
                 && Objects.equals(loged, ruleDO.loged)
                 && Objects.equals(sort, ruleDO.sort)
-                && Objects.equals(handle, ruleDO.handle);
+                && Objects.equals(handle, ruleDO.handle)
+                && Objects.equals(matchRestful, ruleDO.matchRestful);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), selectorId, matchMode, name, 
enabled, loged, sort, handle);
+        return Objects.hash(super.hashCode(), selectorId, matchMode, name, 
enabled, loged, sort, handle, matchRestful);
     }
 
     public static final class RuleDOBuilder {
@@ -339,6 +367,8 @@ public final class RuleDO extends BaseDO {
         private Integer sort;
 
         private String handle;
+        
+        private Boolean matchRestful;
 
         private RuleDOBuilder() {
         }
@@ -452,6 +482,17 @@ public final class RuleDO extends BaseDO {
             this.handle = handle;
             return this;
         }
+    
+        /**
+         * matchRestful.
+         *
+         * @param matchRestful matchRestful
+         * @return RuleDOBuilder
+         */
+        public RuleDOBuilder matchRestful(final Boolean matchRestful) {
+            this.matchRestful = matchRestful;
+            return this;
+        }
 
         /**
          * build method.
@@ -470,6 +511,7 @@ public final class RuleDO extends BaseDO {
             ruleDO.setLoged(loged);
             ruleDO.setSort(sort);
             ruleDO.setHandle(handle);
+            ruleDO.setMatchRestful(matchRestful);
             return ruleDO;
         }
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/SelectorDO.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/SelectorDO.java
index 89f8d853f..cbc81e0cf 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/SelectorDO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/SelectorDO.java
@@ -81,6 +81,11 @@ public final class SelectorDO extends BaseDO {
      * handle.
      */
     private String handle;
+    
+    /**
+     * match restful.
+     */
+    private Boolean matchRestful;
 
     public SelectorDO() {
     }
@@ -93,7 +98,8 @@ public final class SelectorDO extends BaseDO {
                       final Boolean enabled,
                       final Boolean loged,
                       final Boolean continued,
-                      final String handle) {
+                      final String handle,
+                      final Boolean matchRestful) {
         this.pluginId = pluginId;
         this.name = name;
         this.matchMode = matchMode;
@@ -103,6 +109,7 @@ public final class SelectorDO extends BaseDO {
         this.loged = loged;
         this.continued = continued;
         this.handle = handle;
+        this.matchRestful = matchRestful;
     }
 
     /**
@@ -266,7 +273,25 @@ public final class SelectorDO extends BaseDO {
     public void setHandle(final String handle) {
         this.handle = handle;
     }
-
+    
+    /**
+     * get match restful.
+     *
+     * @return match restful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     /**
      * builder method.
      *
@@ -296,12 +321,13 @@ public final class SelectorDO extends BaseDO {
                 && Objects.equals(enabled, that.enabled)
                 && Objects.equals(loged, that.loged)
                 && Objects.equals(continued, that.continued)
-                && Objects.equals(handle, that.handle);
+                && Objects.equals(handle, that.handle)
+                && Objects.equals(matchRestful, that.matchRestful);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), pluginId, name, matchMode, type, 
sort, enabled, loged, continued, handle);
+        return Objects.hash(super.hashCode(), pluginId, name, matchMode, type, 
sort, enabled, loged, continued, handle, matchRestful);
     }
 
     /**
@@ -323,6 +349,7 @@ public final class SelectorDO extends BaseDO {
                     .handle(item.getHandle())
                     .pluginId(item.getPluginId())
                     .name(item.getName())
+                    .matchRestful(item.getMatchRestful())
                     .build();
             if (StringUtils.isEmpty(item.getId())) {
                 selectorDO.setId(UUIDUtils.getInstance().generateShortUuid());
@@ -361,6 +388,7 @@ public final class SelectorDO extends BaseDO {
                 .continued(selectorDO.getContinued())
                 .handle(selectorDO.getHandle())
                 .conditionList(conditionDataList)
+                .matchRestful(selectorDO.getMatchRestful())
                 .build();
     }
 
@@ -389,6 +417,8 @@ public final class SelectorDO extends BaseDO {
         private Boolean continued;
 
         private String handle;
+        
+        private Boolean matchRestful;
 
         private SelectorDOBuilder() {
         }
@@ -524,6 +554,17 @@ public final class SelectorDO extends BaseDO {
             this.handle = handle;
             return this;
         }
+    
+        /**
+         * match restful.
+         *
+         * @param matchRestful matchRestful
+         * @return SelectorDOBuilder
+         */
+        public SelectorDOBuilder matchRestful(final Boolean matchRestful) {
+            this.matchRestful = matchRestful;
+            return this;
+        }
 
         /**
          * build method.
@@ -544,6 +585,7 @@ public final class SelectorDO extends BaseDO {
             selectorDO.setLoged(loged);
             selectorDO.setContinued(continued);
             selectorDO.setHandle(handle);
+            selectorDO.setMatchRestful(matchRestful);
             return selectorDO;
         }
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/RuleVO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/RuleVO.java
index c000b28fd..a1a70f06e 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/RuleVO.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/RuleVO.java
@@ -75,7 +75,12 @@ public class RuleVO implements Serializable {
      * process logic.
      */
     private String handle;
-
+    
+    /**
+     * match restful.
+     */
+    private Boolean matchRestful;
+    
     /**
      * rule conditions.
      */
@@ -103,6 +108,7 @@ public class RuleVO implements Serializable {
                   final Boolean loged,
                   final Integer sort,
                   final String handle,
+                  final Boolean matchRestful,
                   final List<RuleConditionVO> ruleConditions,
                   final String dateCreated,
                   final String dateUpdated) {
@@ -115,6 +121,7 @@ public class RuleVO implements Serializable {
         this.loged = loged;
         this.sort = sort;
         this.handle = handle;
+        this.matchRestful = matchRestful;
         this.ruleConditions = ruleConditions;
         this.dateCreated = dateCreated;
         this.dateUpdated = dateUpdated;
@@ -281,7 +288,25 @@ public class RuleVO implements Serializable {
     public void setHandle(final String handle) {
         this.handle = handle;
     }
-
+    
+    /**
+     * get match restful.
+     *
+     * @return matchRestful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     /**
      * Gets the value of ruleConditions.
      *
@@ -355,7 +380,8 @@ public class RuleVO implements Serializable {
      */
     public static RuleVO buildRuleVO(final RuleDO ruleDO, final 
List<RuleConditionVO> ruleConditions) {
         return new RuleVO(ruleDO.getId(), ruleDO.getSelectorId(), 
ruleDO.getMatchMode(), MatchModeEnum.getMatchModeByCode(ruleDO.getMatchMode()),
-                ruleDO.getName(), ruleDO.getEnabled(), ruleDO.getLoged(), 
ruleDO.getSort(), ruleDO.getHandle(), ruleConditions,
+                ruleDO.getName(), ruleDO.getEnabled(), ruleDO.getLoged(), 
ruleDO.getSort(), ruleDO.getHandle(),
+                ruleDO.getMatchRestful(), ruleConditions,
                 
DateUtils.localDateTimeToString(ruleDO.getDateCreated().toLocalDateTime()),
                 
DateUtils.localDateTimeToString(ruleDO.getDateUpdated().toLocalDateTime()));
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/SelectorVO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/SelectorVO.java
index 420805b11..493dbe9e6 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/SelectorVO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/SelectorVO.java
@@ -86,6 +86,11 @@ public class SelectorVO implements Serializable {
      * whether continued.
      */
     private Boolean continued;
+    
+    /**
+     * match restful.
+     */
+    private Boolean matchRestful;
 
     private String handle;
 
@@ -118,6 +123,7 @@ public class SelectorVO implements Serializable {
                       final Boolean enabled,
                       final Boolean loged,
                       final Boolean continued,
+                      final Boolean matchRestful,
                       final String handle,
                       final List<SelectorConditionVO> selectorConditions,
                       final String dateCreated,
@@ -133,6 +139,7 @@ public class SelectorVO implements Serializable {
         this.enabled = enabled;
         this.loged = loged;
         this.continued = continued;
+        this.matchRestful = matchRestful;
         this.handle = handle;
         this.selectorConditions = selectorConditions;
         this.dateCreated = dateCreated;
@@ -336,7 +343,25 @@ public class SelectorVO implements Serializable {
     public void setContinued(final Boolean continued) {
         this.continued = continued;
     }
-
+    
+    /**
+     * get match restful value.
+     *
+     * @return matchRestful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set matchr restful value.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     /**
      * Gets the value of handle.
      *
@@ -427,9 +452,11 @@ public class SelectorVO implements Serializable {
      * @return {@linkplain SelectorVO}
      */
     public static SelectorVO buildSelectorVO(final SelectorDO selectorDO, 
final List<SelectorConditionVO> selectorConditions) {
-        return new SelectorVO(selectorDO.getId(), selectorDO.getPluginId(), 
selectorDO.getName(), selectorDO.getMatchMode(), 
MatchModeEnum.getMatchModeByCode(selectorDO.getMatchMode()),
-                selectorDO.getType(), 
SelectorTypeEnum.getSelectorTypeByCode(selectorDO.getType()), 
selectorDO.getSort(),
-                selectorDO.getEnabled(), selectorDO.getLoged(), 
selectorDO.getContinued(), selectorDO.getHandle(), selectorConditions,
+        return new SelectorVO(selectorDO.getId(), selectorDO.getPluginId(), 
selectorDO.getName(), selectorDO.getMatchMode(),
+                MatchModeEnum.getMatchModeByCode(selectorDO.getMatchMode()), 
selectorDO.getType(),
+                SelectorTypeEnum.getSelectorTypeByCode(selectorDO.getType()), 
selectorDO.getSort(),
+                selectorDO.getEnabled(), selectorDO.getLoged(), 
selectorDO.getContinued(),
+                selectorDO.getMatchRestful(), selectorDO.getHandle(), 
selectorConditions,
                 
DateUtils.localDateTimeToString(selectorDO.getDateCreated().toLocalDateTime()),
                 
DateUtils.localDateTimeToString(selectorDO.getDateUpdated().toLocalDateTime()));
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java
index 65ff9011a..67571aa0d 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java
@@ -299,6 +299,7 @@ public abstract class 
AbstractShenyuClientRegisterServiceImpl extends FallbackSh
                 .matchMode(MatchModeEnum.AND.getCode())
                 .enabled(Boolean.TRUE)
                 .loged(Boolean.TRUE)
+                .matchRestful(Boolean.FALSE)
                 .sort(1)
                 .handle(ruleHandler)
                 .build();
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/SelectorUtil.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/SelectorUtil.java
index 3256b1e12..becbf90b5 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/SelectorUtil.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/SelectorUtil.java
@@ -94,6 +94,7 @@ public final class SelectorUtil {
                 .enabled(Boolean.TRUE)
                 .loged(Boolean.TRUE)
                 .continued(Boolean.TRUE)
+                .matchRestful(Boolean.FALSE)
                 .sort(1)
                 .build();
     }
diff --git a/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml 
b/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
index e53fee421..b93278603 100644
--- a/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
@@ -28,6 +28,7 @@
         <result column="sort" jdbcType="INTEGER" property="sort"/>
         <result column="enabled" jdbcType="TINYINT" property="enabled"/>
         <result column="loged" jdbcType="TINYINT" property="loged"/>
+        <result column="match_restful" jdbcType="TINYINT" 
property="matchRestful"/>
         <result column="handle" jdbcType="VARCHAR" property="handle"/>
     </resultMap>
 
@@ -41,6 +42,7 @@
         sort,
         enabled,
         loged,
+        match_restful,
         handle
     </sql>
 
@@ -196,6 +198,7 @@
                          sort,
                          enabled,
                          loged,
+                         match_restful,
                          handle)
                   VALUES (#{id, jdbcType=VARCHAR},
                           #{dateCreated, jdbcType=TIMESTAMP},
@@ -206,6 +209,7 @@
                           #{sort, jdbcType=INTEGER},
                           #{enabled, jdbcType=TINYINT},
                           #{loged, jdbcType=TINYINT},
+                          #{matchRestful, jdbcType=TINYINT},
                           #{handle, jdbcType=VARCHAR})
     </insert>
 
@@ -237,6 +241,9 @@
             <if test="loged != null">
                 loged,
             </if>
+            <if test="matchRestful != null">
+                match_restful,
+            </if>
             <if test="handle != null">
                 handle,
             </if>
@@ -267,6 +274,9 @@
             <if test="loged != null">
                 #{loged, jdbcType=TINYINT},
             </if>
+            <if test="matchRestful != null">
+                #{matchRestful, jdbcType=TINYINT},
+            </if>
             <if test="handle != null">
                 #{handle, jdbcType=VARCHAR},
             </if>
@@ -275,15 +285,16 @@
 
     <update id="update" 
parameterType="org.apache.shenyu.admin.model.entity.RuleDO">
         UPDATE rule
-           SET date_created = #{dateCreated, jdbcType=TIMESTAMP},
-               date_updated = #{dateUpdated, jdbcType=TIMESTAMP},
-               selector_id  = #{selectorId, jdbcType=VARCHAR},
-               name         = #{name, jdbcType=VARCHAR},
-               match_mode   = #{matchMode, jdbcType=INTEGER},
-               sort         = #{sort, jdbcType=INTEGER},
-               enabled      = #{enabled, jdbcType=TINYINT},
-               loged        = #{loged, jdbcType=TINYINT},
-               handle       = #{handle, jdbcType=VARCHAR}
+           SET date_created  = #{dateCreated, jdbcType=TIMESTAMP},
+               date_updated  = #{dateUpdated, jdbcType=TIMESTAMP},
+               selector_id   = #{selectorId, jdbcType=VARCHAR},
+               name          = #{name, jdbcType=VARCHAR},
+               match_mode    = #{matchMode, jdbcType=INTEGER},
+               sort          = #{sort, jdbcType=INTEGER},
+               enabled       = #{enabled, jdbcType=TINYINT},
+               loged         = #{loged, jdbcType=TINYINT},
+               match_restful = #{matchRestful, jdbcType=TINYINT},
+               handle        = #{handle, jdbcType=VARCHAR}
          WHERE id = #{id, jdbcType=VARCHAR}
     </update>
 
@@ -314,6 +325,9 @@
             <if test="loged != null">
                 loged = #{loged, jdbcType=TINYINT},
             </if>
+            <if test="matchRestful != null">
+                match_restful = #{matchRestful, jdbcType=TINYINT},
+            </if>
             <if test="handle != null">
                 handle = #{handle, jdbcType=VARCHAR},
             </if>
diff --git a/shenyu-admin/src/main/resources/mappers/selector-sqlmap.xml 
b/shenyu-admin/src/main/resources/mappers/selector-sqlmap.xml
index 039a434a4..0f78fb036 100644
--- a/shenyu-admin/src/main/resources/mappers/selector-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/selector-sqlmap.xml
@@ -30,6 +30,7 @@
         <result column="enabled" jdbcType="TINYINT" property="enabled"/>
         <result column="loged" jdbcType="TINYINT" property="loged"/>
         <result column="continued" jdbcType="TINYINT" property="continued"/>
+        <result column="match_restful" jdbcType="TINYINT" 
property="matchRestful"/>
         <result column="handle" jdbcType="VARCHAR" property="handle"/>
     </resultMap>
 
@@ -45,6 +46,7 @@
         enabled,
         loged,
         continued,
+        match_restful,
         handle
     </sql>
 
@@ -204,6 +206,7 @@
                     enabled,
                     loged,
                     continued,
+                    match_restful,
                     handle)
             VALUES
                     (#{id, jdbcType=VARCHAR},
@@ -217,6 +220,7 @@
                     #{enabled, jdbcType=TINYINT},
                     #{loged, jdbcType=TINYINT},
                     #{continued, jdbcType=TINYINT},
+                    #{matchRestful, jdbcType=TINYINT},
                     #{handle, jdbcType=VARCHAR})
     </insert>
 
@@ -254,6 +258,9 @@
             <if test="continued != null">
                 continued,
             </if>
+            <if test="matchRestful != null">
+                match_restful,
+            </if>
             <if test="handle != null">
                 handle,
             </if>
@@ -290,6 +297,9 @@
             <if test="continued != null">
                 #{continued, jdbcType=TINYINT},
             </if>
+            <if test="matchRestful != null">
+                #{matchRestful, jdbcType=TINYINT},
+            </if>
             <if test="handle != null">
                 #{handle, jdbcType=VARCHAR},
             </if>
@@ -309,6 +319,7 @@
                enabled = #{enabled, jdbcType=TINYINT},
                loged = #{loged, jdbcType=TINYINT},
                continued = #{continued, jdbcType=TINYINT},
+               match_restful = #{matchRestful, jdbcType=TINYINT},
                handle = #{handle, jdbcType=VARCHAR}
          WHERE id = #{id, jdbcType=VARCHAR}
     </update>
@@ -346,6 +357,9 @@
             <if test="continued != null">
                 continued = #{continued, jdbcType=TINYINT},
             </if>
+            <if test="matchRestful != null">
+                match_restful = #{matchRestful, jdbcType=TINYINT},
+            </if>
             <if test="handle != null">
                 handle = #{handle, jdbcType=VARCHAR},
             </if>
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 3411f9c84..bae3b181d 100755
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -67,6 +67,7 @@ CREATE TABLE IF NOT EXISTS `selector` (
   `enabled` tinyint(4) NOT NULL COMMENT 'whether to open',
   `loged` tinyint(4) NOT NULL COMMENT 'whether to print the log',
   `continued` tinyint(4) NOT NULL COMMENT 'whether to continue execution',
+  `match_restful` tinyint(4) NOT NULL COMMENT 'whether to match restful(0 
cache, 1 not cache)',
   `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create 
time',
   `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE 
CURRENT_TIMESTAMP COMMENT 'update time'
 );
@@ -92,6 +93,7 @@ CREATE TABLE IF NOT EXISTS `rule` (
   `name` varchar(128) NOT NULL COMMENT 'rule name',
   `enabled` tinyint(4) NOT NULL COMMENT 'whether to open',
   `loged` tinyint(4) NOT NULL COMMENT 'whether to log or not',
+  `match_restful` tinyint(4) NOT NULL COMMENT 'whether to match restful(0 
cache, 1 not cache)',
   `sort` int(4) NOT NULL COMMENT 'sort',
   `handle` varchar(1024) DEFAULT NULL COMMENT 'processing logic (here for 
different plug-ins, there will be different fields to identify different 
processes, all data in JSON format is stored)',
   `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create 
time',
diff --git a/shenyu-admin/src/main/resources/static/index.2c016d57.js 
b/shenyu-admin/src/main/resources/static/index.2c016d57.js
new file mode 100644
index 000000000..555a3b2b6
--- /dev/null
+++ b/shenyu-admin/src/main/resources/static/index.2c016d57.js
@@ -0,0 +1 @@
+!function(e){function t(r){if(n[r])return n[r].exports;var 
o=n[r]={i:r,l:!1,exports:{}};return 
e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var 
n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var
 n=e&&e.__esModule?function(){return e.default}:function(){return e};return 
t.d(n,"a",n),n},t.o=function(e,t){return 
Object.prototype.hasOwnProperty.call(e,t)},t.p="/",t(t.s="lVK7")}({"+0it":function(e,t,n){"u
 [...]
\ No newline at end of file
diff --git a/shenyu-admin/src/main/resources/static/index.98c5ed36.css 
b/shenyu-admin/src/main/resources/static/index.7904889c.css
similarity index 99%
rename from shenyu-admin/src/main/resources/static/index.98c5ed36.css
rename to shenyu-admin/src/main/resources/static/index.7904889c.css
index 8a7ebd914..1943058a7 100644
--- a/shenyu-admin/src/main/resources/static/index.98c5ed36.css
+++ b/shenyu-admin/src/main/resources/static/index.7904889c.css
@@ -1,5 +1,5 @@
-#root,body,html{height:100%}.plug-content-wrap{padding:24px}.open{color:#14c974}.close{color:#ff586d}.ant-layout{min-height:100%}ol,ul{list-style:none}.ant-table{background:#fff}.table-selected{background:#98cdff}.edit{cursor:pointer}.edit,.edit:hover{color:#1890ff}.searchblock{display:-ms-flexbox!important;display:flex!important}.searchblock
 button{margin-left:30px}.ant-table 
table{padding:0!important}.ant-table-small>.ant-table-content>.ant-table-body{margin:0!important}.table-header{d
 [...]
-  /*! autoprefixer: ignore next 
*/-webkit-box-orient:vertical;overflow:hidden}.optionParts___1KtSu{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center}.optionParts___1KtSu
 
div:first-child{margin-right:16px}.condition___2ujo0{margin-top:8px;display:-ms-flexbox;display:flex}.condition___2ujo0
 ul{padding:0 0 10px 
6px;margin:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:top;align-items:top}.condition___2ujo0
 ul  [...]
+#root,body,html{height:100%}.plug-content-wrap{padding:24px}.open{color:#14c974}.close{color:#ff586d}.ant-layout{min-height:100%}ol,ul{list-style:none}.ant-table{background:#fff}.table-selected{background:#98cdff}.edit{cursor:pointer}.edit,.edit:hover{color:#1890ff}.searchblock{display:-ms-flexbox!important;display:flex!important}.searchblock
 button{margin-left:30px}.ant-table 
table{padding:0!important}.ant-table-small>.ant-table-content>.ant-table-body{margin:0!important}.table-header{d
 [...]
+  /*! autoprefixer: ignore next 
*/-webkit-box-orient:vertical;overflow:hidden}.optionParts___3Uy6m{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center}.optionParts___3Uy6m
 
div:first-child{margin-right:16px}.condition___34I17{margin-top:8px;display:-ms-flexbox;display:flex}.condition___34I17
 ul{padding:0 0 10px 
6px;margin:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:top;align-items:top}.condition___34I17
 ul  [...]
  * 
  * antd v3.26.20
  * 
@@ -7,4 +7,4 @@
  * All rights reserved.
  *       
  
*/body,html{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,:after,:before{-webkit-box-sizing:border-box;box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;color:rgba(0,0,0,.65);font-si
 [...]
-  /*! autoprefixer: ignore next 
*/-webkit-box-orient:vertical;overflow:hidden}.ant-upload{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;-webkit-font-feature-settings:"tnum";font-feature-settings:"tnum";outline:0}.ant-upload
 p{margin:0}.ant-upload-btn{display:block;width:100%;outline:none}.ant-upload 
input[type=file]{cursor:pointer}.ant-upload.ant-upload-select{display:i [...]
\ No newline at end of file
+  /*! autoprefixer: ignore next 
*/-webkit-box-orient:vertical;overflow:hidden}.ant-upload{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;-webkit-font-feature-settings:"tnum";font-feature-settings:"tnum";outline:0}.ant-upload
 p{margin:0}.ant-upload-btn{display:block;width:100%;outline:none}.ant-upload 
input[type=file]{cursor:pointer}.ant-upload.ant-upload-select{display:i [...]
\ No newline at end of file
diff --git a/shenyu-admin/src/main/resources/static/index.e0e89752.js 
b/shenyu-admin/src/main/resources/static/index.e0e89752.js
deleted file mode 100644
index 0a5f428c8..000000000
--- a/shenyu-admin/src/main/resources/static/index.e0e89752.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e){function t(r){if(n[r])return n[r].exports;var 
o=n[r]={i:r,l:!1,exports:{}};return 
e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var 
n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var
 n=e&&e.__esModule?function(){return e.default}:function(){return e};return 
t.d(n,"a",n),n},t.o=function(e,t){return 
Object.prototype.hasOwnProperty.call(e,t)},t.p="/",t(t.s="lVK7")}({"+0it":function(e,t,n){"u
 [...]
\ No newline at end of file
diff --git a/shenyu-admin/src/main/resources/static/index.html 
b/shenyu-admin/src/main/resources/static/index.html
index a4b46b064..4a0423444 100644
--- a/shenyu-admin/src/main/resources/static/index.html
+++ b/shenyu-admin/src/main/resources/static/index.html
@@ -24,11 +24,11 @@
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Apache ShenYu Gateway</title>
   <link rel="icon" href="/favicon.png" type="image/x-icon">
-<link href="/index.98c5ed36.css" rel="stylesheet"></head>
+<link href="/index.7904889c.css" rel="stylesheet"></head>
 
 <body>
   <div id="httpPath" style="display: none" th:text="${domain}"></div>
   <div id="root"></div>
-<script type="text/javascript" src="/index.c7c7b3e8.js"></script></body>
+<script type="text/javascript" src="/index.2c016d57.js"></script></body>
 
 </html>
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RuleControllerTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RuleControllerTest.java
index a6a8668fb..d4f177a67 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RuleControllerTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RuleControllerTest.java
@@ -87,7 +87,7 @@ public final class RuleControllerTest {
 
     private final List<RuleConditionVO> rcList = new 
ArrayList<>(Collections.singletonList(rCondition1));
 
-    private final RuleVO ruleVO = new RuleVO("666", "168", 0, "zero mode", 
"/http/test/**", true, true, 1, 
"{\"loadBalance\":\"random\",\"retry\":0,\"timeout\":3000}",
+    private final RuleVO ruleVO = new RuleVO("666", "168", 0, "zero mode", 
"/http/test/**", true, true, 1, 
"{\"loadBalance\":\"random\",\"retry\":0,\"timeout\":3000}", false,
             rcList, DateUtils.localDateTimeToString(LocalDateTime.now()), 
DateUtils.localDateTimeToString(LocalDateTime.now()));
     
     private final CommonPager<RuleVO> commonPager = new CommonPager<>(new 
PageParameter(), Collections.singletonList(ruleVO));
@@ -147,6 +147,7 @@ public final class RuleControllerTest {
                 .name("/http/order/save")
                 .enabled(true)
                 .loged(true)
+                .matchRestful(false)
                 .sort(1)
                 
.handle("{\"loadBalance\":\"random\",\"retry\":0,\"timeout\":3000}")
                 .ruleConditions(conList)
@@ -186,6 +187,7 @@ public final class RuleControllerTest {
                 .name("/http/order/update")
                 .enabled(true)
                 .loged(true)
+                .matchRestful(false)
                 .sort(1)
                 
.handle("{\"loadBalance\":\"random\",\"retry\":0,\"timeout\":3000}")
                 .ruleConditions(conList)
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/SelectorControllerTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/SelectorControllerTest.java
index 977f5df2b..11aab8cde 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/SelectorControllerTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/SelectorControllerTest.java
@@ -81,7 +81,7 @@ public final class SelectorControllerTest {
     
     private final SelectorVO selectorVO = new SelectorVO("1", "2", 
"selector-1", MatchModeEnum.AND.getCode(),
             MatchModeEnum.AND.getName(), SelectorTypeEnum.FULL_FLOW.getCode(), 
SelectorTypeEnum.FULL_FLOW.getName(),
-            1, true, true, true, "handle", Collections.emptyList(),
+            1, true, true, true, false, "handle", Collections.emptyList(),
             DateUtils.localDateTimeToString(LocalDateTime.now()), 
DateUtils.localDateTimeToString(LocalDateTime.now()));
 
     private final CommonPager<SelectorVO> commonPager = new CommonPager<>(new 
PageParameter(), Collections.singletonList(selectorVO));
@@ -118,6 +118,7 @@ public final class SelectorControllerTest {
                 .type(1)
                 .loged(true)
                 .enabled(true)
+                .matchRestful(false)
                 .pluginId("2")
                 .sort(1)
                 .build();
@@ -144,6 +145,7 @@ public final class SelectorControllerTest {
                 .type(1)
                 .loged(true)
                 .enabled(true)
+                .matchRestful(false)
                 .pluginId("2")
                 .sort(1)
                 .build();
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
index 26ea85ead..5e2faef99 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
@@ -199,6 +199,7 @@ public final class RuleMapperTest extends 
AbstractSpringIntegrationTest {
                 .loged(true)
                 .matchMode(1)
                 .selectorId("test-selector-1")
+                .matchRestful(false)
                 .sort(1)
                 .dateCreated(now)
                 .dateUpdated(now)
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/SelectorMapperTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/SelectorMapperTest.java
index 608b69b3f..0aff02383 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/SelectorMapperTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/SelectorMapperTest.java
@@ -234,6 +234,7 @@ public final class SelectorMapperTest extends 
AbstractSpringIntegrationTest {
                 .sort(1)
                 .enabled(Boolean.TRUE)
                 .loged(Boolean.TRUE)
+                .matchRestful(false)
                 .continued(Boolean.TRUE)
                 .handle("handle")
                 .build();
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DataPermissionServiceTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DataPermissionServiceTest.java
index 5c5758950..48e9083ab 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DataPermissionServiceTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/DataPermissionServiceTest.java
@@ -78,13 +78,13 @@ public final class DataPermissionServiceTest {
 
     @BeforeEach
     public void setup() {
-        ruleDTO = new RuleDTO("1", "1", 1, "test", true, true, 1, "test", 
null);
+        ruleDTO = new RuleDTO("1", "1", 1, "test", true, true, 1, "test", 
null, false);
         dataPermissionDTO = new DataPermissionDTO();
         dataPermissionDTO.setId("1");
         dataPermissionDTO.setUserId("1001");
         dataPermissionDTO.setDataId("1");
         dataPermissionDTO.setIsSelected(true);
-        selectorDTO = new SelectorDTO("1", "1", "test", 1, 1, 1, true, false, 
true, "test", null);
+        selectorDTO = new SelectorDTO("1", "1", "test", 1, 1, 1, true, false, 
true, "test", null, false);
     }
 
     @Test
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/RuleData.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/RuleData.java
index b6f0391b4..62b01c384 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/RuleData.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/RuleData.java
@@ -54,6 +54,11 @@ public class RuleData {
     private List<ConditionData> conditionDataList;
 
     private List<ConditionData> beforeConditionDataList;
+    
+    /**
+     * match restful.
+     */
+    private Boolean matchRestful;
 
     /**
      * no args constructor.
@@ -78,6 +83,7 @@ public class RuleData {
         this.handle = builder.handle;
         this.conditionDataList = builder.conditionDataList;
         this.beforeConditionDataList = builder.beforeConditionDataList;
+        this.matchRestful = builder.matchRestful;
     }
 
     /**
@@ -306,7 +312,25 @@ public class RuleData {
     public void setBeforeConditionDataList(final List<ConditionData> 
beforeConditionDataList) {
         this.beforeConditionDataList = beforeConditionDataList;
     }
-
+    
+    /**
+     * get match restful.
+     *
+     * @return matchRestful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
@@ -326,12 +350,14 @@ public class RuleData {
                 && Objects.equals(loged, ruleData.loged)
                 && Objects.equals(handle, ruleData.handle)
                 && Objects.equals(conditionDataList, 
ruleData.conditionDataList)
-                && Objects.equals(beforeConditionDataList, 
ruleData.beforeConditionDataList);
+                && Objects.equals(beforeConditionDataList, 
ruleData.beforeConditionDataList)
+                && Objects.equals(matchRestful, ruleData.matchRestful);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, name, pluginName, selectorId, matchMode, sort, 
enabled, loged, handle, conditionDataList, beforeConditionDataList);
+        return Objects.hash(id, name, pluginName, selectorId, matchMode, sort, 
enabled, loged, handle, conditionDataList,
+                beforeConditionDataList, matchRestful);
     }
 
     @Override
@@ -362,6 +388,8 @@ public class RuleData {
                 + '\''
                 + ", conditionDataList="
                 + conditionDataList
+                + ", matchRestful="
+                + matchRestful
                 + '}';
     }
 
@@ -391,7 +419,8 @@ public class RuleData {
         private List<ConditionData> conditionDataList;
 
         private List<ConditionData> beforeConditionDataList;
-
+        
+        private Boolean matchRestful;
 
         /**
          * no args constructor.
@@ -528,5 +557,16 @@ public class RuleData {
             this.beforeConditionDataList = beforeConditionDataList;
             return this;
         }
+    
+        /**
+         * build match restful.
+         *
+         * @param matchRestful matchRestful
+         * @return this
+         */
+        public Builder matchRestful(final Boolean matchRestful) {
+            this.matchRestful = matchRestful;
+            return this;
+        }
     }
 }
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/SelectorData.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/SelectorData.java
index e446b1ab3..72efbef48 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/SelectorData.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/SelectorData.java
@@ -59,6 +59,11 @@ public class SelectorData {
     private String handle;
 
     private List<ConditionData> conditionList;
+    
+    /**
+     * match restful api.
+     */
+    private Boolean matchRestful;
 
     /**
      * no args constructor.
@@ -84,6 +89,7 @@ public class SelectorData {
         this.continued = builder.continued;
         this.handle = builder.handle;
         this.conditionList = builder.conditionList;
+        this.matchRestful = builder.matchRestful;
     }
 
     /**
@@ -310,7 +316,25 @@ public class SelectorData {
     public void setConditionList(final List<ConditionData> conditionList) {
         this.conditionList = conditionList;
     }
-
+    
+    /**
+     * get match restful.
+     *
+     * @return match restful
+     */
+    public Boolean getMatchRestful() {
+        return matchRestful;
+    }
+    
+    /**
+     * set match restful.
+     *
+     * @param matchRestful matchRestful
+     */
+    public void setMatchRestful(final Boolean matchRestful) {
+        this.matchRestful = matchRestful;
+    }
+    
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
@@ -323,12 +347,13 @@ public class SelectorData {
         return Objects.equals(id, that.id) && Objects.equals(pluginId, 
that.pluginId) && Objects.equals(pluginName, that.pluginName)
                 && Objects.equals(name, that.name) && 
Objects.equals(matchMode, that.matchMode) && Objects.equals(type, that.type)
                 && Objects.equals(sort, that.sort) && Objects.equals(enabled, 
that.enabled) && Objects.equals(logged, that.logged)
-                && Objects.equals(continued, that.continued) && 
Objects.equals(handle, that.handle) && Objects.equals(conditionList, 
that.conditionList);
+                && Objects.equals(continued, that.continued) && 
Objects.equals(handle, that.handle)
+                && Objects.equals(conditionList, that.conditionList) && 
Objects.equals(matchRestful, that.matchRestful);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, pluginId, pluginName, name, matchMode, type, 
sort, enabled, logged, continued, handle, conditionList);
+        return Objects.hash(id, pluginId, pluginName, name, matchMode, type, 
sort, enabled, logged, continued, handle, conditionList, matchRestful);
     }
 
     @Override
@@ -363,6 +388,8 @@ public class SelectorData {
                 + '\''
                 + ", conditionList="
                 + conditionList
+                + ", matchRestful="
+                + matchRestful
                 + '}';
     }
 
@@ -394,6 +421,8 @@ public class SelectorData {
         private String handle;
 
         private List<ConditionData> conditionList;
+        
+        private Boolean matchRestful;
 
         /**
          * no args constructor.
@@ -541,5 +570,16 @@ public class SelectorData {
             this.conditionList = conditionList;
             return this;
         }
+    
+        /**
+         * build match restful.
+         *
+         * @param matchRestful matchRestful
+         * @return this
+         */
+        public Builder matchRestful(final Boolean matchRestful) {
+            this.matchRestful = matchRestful;
+            return this;
+        }
     }
 }
diff --git a/shenyu-e2e/pom.xml b/shenyu-e2e/pom.xml
index a15b07742..79a54508c 100644
--- a/shenyu-e2e/pom.xml
+++ b/shenyu-e2e/pom.xml
@@ -233,6 +233,7 @@
                 <configuration>
                     <source>${java.version}</source>
                     <target>${java.version}</target>
+                    <fork>true</fork>
                 </configuration>
             </plugin>
 
diff --git 
a/shenyu-e2e/shenyu-e2e-case/src/main/java/org/apache/shenyu/e2e/testcase/common/ResourceDataTemplate.java
 
b/shenyu-e2e/shenyu-e2e-case/src/main/java/org/apache/shenyu/e2e/testcase/common/ResourceDataTemplate.java
index 78189321d..3c19bfd2b 100644
--- 
a/shenyu-e2e/shenyu-e2e-case/src/main/java/org/apache/shenyu/e2e/testcase/common/ResourceDataTemplate.java
+++ 
b/shenyu-e2e/shenyu-e2e-case/src/main/java/org/apache/shenyu/e2e/testcase/common/ResourceDataTemplate.java
@@ -48,6 +48,7 @@ public class ResourceDataTemplate {
                 .continued(true)
                 .logged(true)
                 .enabled(true)
+                .matchRestful(false)
                 .sort(1);
     }
     
@@ -62,6 +63,7 @@ public class ResourceDataTemplate {
                 .selectorId(selectorId)
                 .enabled(true)
                 .logged(true)
+                .matchRestful(false)
                 .sort(1);
     }
     
diff --git 
a/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/RuleData.java
 
b/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/RuleData.java
index e563d5a75..5bbdfcecb 100644
--- 
a/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/RuleData.java
+++ 
b/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/RuleData.java
@@ -18,17 +18,13 @@
 package org.apache.shenyu.e2e.client.admin.model.data;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import lombok.Builder;
 import lombok.Data;
 import org.apache.shenyu.e2e.client.admin.model.MatchMode;
 import org.apache.shenyu.e2e.client.admin.model.handle.RuleHandle;
-import org.apache.shenyu.e2e.common.IdManagers.Selectors;
+import org.apache.shenyu.e2e.client.admin.model.handle.RuleHandle.Serializer;
 
-import java.io.IOException;
 import java.util.List;
 
 @Data
@@ -48,7 +44,7 @@ public class RuleData implements ResourceData {
     
     private int sort;
     
-    @JsonSerialize(using = RuleHandle.Serializer.class)
+    @JsonSerialize(using = Serializer.class)
     private RuleHandle handle;
     
     @JsonProperty("ruleConditions")
@@ -56,4 +52,5 @@ public class RuleData implements ResourceData {
     
     private boolean enabled;
     
+    private Boolean matchRestful;
 }
diff --git 
a/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/SelectorData.java
 
b/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/SelectorData.java
index 070936cc9..a38e1edef 100644
--- 
a/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/SelectorData.java
+++ 
b/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/model/data/SelectorData.java
@@ -64,6 +64,7 @@ public class SelectorData implements ResourceData {
     
     private int sort;
     
+    private boolean matchRestful;
     static class PluginHandleSerializer extends JsonSerializer<PluginHandle> {
         private static final ObjectMapper mapper = new ObjectMapper();
         
@@ -74,4 +75,4 @@ public class SelectorData implements ResourceData {
         }
     }
     
-}
\ No newline at end of file
+}
diff --git 
a/shenyu-e2e/shenyu-e2e-client/src/test/java/org/apache/shenyu/e2e/client/admin/AdminClientTest.java
 
b/shenyu-e2e/shenyu-e2e-client/src/test/java/org/apache/shenyu/e2e/client/admin/AdminClientTest.java
index 055c69ee7..dac2d74ee 100644
--- 
a/shenyu-e2e/shenyu-e2e-client/src/test/java/org/apache/shenyu/e2e/client/admin/AdminClientTest.java
+++ 
b/shenyu-e2e/shenyu-e2e-client/src/test/java/org/apache/shenyu/e2e/client/admin/AdminClientTest.java
@@ -96,6 +96,7 @@ public class AdminClientTest {
                 .logged(true)
                 .enabled(true)
                 .continued(true)
+                .matchRestful(false)
                 
.handle(Upstreams.builder().add(Upstream.builder().upstreamUrl("httpbin.org:80").build()).build())
                 .conditionList(
                         
Lists.newArrayList(Condition.builder().paramType(ParamType.URI).operator(Operator.MATCH).paramName("/").paramValue("/**").build())
@@ -108,6 +109,7 @@ public class AdminClientTest {
                 .name("test-create-rule")
                 .enabled(true)
                 .logged(true)
+                .matchRestful(false)
                 .handle(DivideRuleHandle.builder()
                         .loadBalance("hash")
                         .retryStrategy("current")
@@ -139,6 +141,7 @@ public class AdminClientTest {
                 .logged(true)
                 .enabled(true)
                 .continued(true)
+                .matchRestful(false)
                 
.handle(Upstreams.builder().add(Upstream.builder().upstreamUrl("httpbin.org:80").build()).build())
                 .conditionList(
                         
Lists.newArrayList(Condition.builder().paramType(ParamType.URI).operator(Operator.MATCH).paramName("/").paramValue("/**").build())
@@ -169,6 +172,7 @@ public class AdminClientTest {
                         .requestMaxSize(10240)
                         .build())
                 .sort(1)
+                .matchRestful(false)
                 .matchMode(MatchMode.AND)
                 .selectorId(selector.getId())
                 .conditionList(Lists.newArrayList(Condition.builder()
@@ -194,6 +198,7 @@ public class AdminClientTest {
                     .logged(true)
                     .enabled(true)
                     .continued(true)
+                    .matchRestful(false)
                     
.handle(Upstreams.builder().add(Upstream.builder().upstreamUrl("httpbin.org:80").build()).build())
                     .conditionList(
                             
Lists.newArrayList(Condition.builder().paramType(ParamType.URI).operator(Operator.MATCH).paramName("/").paramValue("/**").build())
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
index 1e9e627a1..561377b2d 100644
--- 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
@@ -23,6 +23,7 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -144,13 +145,15 @@ public abstract class AbstractShenyuPlugin implements 
ShenyuPlugin {
                     Pair<Boolean, RuleData> matchRuleData = 
matchRule(exchange, rules);
                     ruleData = matchRuleData.getRight();
                     if (matchRuleData.getLeft()) {
+                        ruleData = Optional.ofNullable(ruleData)
+                                
.orElse(RuleData.builder().pluginName(pluginName).matchRestful(false).build());
                         cacheRuleData(path, ruleData);
                     }
                 }
             }
-            if (Objects.isNull(ruleData)) {
-                return handleRuleIfNull(pluginName, exchange, chain);
-            }
+        }
+        if (Objects.isNull(ruleData) || Objects.isNull(ruleData.getId())) {
+            return handleRuleIfNull(pluginName, exchange, chain);
         }
         printLog(ruleData, pluginName);
         return doExecute(exchange, chain, selectorData, ruleData);
@@ -169,6 +172,10 @@ public abstract class AbstractShenyuPlugin implements 
ShenyuPlugin {
         if (Objects.isNull(selectorData)) {
             return;
         }
+        if (Objects.isNull(selectorData.getMatchRestful())
+                || (Objects.nonNull(selectorData.getMatchRestful()) && 
selectorData.getMatchRestful())) {
+            return;
+        }
         if (StringUtils.isBlank(selectorData.getId())) {
             MatchDataCache.getInstance().cacheSelectorData(path, selectorData, 
getSelectorMaxFreeMemory());
             return;
@@ -283,6 +290,11 @@ public abstract class AbstractShenyuPlugin implements 
ShenyuPlugin {
         if (Objects.isNull(ruleData)) {
             return;
         }
+        // if the field of matchRestful is true, not cache rule data. the 
field is false, cache rule data.
+        if (Objects.isNull(ruleData.getMatchRestful())
+                || (Objects.nonNull(ruleData.getMatchRestful()) && 
ruleData.getMatchRestful())) {
+            return;
+        }
         int initialCapacity = matchCacheConfig.getRule().getInitialCapacity();
         long maximumSize = matchCacheConfig.getRule().getMaximumSize();
         if (StringUtils.isBlank(ruleData.getId())) {
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MatchDataCache.java
 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MatchDataCache.java
index 879e2ef5f..61a6d96d5 100644
--- 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MatchDataCache.java
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MatchDataCache.java
@@ -137,4 +137,5 @@ public final class MatchDataCache {
         final Map<String, RuleData> lruMap = RULE_DATA_MAP.get(pluginName);
         return Optional.ofNullable(lruMap).orElse(Maps.newHashMap()).get(path);
     }
+    
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/trie/ShenyuTrie.java
 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/trie/ShenyuTrie.java
index 2039b8b50..6129aa231 100644
--- 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/trie/ShenyuTrie.java
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/trie/ShenyuTrie.java
@@ -312,7 +312,6 @@ public class ShenyuTrie {
             // node is not null, judge exist many plugin mapping
             if (Objects.nonNull(currentNode) && 
Objects.nonNull(currentNode.getPathRuleCache())) {
                 // check current mapping
-                currentNode.getPathRuleCache().cleanUp();
                 List<RuleData> ruleDataList = 
getVal(currentNode.getPathRuleCache(), ruleData.getSelectorId());
                 if (CollectionUtils.isNotEmpty(ruleDataList) && 
ruleDataList.size() == 1 && Objects.isNull(currentNode.getChildren())) {
                     // remove current node from parent node
@@ -327,6 +326,7 @@ public class ShenyuTrie {
                     if (CollectionUtils.isNotEmpty(delRuleData)) {
                         synchronized (ruleData.getSelectorId()) {
                             delRuleData.removeIf(rule -> 
rule.getId().equals(ruleData.getSelectorId()));
+                            
currentNode.getPathRuleCache().put(ruleData.getSelectorId(), delRuleData);
                         }
                     }
                 }
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/AbstractShenyuPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/AbstractShenyuPluginTest.java
index 1165a68d7..c2b450713 100644
--- 
a/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/AbstractShenyuPluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/AbstractShenyuPluginTest.java
@@ -73,6 +73,7 @@ public final class AbstractShenyuPluginTest {
                 .selectorId("1")
                 .enabled(true)
                 .loged(true)
+                .matchRestful(false)
                 .sort(1).build();
         this.conditionData = new ConditionData();
         this.conditionData.setOperator("match");
@@ -86,6 +87,7 @@ public final class AbstractShenyuPluginTest {
         this.selectorData = SelectorData.builder()
                 .id("1").pluginName("SHENYU")
                 .enabled(true)
+                .matchRestful(false)
                 .type(SelectorTypeEnum.CUSTOM_FLOW.getCode()).build();
         this.testShenyuPlugin = spy(new TestShenyuPlugin());
         this.exchange = 
MockServerWebExchange.from(MockServerHttpRequest.get("/http/SHENYU/SHENYU")
@@ -132,6 +134,7 @@ public final class AbstractShenyuPluginTest {
         List<ConditionData> conditionDataList = 
Collections.singletonList(conditionData);
         this.selectorData.setMatchMode(0);
         this.selectorData.setLogged(true);
+        this.selectorData.setMatchRestful(false);
         this.selectorData.setConditionList(conditionDataList);
         BaseDataCache.getInstance().cachePluginData(pluginData);
         BaseDataCache.getInstance().cacheSelectData(selectorData);
@@ -147,7 +150,9 @@ public final class AbstractShenyuPluginTest {
         List<ConditionData> conditionDataList = 
Collections.singletonList(conditionData);
         this.ruleData.setConditionDataList(conditionDataList);
         this.ruleData.setMatchMode(0);
+        this.ruleData.setMatchRestful(false);
         this.selectorData.setMatchMode(0);
+        this.selectorData.setMatchRestful(false);
         this.selectorData.setLogged(true);
         this.selectorData.setConditionList(conditionDataList);
         BaseDataCache.getInstance().cachePluginData(pluginData);
@@ -186,6 +191,7 @@ public final class AbstractShenyuPluginTest {
         List<ConditionData> conditionDataList = 
Collections.singletonList(conditionData);
         this.ruleData.setConditionDataList(conditionDataList);
         this.ruleData.setMatchMode(0);
+        this.ruleData.setMatchRestful(false);
         this.selectorData.setMatchMode(0);
         this.selectorData.setLogged(true);
         this.selectorData.setConditionList(conditionDataList);
@@ -199,6 +205,7 @@ public final class AbstractShenyuPluginTest {
                 .enabled(true)
                 .loged(true)
                 .matchMode(0)
+                .matchRestful(false)
                 .conditionDataList(Collections.singletonList(conditionData))
                 .sort(1).build());
 
@@ -209,8 +216,9 @@ public final class AbstractShenyuPluginTest {
                 .enabled(true)
                 .loged(true)
                 .matchMode(0)
+                .matchRestful(false)
                 .conditionDataList(Collections.singletonList(conditionData))
-                .sort(1).build());
+                .sort(2).build());
         StepVerifier.create(testShenyuPlugin.execute(exchange, 
shenyuPluginChain)).expectSubscription().verifyComplete();
         verify(testShenyuPlugin).doExecute(exchange, shenyuPluginChain, 
selectorData, ruleData);
     }
@@ -223,7 +231,9 @@ public final class AbstractShenyuPluginTest {
         List<ConditionData> conditionDataList = 
Collections.singletonList(conditionData);
         this.ruleData.setConditionDataList(conditionDataList);
         this.ruleData.setMatchMode(1);
+        this.ruleData.setMatchRestful(false);
         this.selectorData.setMatchMode(0);
+        this.selectorData.setMatchRestful(false);
         this.selectorData.setType(SelectorTypeEnum.FULL_FLOW.getCode());
         this.selectorData.setLogged(true);
         this.selectorData.setConditionList(conditionDataList);
diff --git 
a/shenyu-web/src/main/java/org/apache/shenyu/web/controller/LocalPluginController.java
 
b/shenyu-web/src/main/java/org/apache/shenyu/web/controller/LocalPluginController.java
index 5f2dc9f53..ab2f181b7 100644
--- 
a/shenyu-web/src/main/java/org/apache/shenyu/web/controller/LocalPluginController.java
+++ 
b/shenyu-web/src/main/java/org/apache/shenyu/web/controller/LocalPluginController.java
@@ -205,6 +205,7 @@ public class LocalPluginController {
         subscriber.onSelectorSubscribe(result);
         RuleData ruleData = RuleData.builder()
                 .selectorId(result.getId())
+                .matchRestful(Boolean.FALSE)
                 .pluginName(selectorRuleData.getPluginName())
                 .handle(selectorRuleData.getRuleHandler())
                 .conditionDataList(selectorRuleData.getConditionDataList())
@@ -356,6 +357,9 @@ public class LocalPluginController {
         if (Objects.isNull(selectorData.getLogged())) {
             selectorData.setLogged(false);
         }
+        if (Objects.isNull(selectorData.getMatchRestful())) {
+            selectorData.setMatchRestful(false);
+        }
         return selectorData;
     }
 
@@ -378,6 +382,9 @@ public class LocalPluginController {
         if (Objects.isNull(ruleData.getLoged())) {
             ruleData.setLoged(false);
         }
+        if (Objects.isNull(ruleData.getMatchRestful())) {
+            ruleData.setMatchRestful(false);
+        }
         return ruleData;
     }
 

Reply via email to