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

Spring Boot+Thymeleaf中String转joda.money类型绑定问题解决

问题根因

Spring MVC 执行Thymeleaf表单绑定时,前端数字输入框提交的值默认以String类型传递到后端,框架内置的类型转换规则未覆盖org.joda.money.Money类型,找不到匹配的转换策略时就会抛出BindException。

实现方案

推荐使用全局类型转换器实现,一次配置全项目生效,无需重复编写绑定逻辑。

方案1:全局Converter(推荐)

  • 编写自定义转换类实现Spring的Converter<S,T>接口,完成String到Money的转换逻辑,可根据业务指定固定默认币种:
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;

@Component
public class StringToMoneyConverter implements Converter<String, Money> {
    // 按业务需求替换为对应币种,示例为人民币CNY,美元可改为CurrencyUnit.USD
    private static final CurrencyUnit DEFAULT_CURRENCY_UNIT = CurrencyUnit.CNY;

    @Override
    public Money convert(String sourceVal) {
        if (sourceVal == null || sourceVal.trim().isEmpty()) {
            return null;
        }
        BigDecimal amount = new BigDecimal(sourceVal.trim());
        return Money.of(DEFAULT_CURRENCY_UNIT, amount);
    }
}
  • 若转换器未被自动注册(少数低版本Spring Boot需要手动配置),添加WebMVC配置类手动注册:
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    private final StringToMoneyConverter stringToMoneyConverter;

    public WebConfig(StringToMoneyConverter stringToMoneyConverter) {
        this.stringToMoneyConverter = stringToMoneyConverter;
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(stringToMoneyConverter);
    }
}

方案2:单Controller生效的@InitBinder配置

如果不需要全局生效,只需要在处理Governor表单的Controller中添加绑定逻辑即可:

import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import java.beans.PropertyEditorSupport;
import java.math.BigDecimal;

// 该方法写在你的GovernorController内部
@InitBinder
public void initMoneyBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Money.class, new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            if (text == null || text.trim().isEmpty()) {
                setValue(null);
                return;
            }
            setValue(Money.of(CurrencyUnit.CNY, new BigDecimal(text.trim())));
        }
    });
}
注意事项
  • 如果业务场景支持多币种,可以在前端表单新增币种选择输入项,调整转换器逻辑同时接收币种、金额参数解析生成Money实例即可
  • 转换逻辑中可根据需要添加金额格式校验、非法入参异常提示,避免非数字传入导致转换报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:57:19