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

Spring Web中FastMoney使用及Lombok、表单转换问题

解决方案

1. 用Lombok配置FastMoney类型字段

FastMoney没有公共无参构造函数,无法通过常规方式直接实例化,需要结合Lombok的扩展能力和Jackson自定义反序列化来解决:

调整DTO的Lombok注解与构造逻辑

修改PaymentDto,通过自定义Builder方法来适配FastMoney的实例化规则,同时保留Lombok的便利性:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor // 为Jackson反序列化提供基础构造(可选,若自定义反序列化无需则可省略)
public class PaymentDto {
    private String recipientName;
    @JsonInclude
    @JsonDeserialize(using = FastMoneyDeserializer.class) // 关联自定义反序列化器
    private FastMoney amount;

    // 自定义Builder方法,支持传入纯金额数值,自动绑定默认货币
    public static class PaymentDtoBuilder {
        public PaymentDtoBuilder amount(BigDecimal amount) {
            // 这里用业务约定的默认货币,比如USD或系统默认区域货币
            this.amount = FastMoney.of(amount, CurrencyUnit.getInstance(Locale.getDefault()));
            return this;
        }

        public PaymentDtoBuilder amount(String amountStr) {
            // 支持解析带货币的字符串,如"100.00 USD"
            this.amount = FastMoney.parse(amountStr);
            return this;
        }
    }
}

添加Jackson自定义反序列化器

编写反序列化器处理前端传入的纯数字或字符串金额,自动补全默认货币:

public class FastMoneyDeserializer extends JsonDeserializer<FastMoney> {
    @Override
    public FastMoney deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = p.getText();
        // 处理纯数字格式的金额,绑定默认货币
        if (value.matches("\\d+(\\.\\d+)?")) {
            return FastMoney.of(new BigDecimal(value), CurrencyUnit.of("USD"));
        }
        // 处理带货币标识的字符串格式
        return FastMoney.parse(value);
    }
}

配置完成后,Postman提交{"amount": 100.00}或{"amount": "100.00"}时,会自动转换为带默认货币的FastMoney实例。

2. Thymeleaf表单提交值转换为FastMoney

Spring MVC无法自动将表单字符串转换为FastMoney,需要自定义类型转换器:

实现Converter接口

@Component
public class StringToFastMoneyConverter implements Converter<String, FastMoney> {
    @Override
    public FastMoney convert(String source) {
        // 处理表单提交的纯数字金额,绑定默认货币
        if (source.matches("\\d+(\\.\\d+)?")) {
            return FastMoney.of(new BigDecimal(source), CurrencyUnit.of("USD"));
        }
        // 支持用户输入带货币的格式,如"100.00 USD"
        return FastMoney.parse(source);
    }
}

注册转换器(可选)

如果Spring未自动扫描到转换器,可在Web配置类中手动注册:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToFastMoneyConverter());
    }
}

之后Thymeleaf表单提交的金额(如<input type="text" name="amount" value="100.00"/>)会自动转换为FastMoney实例并绑定到PaymentDto。

补充说明

JavaMoney的设计强制绑定货币,无货币的金额不具备业务意义。如果暂时不需要前端指定,建议后端统一使用业务约定的默认货币,后续再扩展多货币支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:26:10