alibaba / fastjson2

🚄 FASTJSON2 is a Java JSON library with excellent performance.
Apache License 2.0
3.74k stars 484 forks source link

如何像fastjson1一样,在使用@JSONField注解时,获取注解上的format属性的值 #2400

Open 1029219814 opened 6 months ago

1029219814 commented 6 months ago

请描述您的问题

询问有关本项目的使用和其他方面的相关问题。 在fastjson1中,继承ContextObjectSerializer,我可以通过BeanContext context获取JSONField注解中的format字段,类似 @JSONField(serializeUsing = CustomerBigDecimalCodec.class, format = "#,###.####") 在CustomerBigDecimalCodec中,可以对不同字段实现不同精度的序列化,但是在fastjson2中。如何实现类似的需求,通过继承ObjectWriter,JSONWriter无法获取JSONField注解上format的值

public class CustomerBigDecimalCodec extends BigDecimalCodec implements ContextObjectSerializer {
    @Override
    public void write(JSONSerializer serializer, Object object, BeanContext context) throws IOException {
        SerializeWriter out = serializer.out;
        if (object == null) {
            out.writeString("0.00");
            return;
        }
        String format = context.getFormat();
        String[] split = format.split(":");
        if (split.length > 1) {
            BigDecimal number = ((BigDecimal) object).setScale(Integer.parseInt(split[1]), RoundingMode.HALF_UP);
            DecimalFormat formatter = new DecimalFormat(split[0]);
            out.writeString(formatter.format(number));
            return;
        }
        DecimalFormat decimalFormat = new DecimalFormat(format);
        out.writeString(decimalFormat.format(object));
    }
}
wenshao commented 6 months ago
@Test
    public void test() {
        final AtomicReference<String> formatRef = new AtomicReference<>();
        ContextValueFilter contextValueFilter = new ContextValueFilter() {
            @Override
            public Object process(BeanContext context, Object object, String name, Object value) {
                formatRef.set(context.getFormat());
                return value;
            }
        };

        Bean bean = new Bean();
        bean.id = LocalDate.of(2012, 3, 4);
        JSON.toJSONString(bean, contextValueFilter);
        assertEquals("yyyyMMdd", formatRef.get());

    }

    public static class Bean {
        @JSONField(format = "yyyyMMdd")
        public LocalDate id;
    }

你看下这个ContextValueFilter是不是你想要的

1029219814 commented 6 months ago

不能像以前一样方便么,不去主动传入Filer,因为是统一进行JSON.toJSONString的

@Test
    public void test() {
        final AtomicReference<String> formatRef = new AtomicReference<>();
        ContextValueFilter contextValueFilter = new ContextValueFilter() {
            @Override
            public Object process(BeanContext context, Object object, String name, Object value) {
                formatRef.set(context.getFormat());
                return value;
            }
        };

        Bean bean = new Bean();
        bean.id = LocalDate.of(2012, 3, 4);
        JSON.toJSONString(bean, contextValueFilter);
        assertEquals("yyyyMMdd", formatRef.get());

    }

    public static class Bean {
        @JSONField(format = "yyyyMMdd")
        public LocalDate id;
    }

你看下这个ContextValueFilter是不是你想要的