You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jackson XMLMapper实现浮点类型十进制分隔符的本地化

解决方案

Jackson本身没有内置十进制分隔符本地化的开关,但可以通过自定义数值序列化器+全局注册的方式优雅实现,属于Jackson标准扩展能力,不需要修改核心逻辑。

实现步骤

  1. 自定义浮点/十进制类型序列化器
    这里我们统一处理Float/Double/BigDecimal三类数值类型,可按需调整小数保留位数:
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols

// 通用本地化数值序列化器
class LocalizedNumberSerializer(t: Class<*>) : StdSerializer<Number>(t) {
    // 配置格式:保留2位小数,十进制分隔符为逗号
    private val format = DecimalFormat("0.00").apply {
        decimalFormatSymbols = DecimalFormatSymbols().apply {
            decimalSeparator = ','
        }
        isGroupingUsed = false // 关闭千位分隔符,如有需要可自行开启
    }

    override fun serialize(value: Number, gen: JsonGenerator, provider: SerializerProvider) {
        gen.writeString(format.format(value))
    }
}

注意:XML Schema的原生数值类型要求用.作为十进制分隔符,逗号分隔符的数值本身不符合XML数值标准,因此序列化后以字符串类型承载该值,是该场景下的通用实现方式。

  1. 将序列化器注册到XmlMapper
    创建SimpleModule注册自定义序列化器,添加到原有配置中即可全局生效:
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.dataformat.xml.XmlMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator

val xmlMapper = XmlMapper()

// 新增:注册本地化数值序列化器
val numberModule = SimpleModule()
numberModule.addSerializer(Float::class.java, LocalizedNumberSerializer(Float::class.java))
numberModule.addSerializer(Double::class.java, LocalizedNumberSerializer(Double::class.java))
numberModule.addSerializer(BigDecimal::class.java, LocalizedNumberSerializer(BigDecimal::class.java))
xmlMapper.registerModule(numberModule)

// 保留原有配置不变
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT)
xmlMapper.propertyNamingStrategy = CustomPropertyNamingStrategy()
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true)
xmlMapper.setDefaultUseWrapper(false)

可选扩展

如果不需要全局生效,仅需要部分字段使用逗号分隔符,可以去掉全局注册的逻辑,直接在对应字段上添加@JsonSerialize注解即可:

data class YourXmlEntity(
    @JacksonXmlProperty(localName = "amount")
    @JsonSerialize(using = LocalizedNumberSerializer::class)
    val amount: Double
)

内容的提问来源于stack exchange,提问作者Felix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:06:03