Spring+MySQL中@NumberFormat注解问题:千分位数值提交转换失败
问题:Spring表单提交带千分位格式数值时类型转换失败
我在MySQL中创建了如下表:
CREATE TABLE `myTab` ( `code` VARCHAR(10) NOT NULL, `membershipValue` DOUBLE(15,2) NULL, PRIMARY KEY (`code`));
对应的Java实体类如下:
@Id private String code; @NumberFormat(pattern="###,##0.00") private Double membershipValue=0.0;
我使用@NumberFormat注解实现期望的货币格式,并通过Spring和Thymeleaf创建了如下表单:
<form th:action="@{/plan/addMyTab}" th:object="${oMyTab}" method="post"> <div class="row"> <fieldset class="form-group border rounded-3 p-3"> <legend>Membership</legend> <div class="row"> <label class="col-sm-2 col-form-label">Membership value</label> <div class="col-sm-2"> <input class="form-control" type="text" th:field="*{membershipValue}"> </div> <div class="col-sm-1"> <span class="mensagem" th:if="${#fields.hasErrors('membershipValue')}" th:errors="*{membershipValue}"></span> </div> </div> </fieldset> </div> <input class="btn btn-primary" type="submit" value="Gravar" /> </form>
提交表单时,输入大于1000.00(格式为1.234,56)的数值时出现错误:
Failed to convert property value of type java.lang.String to required type java.lang.Double for property membershipValue; For input string: "1.234,56"
请问我哪里操作有误?
问题原因与解决方案
问题根源
@NumberFormat注解默认仅负责页面展示时的数值格式化,但表单提交时,Spring的默认数据转换器无法识别这种带千分位分隔符(.)、逗号作为小数分隔符的字符串,没法把它转换成Double类型,所以抛出转换错误。
解决办法
方法1:调整实体类注解,指定本地化解析规则
修改@NumberFormat注解,明确指定格式化风格和对应本地化信息,让Spring既能处理展示格式化,也能处理提交时的解析:
@Id private String code; // 适配千分位用点、小数用逗号的格式(如葡萄牙语巴西地区) @NumberFormat(pattern = "###,##0.00", style = NumberFormat.Style.NUMBER) private Double membershipValue = 0.0;
如果是货币格式,也可以直接用风格枚举简化:
@NumberFormat(style = NumberFormat.Style.CURRENCY, locale = "pt_BR") private Double membershipValue = 0.0;
方法2:配置全局数字格式化解析器
如果需要整个项目都支持这种格式的数值解析,可以创建全局配置类,注册自定义的数字格式化器:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { // 创建对应本地化的数字格式化器,这里以pt_BR为例,对应1.234,56格式 NumberFormat numberFormat = NumberFormat.getNumberInstance(new Locale("pt", "BR")); numberFormat.setMinimumFractionDigits(2); numberFormat.setMaximumFractionDigits(2); // 注册格式化器,让Spring处理Double类型时使用该规则 registry.addFormatterForFieldType(Double.class, new NumberFormatter(numberFormat)); } }
注意事项
确保页面渲染和表单提交的本地化规则一致,比如如果页面用的是葡萄牙语巴西地区的格式,后端解析也要用相同的本地化配置,避免格式不匹配导致的转换失败。
内容的提问来源于stack exchange,提问作者gapler
相关产品推荐
相关产品推荐

