【前后端数据转换】通过JsonSerialize或JSONField 配置BigDecimal精度,以及@JsonSerialize失效原因

今天突然 想着fastjson也应该支持注解方式指定序列类才对,不一定要全局配置,这才是最灵活的吧!

结论:没有在mvc配置configureMessageConverters,默认配置的序列化是jackson,使用@JsonSerialize;

在 configureMessageConverters配置了fastjson处理的,使用@JSONField

下面是fastjson处理的相关代码。 configureMessageConverters配置在文章尾部

public class MyBigDecimalCodec extends BigDecimalCodec implements ContextObjectSerializer {

    public static final MyBigDecimalCodec instance = new MyBigDecimalCodec();

    @Override
    public void write(JSONSerializer serializer, Object object, BeanContext context) {
        String format = StringUtils.isNotBlank(context.getFormat()) ? context.getFormat() : "#0.00";
        serializer.out.writeString(object != null ? new DecimalFormat(format).format(object) : "0.00");
    }
}
//注意一个细节,注解的 format 必须要加的,不然就不会生效,这点上我有些奇怪
    @JSONField(serializeUsing = MyBigDecimalCodec.class,format = "#0.00")
    private BigDecimal num;

——————————————————————————————————————————
这两天有个需求,要求保留BigDecimal小数点后两位,想着不如全局配置了,
网上查了用@JsonSerialize在序列化时进行数据处理:
1、重写serialize

public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value != null) {
            gen.writeNumber(new DecimalFormat("#0.00").format(value));
        }
    }
}

2、增加注解

    @JsonSerialize(using = BigDecimalSerializer.class)
    private BigDecimal num;

打了断点,有走该方法,但是swagger调用发现数值并没有改变,查了半天,发现应该在
WebConfig extends WebMvcConfigurationSupport 里面的 configureMessageConverters方法 配置了 fastjson ,大概 Jackson 的估计是被覆盖了。

于是查了资料,使用fastjson 的序列处理,参考了文章链接:https://blog.csdn.net/panyox/article/details/106632353

文章写得很清晰,两种方式
1、和@JsonSerialize差不多

重写序列方法

public class MyBigDecimalCodec extends BigDecimalCodec implements ContextObjectSerializer {
 
    public final static MyBigDecimalCodec instance = new MyBigDecimalCodec();
 
    @Override
    public void write(JSONSerializer serializer, Object object, BeanContext context) {
        if (object != null) {
	        serializer.out.writeString(new DecimalFormat(context.getFormat()).format(object));
        }
    }
}

在字段上添加注解,比较灵活

    @JSONField(format = "#0.00")
    private BigDecimal num;

需要在继承 WebMvcConfigurationSupport 或者 实现 WebMvcConfigurer 的类中的configureMessageConverters里添加 FastJsonConfig

@EnableWebMvc
@Configuration
public class WebConfigPlus implements WebMvcConfigurer {

	    @Override
	    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
	        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
	        List<MediaType> supportedMediaTypes = new ArrayList();
	        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
	        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
	        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
	        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
	        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
	        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
	        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
	        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
	        supportedMediaTypes.add(MediaType.APPLICATION_XML);
	        supportedMediaTypes.add(MediaType.IMAGE_GIF);
	        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
	        supportedMediaTypes.add(MediaType.IMAGE_PNG);
	        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
	        supportedMediaTypes.add(MediaType.TEXT_HTML);
	        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
	        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
	        supportedMediaTypes.add(MediaType.TEXT_XML);
	        fastJsonConverter.setSupportedMediaTypes(supportedMediaTypes);
	        FastJsonConfig fjc = new FastJsonConfig();
	        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
	        serializeConfig.put(Long.class, ToStringSerializer.instance);
	        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
	     	//增加自定义配置    **这里可以不自定义配置,用注解的方式实现,可以看文章开头**
	        serializeConfig.put(BigDecimal.class, MyBigDecimalCodec.instance);
	        fjc.setSerializeConfig(serializeConfig);
	        fjc.setDateFormat("yyyy-MM-dd HH:mm:ss");
	        fjc.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullListAsEmpty);
	        fastJsonConverter.setFastJsonConfig(fjc);
	        converters.add(fastJsonConverter);
	    }
    }

2、全局配置 缺少灵活性,不过简单啊
新增过滤器

public class BigDecimalValueFilter implements ValueFilter {

    @Override
    public Object process(Object object, String name, Object value) {
        return value instanceof BigDecimal
                ? new DecimalFormat("#0.00").format(value)
                : value;
    }

}

mvc配置

@EnableWebMvc
@Configuration
public class WebConfigPlus implements WebMvcConfigurer {
 
	    @Override
	    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
	        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
	        List<MediaType> supportedMediaTypes = new ArrayList();
	        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
	        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
	        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
	        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
	        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
	        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
	        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
	        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
	        supportedMediaTypes.add(MediaType.APPLICATION_XML);
	        supportedMediaTypes.add(MediaType.IMAGE_GIF);
	        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
	        supportedMediaTypes.add(MediaType.IMAGE_PNG);
	        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
	        supportedMediaTypes.add(MediaType.TEXT_HTML);
	        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
	        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
	        supportedMediaTypes.add(MediaType.TEXT_XML);
	        fastJsonConverter.setSupportedMediaTypes(supportedMediaTypes);
	        FastJsonConfig fjc = new FastJsonConfig();
	        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
	        serializeConfig.put(Long.class, ToStringSerializer.instance);
	        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
	        //添加过滤器
	        fjc.setSerializeFilters(new BigDecimalValueFilter());
	        fjc.setSerializeConfig(serializeConfig);
	        fjc.setDateFormat("yyyy-MM-dd HH:mm:ss");
	        fjc.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullListAsEmpty);
	        fastJsonConverter.setFastJsonConfig(fjc);
	        converters.add(fastJsonConverter);
	    }
    }

本以为到这就结束了,然后又学习了。。
————————————————————————————————————————————

本身项目依赖于别的依赖,已经做了 继承 WebMvcConfigurationSupport 的配置,要解决怎么重写configureMessageConverters 方法。
这要谈到 继承 WebMvcConfigurationSupport 或者 实现 WebMvcConfigurer 的区别。

个人理解,两者都是webMvc的配置类,一个继承一个实现,WebMvcConfigurationSupport应该是比较老旧配置类,能不用就不用,
目前springmvc推荐开发者使用 实现 WebMvcConfigurer,它本身有默认配置,使用起来比较安全,
之前还有一个WebMvcConfigurerAdapter, 在 接口可以使用关键字 default 就可以舍弃了。

当已经全局配置WebMvcConfigurationSupport ,做了以下尝试:
1、再写一个 方法继承 WebMvcConfigurationSupport ,发现两个都不生效了,mvc使用了默认DelegatingWebMvcConfiguration
2、实现 WebMvcConfigurer ,需要添加 @EnableWebMvc 原来的配置类不生效,否则当前配置不生效

@EnableWebMvc
@Configuration
public class WebConfigPlus implements WebMvcConfigurer {

尝试多次发现 继承 WebMvcConfigurationSupport实现 WebMvcConfigurer 不共存,没办法,也不好动别人的代码,全复制过来了事。
查了相关资料,都说只用实现 WebMvcConfigurer的配置类,可以做到多个配置共存,未尝试。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值