From 8c23292bd1990079e1dbe0a7272a29b1460eb744 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 06:20:53 +0000 Subject: [PATCH 1/6] Initial plan From 89572f0cedc918491fb8f715158f3bb16c5a4f0d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 06:27:53 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wxpay/v3/util/RsaCryptoUtilTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java new file mode 100644 index 0000000000..dcd1d54104 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java @@ -0,0 +1,66 @@ +package com.github.binarywang.wxpay.v3.util; + +import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingReceiverV3Request; +import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request; +import com.github.binarywang.wxpay.exception.WxPayException; +import org.testng.annotations.Test; + +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import static org.testng.Assert.*; + +/** + * RsaCryptoUtil 测试类 + */ +public class RsaCryptoUtilTest { + + /** + * 测试嵌套对象中的字段加密 + * 验证 List 中每个 Receiver 对象的 name 字段是否能被正确加密 + */ + @Test + public void testEncryptFieldsWithNestedObjects() throws WxPayException { + // 由于需要真实的证书才能加密,这里只是验证递归逻辑是否正确 + // 创建测试对象 + ProfitSharingV3Request request = new ProfitSharingV3Request(); + + List receivers = new ArrayList<>(); + ProfitSharingV3Request.Receiver receiver = new ProfitSharingV3Request.Receiver(); + receiver.setName("张三"); // 设置需要加密的字段 + receiver.setAccount("test-account"); + receiver.setType("PERSONAL_OPENID"); + receiver.setAmount(100); + + receivers.add(receiver); + request.setReceivers(receivers); + + // 注意:这个测试需要有效的证书才能真正执行加密 + // 这里只是演示如何设置测试数据 + // 如果没有证书,会在实际加密时抛出异常 + + System.out.println("测试对象创建成功,name字段: " + receiver.getName()); + // 验证name字段不为null + assertNotNull(receiver.getName()); + assertEquals(receiver.getName(), "张三"); + } + + /** + * 测试单个对象中的字段加密 + * 验证直接在对象上的 @SpecEncrypt 字段是否能被正确加密 + */ + @Test + public void testEncryptFieldsWithDirectField() throws WxPayException { + // 创建测试对象 + ProfitSharingReceiverV3Request request = new ProfitSharingReceiverV3Request(); + request.setName("李四"); // 设置需要加密的字段 + request.setAccount("test-account"); + request.setType("PERSONAL_OPENID"); + + System.out.println("测试对象创建成功,name字段: " + request.getName()); + // 验证name字段不为null + assertNotNull(request.getName()); + assertEquals(request.getName(), "李四"); + } +} From ccd1936c6ad832ccca1dc82c9561ddfb1fc096b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 06:33:14 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A5=E9=AA=8C=E8=AF=81=E5=8A=A0=E5=AF=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wxpay/v3/util/RsaCryptoUtilTest.java | 91 ++++++++++++++++--- 1 file changed, 77 insertions(+), 14 deletions(-) diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java index dcd1d54104..f2f4e1afda 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java @@ -3,9 +3,10 @@ import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingReceiverV3Request; import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request; import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.v3.SpecEncrypt; import org.testng.annotations.Test; -import java.security.cert.X509Certificate; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -16,15 +17,55 @@ */ public class RsaCryptoUtilTest { + /** + * 测试反射能否找到嵌套类中的 @SpecEncrypt 注解字段 + */ + @Test + public void testFindAnnotatedFieldsInNestedClass() { + // 创建 Receiver 对象 + ProfitSharingV3Request.Receiver receiver = new ProfitSharingV3Request.Receiver(); + receiver.setName("测试姓名"); + + // 使用反射查找带有 @SpecEncrypt 注解的字段 + Class receiverClass = receiver.getClass(); + Field[] fields = receiverClass.getDeclaredFields(); + + System.out.println("=== Receiver 类中的所有字段 ==="); + boolean foundNameField = false; + boolean nameFieldHasAnnotation = false; + + for (Field field : fields) { + System.out.println("字段名: " + field.getName() + ", 类型: " + field.getType().getName()); + if (field.getName().equals("name")) { + foundNameField = true; + if (field.isAnnotationPresent(SpecEncrypt.class)) { + nameFieldHasAnnotation = true; + System.out.println(" -> name 字段有 @SpecEncrypt 注解"); + } else { + System.out.println(" -> name 字段没有 @SpecEncrypt 注解"); + } + } + } + + // 验证能够找到 name 字段并且它有 @SpecEncrypt 注解 + assertTrue(foundNameField, "应该能找到 name 字段"); + assertTrue(nameFieldHasAnnotation, "name 字段应该有 @SpecEncrypt 注解"); + } + /** * 测试嵌套对象中的字段加密 - * 验证 List 中每个 Receiver 对象的 name 字段是否能被正确加密 + * 验证 List 中每个 Receiver 对象的 name 字段是否能被正确找到和处理 */ @Test - public void testEncryptFieldsWithNestedObjects() throws WxPayException { - // 由于需要真实的证书才能加密,这里只是验证递归逻辑是否正确 + public void testEncryptFieldsWithNestedObjects() { // 创建测试对象 - ProfitSharingV3Request request = new ProfitSharingV3Request(); + ProfitSharingV3Request request = ProfitSharingV3Request.newBuilder() + .appid("test-appid") + .subMchId("test-submchid") + .transactionId("test-transaction") + .outOrderNo("test-order-no") + .unfreezeUnsplit(true) + .build(); List receivers = new ArrayList<>(); ProfitSharingV3Request.Receiver receiver = new ProfitSharingV3Request.Receiver(); @@ -32,13 +73,21 @@ public void testEncryptFieldsWithNestedObjects() throws WxPayException { receiver.setAccount("test-account"); receiver.setType("PERSONAL_OPENID"); receiver.setAmount(100); + receiver.setRelationType("STORE"); + receiver.setDescription("测试分账"); receivers.add(receiver); request.setReceivers(receivers); - // 注意:这个测试需要有效的证书才能真正执行加密 - // 这里只是演示如何设置测试数据 - // 如果没有证书,会在实际加密时抛出异常 + // 验证 receivers 字段有 @SpecEncrypt 注解 + try { + Field receiversField = ProfitSharingV3Request.class.getDeclaredField("receivers"); + boolean hasAnnotation = receiversField.isAnnotationPresent(SpecEncrypt.class); + System.out.println("ProfitSharingV3Request.receivers 字段有 @SpecEncrypt 注解: " + hasAnnotation); + assertTrue(hasAnnotation, "receivers 字段应该有 @SpecEncrypt 注解"); + } catch (NoSuchFieldException e) { + fail("应该能找到 receivers 字段"); + } System.out.println("测试对象创建成功,name字段: " + receiver.getName()); // 验证name字段不为null @@ -48,15 +97,29 @@ public void testEncryptFieldsWithNestedObjects() throws WxPayException { /** * 测试单个对象中的字段加密 - * 验证直接在对象上的 @SpecEncrypt 字段是否能被正确加密 + * 验证直接在对象上的 @SpecEncrypt 字段是否能被正确找到 */ @Test - public void testEncryptFieldsWithDirectField() throws WxPayException { + public void testEncryptFieldsWithDirectField() { // 创建测试对象 - ProfitSharingReceiverV3Request request = new ProfitSharingReceiverV3Request(); - request.setName("李四"); // 设置需要加密的字段 - request.setAccount("test-account"); - request.setType("PERSONAL_OPENID"); + ProfitSharingReceiverV3Request request = ProfitSharingReceiverV3Request.newBuilder() + .appid("test-appid") + .subMchId("test-submchid") + .type("PERSONAL_OPENID") + .account("test-account") + .name("李四") + .relationType("STORE") + .build(); + + // 验证 name 字段有 @SpecEncrypt 注解 + try { + Field nameField = ProfitSharingReceiverV3Request.class.getDeclaredField("name"); + boolean hasAnnotation = nameField.isAnnotationPresent(SpecEncrypt.class); + System.out.println("ProfitSharingReceiverV3Request.name 字段有 @SpecEncrypt 注解: " + hasAnnotation); + assertTrue(hasAnnotation, "name 字段应该有 @SpecEncrypt 注解"); + } catch (NoSuchFieldException e) { + fail("应该能找到 name 字段"); + } System.out.println("测试对象创建成功,name字段: " + request.getName()); // 验证name字段不为null From 6a9d6c6aca5df4e52f54f87fbef805380a6e7e7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 06:37:25 +0000 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20RsaCryptoUtil=20?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E7=BB=A7=E6=89=BF=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E7=9A=84=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wxpay/v3/util/RsaCryptoUtil.java | 22 +++++- .../wxpay/v3/util/RsaCryptoUtilTest.java | 69 +++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java index 8c3e2ace53..1f3b1ecd67 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java @@ -36,10 +36,28 @@ public static void encryptFields(Object encryptObject, X509Certificate certifica } } + /** + * 递归获取类的所有字段,包括父类中的字段 + * + * @param clazz 要获取字段的类 + * @return 所有字段的列表 + */ + private static java.util.List getAllFields(Class clazz) { + java.util.List fields = new java.util.ArrayList<>(); + while (clazz != null) { + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field field : declaredFields) { + fields.add(field); + } + clazz = clazz.getSuperclass(); + } + return fields; + } + private static void encryptField(Object encryptObject, X509Certificate certificate) throws IllegalAccessException, IllegalBlockSizeException { Class infoClass = encryptObject.getClass(); - Field[] infoFieldArray = infoClass.getDeclaredFields(); - for (Field field : infoFieldArray) { + java.util.List infoFieldList = getAllFields(infoClass); + for (Field field : infoFieldList) { if (field.isAnnotationPresent(SpecEncrypt.class)) { //字段使用了@SpecEncrypt进行标识 if (field.getType().getTypeName().equals(JAVA_LANG_STRING)) { diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java index f2f4e1afda..ef580de4fb 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java @@ -4,6 +4,8 @@ import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingV3Request; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.v3.SpecEncrypt; +import com.google.gson.annotations.SerializedName; +import lombok.Data; import org.testng.annotations.Test; import java.lang.reflect.Field; @@ -126,4 +128,71 @@ public void testEncryptFieldsWithDirectField() { assertNotNull(request.getName()); assertEquals(request.getName(), "李四"); } + + /** + * 测试类继承场景下的字段加密 + * 验证父类中带 @SpecEncrypt 注解的字段是否能被正确找到和加密 + */ + @Test + public void testEncryptFieldsWithInheritance() { + // 定义测试用的父类和子类 + @Data + class ParentRequest { + @SpecEncrypt + @SerializedName("parent_name") + private String parentName; + } + + @Data + @lombok.EqualsAndHashCode(callSuper = false) + class ChildRequest extends ParentRequest { + @SpecEncrypt + @SerializedName("child_name") + private String childName; + } + + // 创建子类实例 + ChildRequest request = new ChildRequest(); + request.setParentName("父类字段"); + request.setChildName("子类字段"); + + // 验证能够找到父类和子类的字段 + System.out.println("=== 测试继承场景 ==="); + System.out.println("父类字段值: " + request.getParentName()); + System.out.println("子类字段值: " + request.getChildName()); + + // 使用 getDeclaredFields 只能找到子类字段 + Field[] childFields = ChildRequest.class.getDeclaredFields(); + System.out.println("使用 getDeclaredFields 找到的字段数: " + childFields.length); + + // 使用 getAllFields 辅助方法应该能找到父类和子类的所有字段 + java.util.List allFields = getAllFields(ChildRequest.class); + System.out.println("使用 getAllFields 找到的字段数: " + allFields.size()); + + int annotatedFieldCount = 0; + for (Field field : allFields) { + if (field.isAnnotationPresent(SpecEncrypt.class)) { + annotatedFieldCount++; + System.out.println(" -> 找到带 @SpecEncrypt 注解的字段: " + field.getName()); + } + } + + // 应该找到2个带注解的字段(parentName 和 childName) + assertTrue(annotatedFieldCount >= 2, "应该能找到至少2个带 @SpecEncrypt 注解的字段"); + } + + /** + * 辅助方法:递归获取类的所有字段,包括父类中的字段 + */ + private java.util.List getAllFields(Class clazz) { + java.util.List fields = new ArrayList<>(); + while (clazz != null) { + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field field : declaredFields) { + fields.add(field); + } + clazz = clazz.getSuperclass(); + } + return fields; + } } From f048e7cf89a8fe0b19523a72e00b87aa834a7510 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 06:40:25 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC=EF=BC=9A=E4=BD=BF=E7=94=A8=E5=90=88=E9=80=82?= =?UTF-8?q?=E7=9A=84=E5=AF=BC=E5=85=A5=E8=80=8C=E4=B8=8D=E6=98=AF=E5=AE=8C?= =?UTF-8?q?=E5=85=A8=E9=99=90=E5=AE=9A=E7=B1=BB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../github/binarywang/wxpay/v3/util/RsaCryptoUtil.java | 8 +++++--- .../binarywang/wxpay/v3/util/RsaCryptoUtilTest.java | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java index 1f3b1ecd67..c8b773267e 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java @@ -14,8 +14,10 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Base64; import java.util.Collection; +import java.util.List; /** * 微信支付敏感信息加密 @@ -42,8 +44,8 @@ public static void encryptFields(Object encryptObject, X509Certificate certifica * @param clazz 要获取字段的类 * @return 所有字段的列表 */ - private static java.util.List getAllFields(Class clazz) { - java.util.List fields = new java.util.ArrayList<>(); + private static List getAllFields(Class clazz) { + List fields = new ArrayList<>(); while (clazz != null) { Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { @@ -56,7 +58,7 @@ private static java.util.List getAllFields(Class clazz) { private static void encryptField(Object encryptObject, X509Certificate certificate) throws IllegalAccessException, IllegalBlockSizeException { Class infoClass = encryptObject.getClass(); - java.util.List infoFieldList = getAllFields(infoClass); + List infoFieldList = getAllFields(infoClass); for (Field field : infoFieldList) { if (field.isAnnotationPresent(SpecEncrypt.class)) { //字段使用了@SpecEncrypt进行标识 diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java index ef580de4fb..51161326cd 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java @@ -166,7 +166,7 @@ class ChildRequest extends ParentRequest { System.out.println("使用 getDeclaredFields 找到的字段数: " + childFields.length); // 使用 getAllFields 辅助方法应该能找到父类和子类的所有字段 - java.util.List allFields = getAllFields(ChildRequest.class); + List allFields = getAllFields(ChildRequest.class); System.out.println("使用 getAllFields 找到的字段数: " + allFields.size()); int annotatedFieldCount = 0; @@ -184,8 +184,8 @@ class ChildRequest extends ParentRequest { /** * 辅助方法:递归获取类的所有字段,包括父类中的字段 */ - private java.util.List getAllFields(Class clazz) { - java.util.List fields = new ArrayList<>(); + private List getAllFields(Class clazz) { + List fields = new ArrayList<>(); while (clazz != null) { Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { From 9b23730457f2cb8a1c31a99d2d9445d89fd6b6bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 06:42:42 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E6=94=B9=E8=BF=9B=20getAllFields=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E6=95=88=E7=8E=87=E5=B9=B6=E9=81=BF=E5=85=8D=E9=81=8D?= =?UTF-8?q?=E5=8E=86=20Object=20=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java | 7 +++---- .../github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java | 6 ++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java index c8b773267e..dbf7ddb9c2 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtil.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Base64; import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -46,11 +47,9 @@ public static void encryptFields(Object encryptObject, X509Certificate certifica */ private static List getAllFields(Class clazz) { List fields = new ArrayList<>(); - while (clazz != null) { + while (clazz != null && clazz != Object.class) { Field[] declaredFields = clazz.getDeclaredFields(); - for (Field field : declaredFields) { - fields.add(field); - } + java.util.Collections.addAll(fields, declaredFields); clazz = clazz.getSuperclass(); } return fields; diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java index 51161326cd..5b09a6d8c7 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/v3/util/RsaCryptoUtilTest.java @@ -186,11 +186,9 @@ class ChildRequest extends ParentRequest { */ private List getAllFields(Class clazz) { List fields = new ArrayList<>(); - while (clazz != null) { + while (clazz != null && clazz != Object.class) { Field[] declaredFields = clazz.getDeclaredFields(); - for (Field field : declaredFields) { - fields.add(field); - } + java.util.Collections.addAll(fields, declaredFields); clazz = clazz.getSuperclass(); } return fields;