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 e1a774534 [ISSUE #4395] cryptor plugin support multi fieldNames. 
(#4435)
e1a774534 is described below

commit e1a774534a5ed6b9d605079e7f653c9f2e0fbf79
Author: DamonXue <[email protected]>
AuthorDate: Mon Mar 6 15:46:10 2023 +0800

    [ISSUE #4395] cryptor plugin support multi fieldNames. (#4435)
    
    * cryptor plugin support multi fieldNames..
    
    * cryptor plugin support multi fieldNames + 1.
    
    ---------
    
    Co-authored-by: moremind <[email protected]>
    Co-authored-by: xiaoyu <[email protected]>
---
 .../src/main/resources/sql-script/h2/schema.sql    |  4 +-
 .../test/combination/MultiRequestPluginTest.java   |  1 +
 .../http/combination/CryptorRequestPluginTest.java | 31 ++------
 ....java => AbstractCryptorPluginDataHandler.java} | 11 +--
 .../handler/CryptorRequestPluginDataHandler.java   | 26 +------
 .../handler/CryptorResponsePluginDataHandler.java  | 26 +------
 .../cryptor/plugin/AbstractCryptorPlugin.java      | 85 ++++++++++++++++++++++
 .../{request => plugin}/CryptorRequestPlugin.java  | 52 ++++---------
 .../CryptorResponsePlugin.java                     | 47 +++---------
 .../plugin/cryptor/strategy/MapTypeEnum.java       | 81 ++++++++++++++++++---
 .../shenyu/plugin/cryptor/utils/CryptorUtil.java   | 43 ++++++++++-
 .../shenyu/plugin/cryptor/utils/JsonUtil.java      | 31 ++++++--
 .../CryptorRequestPluginTest.java                  | 40 +++++++++-
 .../CryptorResponsePluginTest.java                 | 27 ++-----
 .../plugin/cryptor/CryptorPluginConfiguration.java |  4 +-
 15 files changed, 310 insertions(+), 199 deletions(-)

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 00ae30baf..985cbcb36 100755
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -629,13 +629,13 @@ 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`) VALUES 
('1529402613199978579', '24', 'decryptKey', 'decryptKey', 2, 2, 3);
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172800', '24', 'encryptKey', 'encryptKey', 2, 2, 3);
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172801', '24', 'way', 'way', 3, 2, 3);
-INSERT IGNORE 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\":\"\"}', '2023-03-01 
10:41:41', '2023-03-01 10:42:21');
+INSERT IGNORE 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\":\"\"}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172802', '25', 'strategyName', 'strategyName', 3, 2, 2);
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172803', '25', 'decryptKey', 'decryptKey', 2, 2, 3);
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172804', '25', 'encryptKey', 'encryptKey', 2, 2, 3);
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172805', '25', 'fieldNames', 'fieldNames', 2, 2, 4);
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`) VALUES 
('1529402613204172806', '25', 'way', 'way', 3, 2, 3);
-INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1630768384280514560', '25', 'mapType', 'mapType', 3, 2, 4, 
'{\"required\":\"0\",\"defaultValue\":\"all\",\"rule\":\"\"}', '2023-03-01 
11:14:15', '2023-03-01 11:15:14');
+INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1630768384280514560', '25', 'mapType', 'mapType', 3, 2, 4, 
'{\"required\":\"0\",\"defaultValue\":\"all\",\"rule\":\"\"}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172807', '6', 'gray', 'gray', 3, 1, 9, 
'{"required":"0","defaultValue":"false","placeholder":"gray","rule":""}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172808', '6', 'group', 'group', 2, 1, 3, 
'{"required":"0","placeholder":"group","rule":""}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1529402613204172809', '6', 'loadbalance', 'loadbalance', 3, 2, 0, 
'{"required":"0","placeholder":"loadbalance","rule":""}');
diff --git 
a/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/MultiRequestPluginTest.java
 
b/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/MultiRequestPluginTest.java
index b7d792c88..cb4d36a85 100644
--- 
a/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/MultiRequestPluginTest.java
+++ 
b/shenyu-integrated-test/shenyu-integrated-test-combination/src/test/java/org/apache/shenyu/integrated/test/combination/MultiRequestPluginTest.java
@@ -509,6 +509,7 @@ public final class MultiRequestPluginTest extends 
AbstractPluginDataInit {
         cryptorRuleHandler.setStrategyName("rsa");
         cryptorRuleHandler.setFieldNames("userName");
         cryptorRuleHandler.setWay("encrypt");
+        cryptorRuleHandler.setMapType("all");
         return 
Collections.singletonList(buildRuleLocalData(JsonUtils.toJson(cryptorRuleHandler)));
     }
 
diff --git 
a/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/CryptorRequestPluginTest.java
 
b/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/CryptorRequestPluginTest.java
index 93cec7ba9..85532faa8 100644
--- 
a/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/CryptorRequestPluginTest.java
+++ 
b/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/CryptorRequestPluginTest.java
@@ -123,7 +123,7 @@ public final class CryptorRequestPluginTest extends 
AbstractPluginDataInit {
         initSelectorAndRules(PluginEnum.CRYPTOR_REQUEST.getName(),
                 "", SINGLETON_CONDITION_LIST, buildRuleLocalDataList("data", 
"decrypt", ALL.getMapType()));
 
-        AdminResponse response = HttpHelper.INSTANCE.postGateway(TEST_PATH, 
new JsonObject(), AdminResponse.class);
+        AdminResponse<String> response = 
HttpHelper.INSTANCE.<AdminResponse<String>, JsonObject>postGateway(TEST_PATH, 
new JsonObject(), AdminResponse.class);
 
         assertThat(response.getCode(), is(-114));
         assertThat(response.getMessage(), is("Please check Cryptor request 
plugin's [fieldNames]"));
@@ -133,13 +133,7 @@ public final class CryptorRequestPluginTest extends 
AbstractPluginDataInit {
     @ParameterizedTest(name = "return failed message when {0} failed")
     @ValueSource(strings = {"decrypt", "encrypt"})
     public void testWhenDecryptionOrEncryptionIsFailed(final String way) 
throws Exception {
-
-        CryptorRuleHandler handler = buildRuleHandler("rsa", 
-                way, 
-                "wrong_encrypt_key", 
-                "wrong_decrypt_key", 
-                "data", 
-                ALL.getMapType());
+        CryptorRuleHandler handler = buildRuleHandler("rsa", way, 
"wrong_encrypt_key", "wrong_decrypt_key", "data", ALL.getMapType());
         RuleLocalData ruleLocalData = ruleLocalData(handler, 
SINGLETON_CONDITION_LIST);
 
         initSelectorAndRules(PluginEnum.CRYPTOR_REQUEST.getName(), "", 
SINGLETON_CONDITION_LIST, Lists.newArrayList(ruleLocalData));
@@ -147,7 +141,7 @@ public final class CryptorRequestPluginTest extends 
AbstractPluginDataInit {
         JsonObject request = new JsonObject();
         request.addProperty("data", "random_data");
 
-        AdminResponse response = HttpHelper.INSTANCE.postGateway(TEST_PATH, 
request, AdminResponse.class);
+        AdminResponse<String> response = 
HttpHelper.INSTANCE.<AdminResponse<String>, JsonObject>postGateway(TEST_PATH, 
request, AdminResponse.class);
         ShenyuResultEnum resultEnum = "decrypt".equals(way) ? DECRYPTION_ERROR 
: ENCRYPTION_ERROR;
         assertThat(response.getCode(), is(resultEnum.getCode()));
         assertThat(response.getMessage(), is(resultEnum.getMsg()));
@@ -158,18 +152,13 @@ public final class CryptorRequestPluginTest extends 
AbstractPluginDataInit {
     @ValueSource(strings = {"decrypt", "encrypt"})
     public void testWhenKeyIsNull(final String way) throws Exception {
 
-        CryptorRuleHandler handler = buildRuleHandler("rsa", 
-                way, 
-                null, 
-                null, 
-                "data",
-                FIELD.getMapType());
+        CryptorRuleHandler handler = buildRuleHandler("rsa", way, null, null, 
"data", FIELD.getMapType());
 
         initSelectorAndRules(PluginEnum.CRYPTOR_REQUEST.getName(),
                 "", SINGLETON_CONDITION_LIST, 
singletonRuleLocalDataList(handler, SINGLETON_CONDITION_LIST));
 
         JsonObject request = new JsonObject();
-        AdminResponse response = HttpHelper.INSTANCE.postGateway(TEST_PATH, 
request, AdminResponse.class);
+        AdminResponse<String> response = 
HttpHelper.INSTANCE.<AdminResponse<String>, JsonObject>postGateway(TEST_PATH, 
request, AdminResponse.class);
 
         String keyName = "decrypt".equals(way) ? "decryptKey" : "encryptKey";
         assertThat(response.getMessage(), is(String.format("Please check 
Cryptor request plugin's [%s]", keyName)));
@@ -185,7 +174,7 @@ public final class CryptorRequestPluginTest extends 
AbstractPluginDataInit {
                 singletonRuleLocalDataList(handler, SINGLETON_CONDITION_LIST));
 
         JsonObject request = new JsonObject();
-        AdminResponse response = HttpHelper.INSTANCE.postGateway(TEST_PATH, 
request, AdminResponse.class);
+        AdminResponse<String> response = 
HttpHelper.INSTANCE.<AdminResponse<String>, JsonObject>postGateway(TEST_PATH, 
request, AdminResponse.class);
 
         assertThat(response.getMessage(), is(String.format("Please check 
Cryptor request plugin's [%s]", "fieldNames")));
     }
@@ -195,12 +184,8 @@ public final class CryptorRequestPluginTest extends 
AbstractPluginDataInit {
         return singletonRuleLocalDataList(cryptorRuleHandler, 
SINGLETON_CONDITION_LIST);
     }
 
-    private CryptorRuleHandler buildRuleHandler(final String strategyName, 
-                                                final String way, 
-                                                final String encryptKey, 
-                                                final String decryptKey, 
-                                                final String fieldNames,
-                                                final String mapType) {
+    private CryptorRuleHandler buildRuleHandler(final String strategyName, 
final String way, final String encryptKey,
+                                                final String decryptKey, final 
String fieldNames, final String mapType) {
         CryptorRuleHandler cryptorRuleHandler = new CryptorRuleHandler();
         cryptorRuleHandler.setDecryptKey(decryptKey);
         cryptorRuleHandler.setEncryptKey(encryptKey);
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/AbstractCryptorPluginDataHandler.java
similarity index 87%
copy from 
shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
copy to 
shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/AbstractCryptorPluginDataHandler.java
index 7a753da30..5d26f47ce 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/AbstractCryptorPluginDataHandler.java
@@ -18,9 +18,8 @@
 package org.apache.shenyu.plugin.cryptor.handler;
 
 import org.apache.shenyu.common.dto.RuleData;
-import org.apache.shenyu.plugin.base.cache.CommonHandleCache;
-import org.apache.shenyu.common.enums.PluginEnum;
 import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.plugin.base.cache.CommonHandleCache;
 import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
 import org.apache.shenyu.plugin.base.utils.BeanHolder;
 import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
@@ -29,9 +28,9 @@ import java.util.Optional;
 import java.util.function.Supplier;
 
 /**
- * The type cryptor response plugin data subscriber.
+ * AbstractCryptorPluginDataHandler.
  */
-public class CryptorResponsePluginDataHandler implements PluginDataHandler {
+public abstract class AbstractCryptorPluginDataHandler implements 
PluginDataHandler {
 
     public static final Supplier<CommonHandleCache<String, 
CryptorRuleHandler>> CACHED_HANDLE = new BeanHolder<>(CommonHandleCache::new);
 
@@ -48,8 +47,4 @@ public class CryptorResponsePluginDataHandler implements 
PluginDataHandler {
         Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> 
CACHED_HANDLE.get().removeHandle(CacheKeyUtils.INST.getKey(ruleData)));
     }
 
-    @Override
-    public String pluginNamed() {
-        return PluginEnum.CRYPTOR_RESPONSE.getName();
-    }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorRequestPluginDataHandler.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorRequestPluginDataHandler.java
index 641b30d4e..52d31daeb 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorRequestPluginDataHandler.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorRequestPluginDataHandler.java
@@ -17,36 +17,12 @@
 
 package org.apache.shenyu.plugin.cryptor.handler;
 
-import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.enums.PluginEnum;
-import org.apache.shenyu.common.utils.GsonUtils;
-import org.apache.shenyu.plugin.base.cache.CommonHandleCache;
-import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
-import org.apache.shenyu.plugin.base.utils.BeanHolder;
-import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
-
-import java.util.Optional;
-import java.util.function.Supplier;
 
 /**
  * The type cryptor request plugin plugin data subscriber.
  */
-public class CryptorRequestPluginDataHandler implements PluginDataHandler {
-
-    public static final Supplier<CommonHandleCache<String, 
CryptorRuleHandler>> CACHED_HANDLE = new BeanHolder<>(CommonHandleCache::new);
-
-    @Override
-    public void handlerRule(final RuleData ruleData) {
-        Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> {
-            CryptorRuleHandler cryptorRuleHandler = 
GsonUtils.getInstance().fromJson(s, CryptorRuleHandler.class);
-            
CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(ruleData), 
cryptorRuleHandler);
-        });
-    }
-
-    @Override
-    public void removeRule(final RuleData ruleData) {
-        Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> 
CACHED_HANDLE.get().removeHandle(CacheKeyUtils.INST.getKey(ruleData)));
-    }
+public class CryptorRequestPluginDataHandler extends 
AbstractCryptorPluginDataHandler {
 
     @Override
     public String pluginNamed() {
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
index 7a753da30..7f8585152 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/handler/CryptorResponsePluginDataHandler.java
@@ -17,36 +17,12 @@
 
 package org.apache.shenyu.plugin.cryptor.handler;
 
-import org.apache.shenyu.common.dto.RuleData;
-import org.apache.shenyu.plugin.base.cache.CommonHandleCache;
 import org.apache.shenyu.common.enums.PluginEnum;
-import org.apache.shenyu.common.utils.GsonUtils;
-import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
-import org.apache.shenyu.plugin.base.utils.BeanHolder;
-import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
-
-import java.util.Optional;
-import java.util.function.Supplier;
 
 /**
  * The type cryptor response plugin data subscriber.
  */
-public class CryptorResponsePluginDataHandler implements PluginDataHandler {
-
-    public static final Supplier<CommonHandleCache<String, 
CryptorRuleHandler>> CACHED_HANDLE = new BeanHolder<>(CommonHandleCache::new);
-
-    @Override
-    public void handlerRule(final RuleData ruleData) {
-        Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> {
-            CryptorRuleHandler cryptorRuleHandler = 
GsonUtils.getInstance().fromJson(s, CryptorRuleHandler.class);
-            
CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(ruleData), 
cryptorRuleHandler);
-        });
-    }
-
-    @Override
-    public void removeRule(final RuleData ruleData) {
-        Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> 
CACHED_HANDLE.get().removeHandle(CacheKeyUtils.INST.getKey(ruleData)));
-    }
+public class CryptorResponsePluginDataHandler extends 
AbstractCryptorPluginDataHandler {
 
     @Override
     public String pluginNamed() {
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/AbstractCryptorPlugin.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/AbstractCryptorPlugin.java
new file mode 100644
index 000000000..3e6a0a86d
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/AbstractCryptorPlugin.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.cryptor.plugin;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
+import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
+import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
+import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
+import 
org.apache.shenyu.plugin.cryptor.handler.AbstractCryptorPluginDataHandler;
+import org.apache.shenyu.plugin.cryptor.handler.CryptorRuleHandler;
+import org.apache.shenyu.plugin.cryptor.strategy.MapTypeEnum;
+import org.apache.shenyu.plugin.cryptor.utils.CryptorUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.Objects;
+
+/**
+ * AbstractCryptorPlugin.
+ */
+public abstract class AbstractCryptorPlugin extends AbstractShenyuPlugin {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(AbstractCryptorPlugin.class);
+
+    @Override
+    protected Mono<Void> doExecute(final ServerWebExchange exchange, final 
ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
+        final CryptorRuleHandler ruleHandle = 
AbstractCryptorPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
+        if (Objects.isNull(ruleHandle)) {
+            LOG.error("{} rule configuration is null :{}", named(), 
rule.getId());
+            return chain.execute(exchange);
+        }
+
+        Pair<Boolean, String> pair = CryptorUtil.checkParam(ruleHandle);
+        if (Boolean.TRUE.equals(pair.getLeft())) {
+            ShenyuResultEnum resultEnum = checkErrorEnum();
+            return WebFluxResultUtils.failedResult(resultEnum.getCode(),
+                    resultEnum.getMsg() + "[" + pair.getRight() + "]", 
exchange);
+        }
+        return doExecute0(exchange, chain, selector, rule, ruleHandle);
+    }
+
+    protected abstract Mono<Void> doExecute0(ServerWebExchange exchange, 
ShenyuPluginChain chain,
+                                             SelectorData selector, RuleData 
rule, CryptorRuleHandler ruleHandle);
+    
+    protected abstract ShenyuResultEnum checkErrorEnum();
+
+    /**
+     * field parse error diff handler.
+     *
+     * @param originalBody originalBody
+     * @param exchange exchange
+     * @return String
+     */
+    protected abstract String fieldErrorParse(String originalBody, 
ServerWebExchange exchange);
+    
+    protected String convert(final String originalBody, final 
CryptorRuleHandler ruleHandle, final ServerWebExchange exchange) {
+        String converted = 
MapTypeEnum.mapType(ruleHandle.getMapType()).convert(originalBody, ruleHandle, 
exchange);
+        if (Objects.isNull(converted)) {
+            return fieldErrorParse(originalBody, exchange);
+        }
+        return converted;
+    }
+
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/request/CryptorRequestPlugin.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorRequestPlugin.java
similarity index 53%
rename from 
shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/request/CryptorRequestPlugin.java
rename to 
shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorRequestPlugin.java
index c1f42efa3..ad96eff5e 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/request/CryptorRequestPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorRequestPlugin.java
@@ -15,9 +15,8 @@
  * limitations under the License.
  */
 
-package org.apache.shenyu.plugin.cryptor.request;
+package org.apache.shenyu.plugin.cryptor.plugin;
 
-import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
 import org.apache.shenyu.common.enums.PluginEnum;
@@ -25,28 +24,18 @@ import org.apache.shenyu.plugin.api.ShenyuPluginChain;
 import org.apache.shenyu.plugin.api.exception.ResponsiveException;
 import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
 import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
-import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
-import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
 import org.apache.shenyu.plugin.base.utils.ServerWebExchangeUtils;
-import 
org.apache.shenyu.plugin.cryptor.handler.CryptorRequestPluginDataHandler;
 import org.apache.shenyu.plugin.cryptor.handler.CryptorRuleHandler;
-import org.apache.shenyu.plugin.cryptor.utils.CryptorUtil;
-import org.apache.shenyu.plugin.cryptor.utils.JsonUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.http.codec.HttpMessageReader;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
 
 import java.util.List;
-import java.util.Objects;
 
 /**
  * Cryptor request plugin.
  */
-public class CryptorRequestPlugin extends AbstractShenyuPlugin {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(CryptorRequestPlugin.class);
+public class CryptorRequestPlugin extends AbstractCryptorPlugin {
 
     private final List<HttpMessageReader<?>> messageReaders;
 
@@ -60,23 +49,11 @@ public class CryptorRequestPlugin extends 
AbstractShenyuPlugin {
     }
 
     @Override
-    protected Mono<Void> doExecute(final ServerWebExchange exchange, final 
ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
-        CryptorRuleHandler ruleHandle = 
CryptorRequestPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
-        if (Objects.isNull(ruleHandle)) {
-            LOG.error("Cryptor request rule configuration is null :{}", 
rule.getId());
-            return chain.execute(exchange);
-        }
-
-        Pair<Boolean, String> pair = CryptorUtil.checkParam(ruleHandle);
-        if (Boolean.TRUE.equals(pair.getLeft())) {
-            ShenyuResultEnum resultEnum = 
ShenyuResultEnum.CRYPTOR_REQUEST_ERROR_CONFIGURATION;
-            return WebFluxResultUtils.failedResult(resultEnum.getCode(),
-                    resultEnum.getMsg() + "[" + pair.getRight() + "]", 
exchange);
-        }
-
+    protected Mono<Void> doExecute0(final ServerWebExchange exchange, final 
ShenyuPluginChain chain,
+                                    final SelectorData selector, final 
RuleData rule, final CryptorRuleHandler ruleHandle) {
         return ServerWebExchangeUtils.rewriteRequestBody(exchange, 
messageReaders, originalBody ->
-                Mono.just(convert(ruleHandle, originalBody, exchange))
-        ).flatMap(chain::execute)
+                        Mono.just(convert(originalBody, ruleHandle, exchange))
+                ).flatMap(chain::execute)
                 .onErrorResume(error -> {
                     if (error instanceof ResponsiveException) {
                         return 
WebFluxResultUtils.failedResult((ResponsiveException) error);
@@ -85,6 +62,16 @@ public class CryptorRequestPlugin extends 
AbstractShenyuPlugin {
                 });
     }
 
+    @Override
+    protected ShenyuResultEnum checkErrorEnum() {
+        return ShenyuResultEnum.CRYPTOR_REQUEST_ERROR_CONFIGURATION;
+    }
+
+    @Override
+    protected String fieldErrorParse(final String originalBody, final 
ServerWebExchange exchange) {
+        throw new 
ResponsiveException(ShenyuResultEnum.CRYPTOR_REQUEST_ERROR_CONFIGURATION.getCode(),
 ShenyuResultEnum.CRYPTOR_REQUEST_ERROR_CONFIGURATION.getMsg() + 
"[fieldNames]", exchange);
+    }
+
     @Override
     public int getOrder() {
         return PluginEnum.CRYPTOR_REQUEST.getCode();
@@ -95,11 +82,4 @@ public class CryptorRequestPlugin extends 
AbstractShenyuPlugin {
         return PluginEnum.CRYPTOR_REQUEST.getName();
     }
 
-    private String convert(final CryptorRuleHandler ruleHandle, final String 
originalBody, final ServerWebExchange exchange) {
-        String parseBody = JsonUtil.parser(originalBody, 
ruleHandle.getFieldNames());
-        if (Objects.isNull(parseBody)) {
-            throw new 
ResponsiveException(ShenyuResultEnum.CRYPTOR_REQUEST_ERROR_CONFIGURATION.getCode(),
 ShenyuResultEnum.CRYPTOR_REQUEST_ERROR_CONFIGURATION.getMsg() + 
"[fieldNames]", exchange);
-        }
-        return CryptorUtil.crypt(ruleHandle, parseBody, originalBody, 
exchange);
-    }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/response/CryptorResponsePlugin.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorResponsePlugin.java
similarity index 51%
rename from 
shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/response/CryptorResponsePlugin.java
rename to 
shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorResponsePlugin.java
index 5e9e4e448..4f6a73590 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/response/CryptorResponsePlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorResponsePlugin.java
@@ -15,52 +15,28 @@
  * limitations under the License.
  */
 
-package org.apache.shenyu.plugin.cryptor.response;
+package org.apache.shenyu.plugin.cryptor.plugin;
 
-import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
 import org.apache.shenyu.common.enums.PluginEnum;
 import org.apache.shenyu.plugin.api.ShenyuPluginChain;
 import org.apache.shenyu.plugin.api.exception.ResponsiveException;
 import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
-import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
 import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
-import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
-import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
 import org.apache.shenyu.plugin.base.utils.ServerWebExchangeUtils;
-import 
org.apache.shenyu.plugin.cryptor.handler.CryptorResponsePluginDataHandler;
 import org.apache.shenyu.plugin.cryptor.handler.CryptorRuleHandler;
-import org.apache.shenyu.plugin.cryptor.utils.CryptorUtil;
-import org.apache.shenyu.plugin.cryptor.utils.JsonUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
 
-import java.util.Objects;
-
 /**
  * Cryptor response plugin.
  */
-public class CryptorResponsePlugin extends AbstractShenyuPlugin {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(CryptorResponsePlugin.class);
+public class CryptorResponsePlugin extends AbstractCryptorPlugin {
 
     @Override
-    protected Mono<Void> doExecute(final ServerWebExchange exchange, final 
ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
-        CryptorRuleHandler ruleHandle = 
CryptorResponsePluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
-        if (Objects.isNull(ruleHandle)) {
-            LOG.error("Cryptor response rule configuration is null :{}", 
rule.getId());
-            return chain.execute(exchange);
-        }
-        Pair<Boolean, String> pair = CryptorUtil.checkParam(ruleHandle);
-        if (Boolean.TRUE.equals(pair.getLeft())) {
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CRYPTOR_RESPONSE_ERROR_CONFIGURATION.getCode(),
-                    
ShenyuResultEnum.CRYPTOR_RESPONSE_ERROR_CONFIGURATION.getMsg() + "[" + 
pair.getRight() + "]", null);
-            return WebFluxResultUtils.result(exchange, error);
-        }
-
+    protected Mono<Void> doExecute0(final ServerWebExchange exchange, final 
ShenyuPluginChain chain,
+                                    final SelectorData selector, final 
RuleData rule, final CryptorRuleHandler ruleHandle) {
         ServerWebExchange newExchange = 
ServerWebExchangeUtils.rewriteResponseBody(exchange, originalBody -> 
convert(originalBody, ruleHandle, exchange));
 
         return chain.execute(newExchange).onErrorResume(error -> {
@@ -71,15 +47,14 @@ public class CryptorResponsePlugin extends 
AbstractShenyuPlugin {
         });
     }
 
-    private String convert(final String originalBody, final CryptorRuleHandler 
ruleHandle, final ServerWebExchange exchange) {
-
-        String parseBody = JsonUtil.parser(originalBody, 
ruleHandle.getFieldNames());
-
-        if (Objects.isNull(parseBody)) {
-            return originalBody;
-        }
+    @Override
+    protected ShenyuResultEnum checkErrorEnum() {
+        return ShenyuResultEnum.CRYPTOR_RESPONSE_ERROR_CONFIGURATION;
+    }
 
-        return CryptorUtil.crypt(ruleHandle, parseBody, originalBody, 
exchange);
+    @Override
+    protected String fieldErrorParse(final String originalBody, final 
ServerWebExchange exchange) {
+        return originalBody;
     }
 
     @Override
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/strategy/MapTypeEnum.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/strategy/MapTypeEnum.java
index d36a5a2ac..c83cde3c3 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/strategy/MapTypeEnum.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/strategy/MapTypeEnum.java
@@ -19,10 +19,18 @@ package org.apache.shenyu.plugin.cryptor.strategy;
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParser;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.shenyu.plugin.cryptor.handler.CryptorRuleHandler;
+import org.apache.shenyu.plugin.cryptor.utils.CryptorUtil;
 import org.apache.shenyu.plugin.cryptor.utils.JsonUtil;
+import org.springframework.web.server.ServerWebExchange;
 
 import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 /**
  * MapTypeEnum.
@@ -30,23 +38,47 @@ import java.util.concurrent.atomic.AtomicInteger;
 public enum MapTypeEnum {
 
     ALL("all") {
+        
         @Override
-        public String map(final String originalBody, final String 
modifiedBody, final String fieldNames) {
-            AtomicInteger initDeep = new AtomicInteger();
-            initDeep.set(0);
-            JsonElement je = JsonParser.parseString(originalBody);
-            JsonElement resultJe = JsonUtil.replaceJsonNode(je,
-                    initDeep,
-                    modifiedBody,
-                    Arrays.asList(fieldNames.split("\\.")));
+        public String map(final String originalBody, final String 
modifiedBody, final String fieldName) {
+            JsonElement element = JsonParser.parseString(originalBody);
+            JsonElement resultJe = JsonUtil.replaceJsonNode(element, new 
AtomicInteger(0), modifiedBody, Arrays.asList(fieldName.split("\\.")));
             return resultJe.toString();
         }
+
+        @Override
+        public String convert(final String originalBody, final 
CryptorRuleHandler ruleHandle, final ServerWebExchange exchange) {
+            if (!ruleHandle.getFieldNames().contains(",")) {
+                return FIELD.convert(originalBody, ruleHandle, exchange);
+            }
+            final List<Pair<String, String>> pairs = 
JsonUtil.parser(originalBody, Arrays.stream(ruleHandle.getFieldNames()
+                            .split(","))
+                    .collect(Collectors.toSet()));
+            if (CollectionUtils.isEmpty(pairs)) {
+                return null;
+            }
+            return CryptorUtil.crypt(ruleHandle, pairs, originalBody, 
exchange);
+        }
     },
     FIELD("field") {
+        
         @Override
-        public String map(final String originalBody, final String 
modifiedBody, final String fieldNames) {
+        public String map(final String originalBody, final String 
modifiedBody, final String fieldName) {
             return modifiedBody;
         }
+
+        @Override
+        public String convert(final String originalBody, final 
CryptorRuleHandler ruleHandle, final ServerWebExchange exchange) {
+            if (ruleHandle.getFieldNames().contains(",")) {
+                return ALL.convert(originalBody, ruleHandle, exchange);
+            }
+            String parseBody = JsonUtil.parser(originalBody, 
ruleHandle.getFieldNames());
+            // can not find field then return originalBody.
+            if (Objects.isNull(parseBody)) {
+                return null;
+            }
+            return CryptorUtil.crypt(ruleHandle, parseBody, originalBody, 
exchange);
+        }
     };
 
     private final String mapType;
@@ -60,10 +92,37 @@ public enum MapTypeEnum {
      *
      * @param originalBody originalBody
      * @param modifiedBody modifiedBody
-     * @param fieldNames   fieldNames
+     * @param fieldName   fieldName
+     * @return String
+     */
+    public abstract String map(String originalBody, String modifiedBody, 
String fieldName);
+
+    /**
+     * map to type string.
+     *
+     * @param originalBody  originalBody
+     * @param modifiedPairs modifiedPairs
+     * @return String
+     */
+    public String map(final String originalBody, final List<Pair<String, 
String>> modifiedPairs) {
+        if (CollectionUtils.isEmpty(modifiedPairs)) {
+            return originalBody;
+        }
+        String modifiedString = originalBody;
+        for (Pair<String, String> pair : modifiedPairs) {
+            modifiedString = ALL.map(modifiedString, pair.getRight(), 
pair.getLeft());
+        }
+        return modifiedString;
+    }
+
+    /**
+     * convert to json string.
+     * @param originalBody originalBody
+     * @param ruleHandle ruleHandle
+     * @param exchange exchange
      * @return String
      */
-    public abstract String map(String originalBody, String modifiedBody, 
String fieldNames);
+    public abstract String convert(String originalBody, CryptorRuleHandler 
ruleHandle, ServerWebExchange exchange);
 
     /**
      * get mapType.
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
index 3714033c0..dc95d96fd 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.plugin.cryptor.utils;
 
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.plugin.api.exception.ResponsiveException;
@@ -29,8 +30,13 @@ import org.apache.shenyu.plugin.cryptor.strategy.MapTypeEnum;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
 
+import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.apache.shenyu.plugin.cryptor.strategy.MapTypeEnum.ALL;
+import static org.apache.shenyu.plugin.cryptor.strategy.MapTypeEnum.FIELD;
 
 /**
  * cryptor util.
@@ -71,16 +77,28 @@ public final class CryptorUtil {
             return Pair.of(true, "strategyName");
         }
 
-        if (StringUtils.isEmpty(ruleHandle.getFieldNames())) {
+        String fieldNames;
+        if (StringUtils.isEmpty(fieldNames = ruleHandle.getFieldNames())) {
             return Pair.of(true, "fieldNames");
         }
 
+        String mapType;
+        if (StringUtils.isEmpty(mapType = ruleHandle.getMapType())) {
+            ruleHandle.setMapType(ALL.getMapType());
+        }
+
         if (ruleHandle.getWay().equals(CryptorStrategyFactory.DECRYPT) && 
StringUtils.isEmpty(ruleHandle.getDecryptKey())) {
             return Pair.of(true, "decryptKey");
         }
+        
         if (ruleHandle.getWay().equals(CryptorStrategyFactory.ENCRYPT) && 
StringUtils.isEmpty(ruleHandle.getEncryptKey())) {
             return Pair.of(true, "encryptKey");
         }
+
+        if (fieldNames.contains(",") && FIELD.getMapType().equals(mapType)) {
+            ruleHandle.setMapType(ALL.getMapType());
+        }
+        
         return Pair.of(false, "");
     }
 
@@ -104,6 +122,29 @@ public final class CryptorUtil {
         }
 
         return MapTypeEnum.mapType(ruleHandle.getMapType()).map(originalBody, 
modifiedData, ruleHandle.getFieldNames());
+    }
+
+    /**
+     * encrypt or decrypt the response body.
+     * @param ruleHandle ruleHandle
+     * @param pairs pairs
+     * @param originalBody originalBody
+     * @param exchange exchange
+     * @return new body
+     */
+    public static String crypt(final CryptorRuleHandler ruleHandle, final 
List<Pair<String, String>> pairs, final String originalBody, final 
ServerWebExchange exchange) {
+        List<Pair<String, String>> modifiedPairs = pairs.stream().map(pair -> 
Pair.of(pair.getLeft(), CryptorStrategyFactory.match(ruleHandle, 
pair.getRight())))
+                .filter(pair -> StringUtils.isNoneBlank(pair.getRight()))
+                .collect(Collectors.toList());
+
+        if (CollectionUtils.isEmpty(modifiedPairs)) {
+            throw Optional.ofNullable(ruleHandle.getWay())
+                    .filter(CryptorStrategyFactory.DECRYPT::equals)
+                    .map(data -> new 
ResponsiveException(ShenyuResultEnum.DECRYPTION_ERROR, exchange))
+                    .orElse(new 
ResponsiveException(ShenyuResultEnum.ENCRYPTION_ERROR, exchange));
+        }
+
+        return MapTypeEnum.mapType(ruleHandle.getMapType()).map(originalBody, 
modifiedPairs);
 
     }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/JsonUtil.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/JsonUtil.java
index d661bff16..f33ade78c 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/JsonUtil.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/JsonUtil.java
@@ -17,15 +17,20 @@
 
 package org.apache.shenyu.plugin.cryptor.utils;
 
+import com.google.common.collect.Lists;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.utils.GsonUtils;
 import org.springframework.util.CollectionUtils;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 /**
  * json util.
@@ -38,14 +43,14 @@ public final class JsonUtil {
     /**
      * parser JSON.
      * @param json json Map
-     * @param fieldNames params
+     * @param fieldName fieldName
      * @return str.
      */
-    public static String parser(final String json, final String fieldNames) {
+    public static String parser(final String json, final String fieldName) {
         Map<String, Object> map = GsonUtils.getInstance().toObjectMap(json);
         String str = null;
-        if (fieldNames.contains(".")) {
-            String[] split = fieldNames.split("\\.");
+        if (fieldName.contains(".")) {
+            String[] split = fieldName.split("\\.");
             JsonObject jsonObject = (JsonObject) map.get(split[0]);
             for (int i = 1; i < split.length; i++) {
                 if (i == split.length - 1) {
@@ -55,11 +60,27 @@ public final class JsonUtil {
                 }
             }
         } else {
-            return map.get(fieldNames) == null ? null : 
map.get(fieldNames).toString();
+            return map.get(fieldName) == null ? null : 
map.get(fieldName).toString();
         }
         return str;
     }
 
+    /**
+     * parser JSON.
+     * @param json json Map
+     * @param fieldNames params
+     * @return str.
+     */
+    public static List<Pair<String, String>> parser(final String json, final 
Set<String> fieldNames) {
+        if (CollectionUtils.isEmpty(fieldNames) || StringUtils.isBlank(json)) {
+            return Lists.newArrayList();
+        }
+        return fieldNames.stream().filter(StringUtils::isNoneBlank)
+                .map(field -> Pair.of(field, parser(json, field)))
+                .filter(pair -> StringUtils.isNoneBlank(pair.getRight()))
+                .collect(Collectors.toList());
+    }
+
     /**
      * operate json.
      * @param jsonElement jsonElement
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/request/CryptorRequestPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorRequestPluginTest.java
similarity index 85%
rename from 
shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/request/CryptorRequestPluginTest.java
rename to 
shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorRequestPluginTest.java
index b39a8f19a..69d645ba6 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/request/CryptorRequestPluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorRequestPluginTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shenyu.plugin.cryptor.request;
+package org.apache.shenyu.plugin.cryptor.plugin;
 
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
@@ -24,6 +24,7 @@ import org.apache.shenyu.plugin.api.ShenyuPluginChain;
 import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
 import 
org.apache.shenyu.plugin.cryptor.handler.CryptorRequestPluginDataHandler;
 import org.apache.shenyu.plugin.cryptor.handler.CryptorRuleHandler;
+import org.apache.shenyu.plugin.cryptor.strategy.MapTypeEnum;
 import org.apache.shenyu.plugin.cryptor.utils.CryptorUtil;
 import org.apache.shenyu.plugin.cryptor.utils.JsonUtil;
 import org.junit.jupiter.api.BeforeEach;
@@ -83,7 +84,8 @@ public class CryptorRequestPluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"decrypt\""
+                + "\"way\":\"decrypt\","
+                + "\"mapType\":\"all\""
                 + "}\n");
         this.exchange = MockServerWebExchange.from(MockServerHttpRequest
                 .method(HttpMethod.POST, "/test")
@@ -108,7 +110,8 @@ public class CryptorRequestPluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"encrypt\""
+                + "\"way\":\"encrypt\","
+                + "\"mapType\":\"all\""
                 + "}\n");
         this.exchange = MockServerWebExchange.from(MockServerHttpRequest
                 .method(HttpMethod.POST, "/test")
@@ -133,7 +136,8 @@ public class CryptorRequestPluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"encrypt\""
+                + "\"way\":\"encrypt\","
+                + "\"mapType\":\"all\""
                 + "}\n");
         this.exchange = MockServerWebExchange.from(MockServerHttpRequest
                 .method(HttpMethod.POST, "/test")
@@ -238,5 +242,33 @@ public class CryptorRequestPluginTest {
         String parseBody = JsonUtil.parser(originalBody, 
ruleHandle.getFieldNames());
         assertEquals(CryptorUtil.crypt(ruleHandle, parseBody, originalBody, 
exchange), 
"{\"inputToken\":{\"test\":\"{\\\"nickName\\\":\\\"openApi\\\"}\"}}");
     }
+
+    @Test
+    public void mapTypeDecryptMultFieldsTest() {
+        this.ruleData.setHandle("{\"strategyName\":\"rsa\","
+                + "\"fieldNames\":\"inputToken.one,inputToken.two\","
+                + 
"\"decryptKey\":\"MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtrfolGUtLhZVSpd5L/oAXbGW9Rn54mD96Ny"
+                + 
"uWsxp/KCscDoeFScN7uSc3LwKk14wrC4X0+fSDxm0kMPTvgNBywIDAQABAkBFPvt4ycNOlQ4r364A3akn2PbR2s9V2NZBW"
+                + 
"ukE5jVAlOvgCn6L/+tsVDSQgeVtOPd6rwM2a24iASDsNEbnVrwBAiEA34DwAmsa1phE5aGKM1bPHJiGgM8yolIYDWBaBCu"
+                + 
"PTgECIQDRSOWA8rLJWP+Vijm/QB8C41Gw1V7WXC2Kuj07Jv5nywIgTDKCIODw8m5RNtRe8GfNDlu1p158TbidOJo7tiY/og"
+                + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
+                + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
+                + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
+                + "\"way\":\"decrypt\","
+                + "\"mapType\":\"all\""
+                + "}\n");
+        final String originalBody = "{\"inputToken\": "
+                + 
"{\"one\":\"kYPZgOAR2pEipskl5WURW/r3CMxNQJwbs4jbTAOfZNV39L4WkaTOqAeolV+rlKCKiXKvhfHWaxQOTMm9hQBxLA==\","
 
+                + 
"\"two\":\"kYPZgOAR2pEipskl5WURW/r3CMxNQJwbs4jbTAOfZNV39L4WkaTOqAeolV+rlKCKiXKvhfHWaxQOTMm9hQBxLA==\"}"
+                + "}";
+        this.exchange = MockServerWebExchange.from(MockServerHttpRequest
+                .method(HttpMethod.POST, "/test")
+                .header(HttpHeaders.CONTENT_TYPE, 
MediaType.APPLICATION_JSON_VALUE)
+                .body(originalBody));
+        cryptorRequestPluginDataHandler.handlerRule(ruleData);
+        CryptorRuleHandler ruleHandle = 
CryptorRequestPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(ruleData));
+        String parseBody = 
MapTypeEnum.mapType(ruleHandle.getMapType()).convert(originalBody, ruleHandle, 
exchange);
+        assertEquals(parseBody, 
"{\"inputToken\":{\"one\":\"{\\\"nickName\\\":\\\"openApi\\\"}\",\"two\":\"{\\\"nickName\\\":\\\"openApi\\\"}\"}}");
+    }
     
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/response/CryptorResponsePluginTest.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorResponsePluginTest.java
similarity index 90%
rename from 
shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/response/CryptorResponsePluginTest.java
rename to 
shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorResponsePluginTest.java
index cf605f85e..5ecc78c96 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/response/CryptorResponsePluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/test/java/org/apache/shenyu/plugin/cryptor/plugin/CryptorResponsePluginTest.java
@@ -15,14 +15,13 @@
  * limitations under the License.
  */
 
-package org.apache.shenyu.plugin.cryptor.response;
+package org.apache.shenyu.plugin.cryptor.plugin;
 
 import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
 import org.apache.shenyu.common.enums.PluginEnum;
 import org.apache.shenyu.plugin.api.ShenyuPluginChain;
-import org.apache.shenyu.plugin.base.support.ResponseDecorator;
 import 
org.apache.shenyu.plugin.cryptor.handler.CryptorResponsePluginDataHandler;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -94,12 +93,9 @@ public class CryptorResponsePluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"encrypt\""
+                + "\"way\":\"encrypt\",\"mapType\":\"all\""
                 + "}\n");
         ServerWebExchange.Builder builder = 
mock(ServerWebExchange.Builder.class);
-        when(exchange.mutate()).thenReturn(builder);
-        
when(builder.response(any(ResponseDecorator.class))).thenReturn(builder);
-        when(builder.build()).thenReturn(exchange);
         when(chain.execute(any())).thenReturn(Mono.empty());
         cryptorResponsePluginDataHandler.handlerRule(ruleData);
         ServerWebExchange exchangeNormal = generateServerWebExchange();
@@ -125,12 +121,9 @@ public class CryptorResponsePluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"decrypt\""
+                + "\"way\":\"decrypt\",\"mapType\":\"all\""
                 + "}\n");
         ServerWebExchange.Builder builder = 
mock(ServerWebExchange.Builder.class);
-        when(exchange.mutate()).thenReturn(builder);
-        
when(builder.response(any(ResponseDecorator.class))).thenReturn(builder);
-        when(builder.build()).thenReturn(exchange);
         when(chain.execute(any())).thenReturn(Mono.empty());
         cryptorResponsePluginDataHandler.handlerRule(ruleData);
         ServerWebExchange exchangeNormal = generateServerWebExchange();
@@ -155,12 +148,9 @@ public class CryptorResponsePluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"encrypt\""
+                + "\"way\":\"encrypt\",\"mapType\":\"all\""
                 + "}\n");
         ServerWebExchange.Builder builder = 
mock(ServerWebExchange.Builder.class);
-        when(exchange.mutate()).thenReturn(builder);
-        
when(builder.response(any(ResponseDecorator.class))).thenReturn(builder);
-        when(builder.build()).thenReturn(exchange);
         when(chain.execute(any())).thenReturn(Mono.empty());
         cryptorResponsePluginDataHandler.handlerRule(ruleData);
         ServerWebExchange exchangeNormal = generateServerWebExchange();
@@ -186,16 +176,11 @@ public class CryptorResponsePluginTest {
                 + 
"ECIQCaj0tvP83qBWA8AClFpQVCDL936RxxEwJPQduWo+WeoQIhAN7HKEW0E97il2RvCsgeArdt83WjZh7OhMhW6MLPrMjs\","
                 + 
"\"encryptKey\":\"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALa36JRlLS4WVUqXeS/6AF2xlvUZ+eJg/ejcrlrMafygrHA6Hh"
                 + 
"UnDe7knNy8CpNeMKwuF9Pn0g8ZtJDD074DQcsCAwEAAQ\\u003d\\u003d\","
-                + "\"way\":\"decrypt\""
+                + "\"way\":\"decrypt\",\"mapType\":\"all\""
                 + "}\n");
         ServerWebExchange.Builder builder = 
mock(ServerWebExchange.Builder.class);
-        when(exchange.mutate()).thenReturn(builder);
-        
when(builder.response(any(ResponseDecorator.class))).thenReturn(builder);
-        when(builder.build()).thenReturn(exchange);
         when(chain.execute(any())).thenReturn(Mono.empty());
-        cryptorResponsePluginDataHandler.handlerRule(ruleData);
-        ServerWebExchange exchangeNormal = generateServerWebExchange();
-        Mono<Void> result = cryptorResponsePlugin.doExecute(exchangeNormal, 
chain, selectorData, ruleData);
+        Mono<Void> result = cryptorResponsePlugin.doExecute(exchange, chain, 
selectorData, ruleData);
         StepVerifier.create(result).expectSubscription().verifyComplete();
     }
 
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-cryptor/src/main/java/org/apache/shenyu/springboot/starter/plugin/cryptor/CryptorPluginConfiguration.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-cryptor/src/main/java/org/apache/shenyu/springboot/starter/plugin/cryptor/CryptorPluginConfiguration.java
index 8b38b6828..14b316bba 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-cryptor/src/main/java/org/apache/shenyu/springboot/starter/plugin/cryptor/CryptorPluginConfiguration.java
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-cryptor/src/main/java/org/apache/shenyu/springboot/starter/plugin/cryptor/CryptorPluginConfiguration.java
@@ -21,8 +21,8 @@ import org.apache.shenyu.plugin.api.ShenyuPlugin;
 import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
 import 
org.apache.shenyu.plugin.cryptor.handler.CryptorRequestPluginDataHandler;
 import 
org.apache.shenyu.plugin.cryptor.handler.CryptorResponsePluginDataHandler;
-import org.apache.shenyu.plugin.cryptor.request.CryptorRequestPlugin;
-import org.apache.shenyu.plugin.cryptor.response.CryptorResponsePlugin;
+import org.apache.shenyu.plugin.cryptor.plugin.CryptorRequestPlugin;
+import org.apache.shenyu.plugin.cryptor.plugin.CryptorResponsePlugin;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;

Reply via email to