在javaweb项目中返回一个fee,fee类型使用BigDecimal,然后直接按照公司框架封装返回值,结果报错。项目使用的框架为SpringBoot+swagger+lombok,代码如下:请求接口:@ApiOperation(value="查询费用测试2")@PostMapping(path="/getFee2/{fee}")publicResultVogetFee2(@PathVariableStringfee){BigDecimalf=StringUtils.isEmpty(fee)?null:newBigDecimal(费用);returnResultVo.ok(f);}返回结果包装类@ApiModel("返回信息包装类")@DatapublicclassResultVo{publicstaticfinalintOK_CODE=0;publicstaticfinalintERROR_CODE=1;privatestaticfinalStringDEFAULT_MESSAGE="OK";私人静态最终ResultVoOK_VO;内容;static{OK_VO=newResultVo<>(OK_CODE,DEFAULT_MESSAGE);}publicResultVo(Stringcode,StringerrorMsg,Tcontent){this.code=code;this.errorMsg=errorMsg;this.content=内容;publicstaticResultVook(T内容){返回新的ResultVo<>(OK_CODE,null,content);}publicstaticResultVoerror(Tcontent){returnnewResultVo<>(ERROR_CODE,null,content);}publicstaticResultVook(){returnOK_VO;}publicResultVo(){}}接口请求链接:curl-XPOST"http://localhost:8080/shop/getFee2/10"-H"accept:*/*"请求返回结果是:大体意思error是BigDecimal类型的数据在序列化的时候有问题。方案一:在yml中添加如下配置spring:jackson:serialization:FAIL_ON_EMPTY_BEANS:false或者在代码中添加@BeanpublicObjectMapperobjectMapper(){returnnewObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)}结果是请求接口不再报错,但返回数据的值变为null。这个结果不是我所期望的。方案二:将BigDecimal类型的数据转换成其他数据类型返回,比如String。代码如下:@ApiOperation(value="QueryFeeTest2")@PostMapping(path="/getFee2/{fee}")publicResultVogetFee2(@PathVariableStringfee){BigDecimalf=StringUtils.是空的(费用)?null:newBigDecimal(费用);returnResultVo.ok(Objects.nonNull(f)?f.toString():null);}返回结果如下:{"code":"0","errorMsg":null,"content":"10.00"}好像解决了问题,但是没有办法自定义数据格式,比如如果数字是整数,我不要小数点和小数点后的数字。方案三:添加BigDecimal的序列化方法,添加内容如下:@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@JacksonAnnotationsInside@JsonSerialize(using=BigDecimalSerializer.class)@JsonDeserialize(using=BigDecimalDeSerializer.class)public@interfaceBigDecimalFormat{Stringvalue()default"#.000";}@JsonComponentpublicclassBigDecimalDeSerializerextendsJsonDeserializer{@OverridepublicBigDecimaldeserialize(JsonParserjsonParser,DeserializationContextdeserializationContext)抛出IOException,JsonProcessingException{returnnewBigDecimal(jsonParser.获取文本());}}@JsonComponentpublicclassBigDecimalSerializerextendsJsonSerializerimplementsContextualSerializer{//默认格式化方案,在项目中添加BigDecimal格式化配置后,privateStringformat="#.00";@OverridepublicJsonSerializer>createContextual(SerializerProviderserializerProvider,BeanPropertybeanProperty)日行JsonMappingException{if(beanProperty!=null){if(Objects.equals(beanProperty.getType().getRawClass(),BigDecimal.class)){BigDecimalFormatbigDecimalFormat=beanProperty.getAnnotation((BigDecimalFormat.class));如果(bigDecimalFormat==null){bigDecimalFormat=beanProperty.getContextAnnotation(BigDecimalFormat.class);}BigDecimalSerializerbigDecimalSerializer=newBigDecimalSerializer();if(bigDecimalFormat!=null){bigDecimalSerializer.format=bigDecimalFormat.value();}返回bigDecimalSerializer;}返回serializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);}返回serializerProvider.findNullValueSerializer(beanProperty);}@Overridepublicvoidserialize(BigDecimalbigDecimal,JsonGeneratorjsonGenerator,SerializerProviderserializerProvider)抛出IOException{jsonGenerator.writeString(newDecimalFormat(format).format(bigDecimal));}}使用方法如下:将返回的结果fee放入对象中,并为fee字段添加序列化注解,代码如下:@DatapublicclassGetFeeRspVo{@ApiModelProperty(name="fee")@BigDecimalFormat("#.##")privateBigDecimal费用;publicGetFeeRspVo(){}publicGetFeeRspVo(BigDecimalfee){this.fee=fee;}}请求接口返回的结果如下:{"code":"0","errorMsg":null,"content":{"fee":"10"}}看来返回的结果符合我们的需要。解决方案4:是否包装类?研究了方案三的序列化方法,找到了核心的序列化代码jsonGenerator.writeString(newDecimalFormat(format).format(bigDecimal));根据这行代码,我们可以自己手动序列化BigDecimal数据。完整代码如下:@ApiOperation(value="Queryfeetest1")@PostMapping(path="/getFee1/{fee}")publicResultVogetFee1(@PathVariableStringfee){BigDecimalf=StringUtils.isEmpty(费用)?null:newBigDecimal(费用);returnResultVo.ok(newDecimalFormat("#.##").format(f));}返回结果如下:{"code":"0","errorMsg":null,"content":"10"}好像也能满足要求。总结:方案3和方案4都能满足要求。其中方案三比较通用,方案四的代码比较简洁。参考文章:https://blog.csdn.net/read225...https://blog.csdn.net/qq_4135...