From 8dee60c581315cb0738c9fe529422633ea019f1a Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Fri, 10 May 2024 20:01:05 +0800 Subject: [PATCH] fix fastjson 1.x JSONField#unwrapped not work, for issue #2551 --- .../com/alibaba/fastjson2/util/BeanUtils.java | 24 ++++- .../alibaba/fastjson/v2issues/Issue2551.java | 99 +++++++++++++++++++ 2 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 fastjson1-compatible/src/test/java/com/alibaba/fastjson/v2issues/Issue2551.java diff --git a/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java b/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java index 47c34be9c0..191355a5e4 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java @@ -510,13 +510,13 @@ public static void setters(Class objectClass, BeanInfo beanInfo, Class mixin, Co ) { Annotation[] annotations = getAnnotations(method); - boolean unwrapped = false; + AtomicBoolean unwrapped = new AtomicBoolean(false); for (Annotation annotation : annotations) { Class annotationType = annotation.annotationType(); JSONField jsonField = findAnnotation(annotation, JSONField.class); if (jsonField != null) { if (jsonField.unwrapped()) { - unwrapped = true; + unwrapped.set(true); break; } continue; @@ -526,15 +526,31 @@ public static void setters(Class objectClass, BeanInfo beanInfo, Class mixin, Co case "com.fasterxml.jackson.annotation.JsonAnySetter": case "com.alibaba.fastjson2.adapter.jackson.annotation.JsonAnySetter": if (JSONFactory.isUseJacksonAnnotation()) { - unwrapped = true; + unwrapped.set(true); } break; + case "com.alibaba.fastjson.annotation.JSONField": { + BeanUtils.annotationMethods(annotation.getClass(), m -> { + String name = m.getName(); + try { + if ("unwrapped".equals(name)) { + Object result = m.invoke(annotation); + if ((Boolean) result) { + unwrapped.set(true); + } + } + } catch (Throwable ignored) { + // ignored + } + }); + break; + } default: break; } } - if (unwrapped) { + if (unwrapped.get()) { methodConsumer.accept(method); } continue; diff --git a/fastjson1-compatible/src/test/java/com/alibaba/fastjson/v2issues/Issue2551.java b/fastjson1-compatible/src/test/java/com/alibaba/fastjson/v2issues/Issue2551.java new file mode 100644 index 0000000000..203931515b --- /dev/null +++ b/fastjson1-compatible/src/test/java/com/alibaba/fastjson/v2issues/Issue2551.java @@ -0,0 +1,99 @@ +package com.alibaba.fastjson.v2issues; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONPath; +import com.alibaba.fastjson2.annotation.JSONField; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class Issue2551 { + @Test + public void test() { + String json = "{\"name\": \"zhangsan\", \"age\": 18}"; + People p = JSON.parseObject(json, People.class); + + assertEquals("zhangsan", p.getName()); + assertEquals(18, p.getExtra().get("age")); + + JSONPath.set(p, "$.age", 20); + assertEquals(20, p.getExtra().get("age")); + } + + static class People { + private String name; + private Map extra = new HashMap<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getExtra() { + return extra; + } + + public void setExtra(Map extra) { + this.extra = extra; + } + + @JSONField(unwrapped = true) + public void set(String key, Object value) { + this.extra.put(key, value); + } + + @JSONField(unwrapped = true) + public Object get(String key) { + return this.extra.get(key); + } + } + + @Test + public void testfj() { + String json = "{\"name\": \"zhangsan\", \"age\": 18}"; + People1 p = com.alibaba.fastjson.JSON.parseObject(json, People1.class); + + assertEquals("zhangsan", p.getName()); + assertEquals(18, p.getExtra().get("age")); + + com.alibaba.fastjson.JSONPath.set(p, "$.age", 20); + assertEquals(20, p.getExtra().get("age")); + } + + static class People1 { + private String name; + private Map extra = new HashMap<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getExtra() { + return extra; + } + + public void setExtra(Map extra) { + this.extra = extra; + } + + @com.alibaba.fastjson.annotation.JSONField(unwrapped = true) + public void set(String key, Object value) { + this.extra.put(key, value); + } + + @com.alibaba.fastjson.annotation.JSONField(unwrapped = true) + public Object get(String key) { + return this.extra.get(key); + } + } +}