发布时间:2023-04-25 分类:WEB开发, 电脑百科 字号: 默认 - - 超大 打印
  1. fastjson的ToStringSerializer注解:

java中long数据能表示的范围比js中number大,在跟前端交互时,这样也就意味着部分数值在js中存不下(变成不准确的值)。

解决办法可以这样:

使用fastjson的ToStringSerializer注解,让系统序列化时,保留相关精度。

/**
* 记录属性的主键
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;

场景: id为long,传到后台就变了值 。

测试一下,这个要是只有几位数的情况下,其实都不需要这个注解,大于某个值,19位数的时候就会出问题,导致精度丢失;

解决办法:在实体类上面添加这个注解就可以了。

原因:使用fastjson的ToStringSerializer注解,让系统序列化时,保留相关精度。

ToStringSerializer是一个类,还有一个与它类似的是

@JsonSerialize(using = LongToStringUtil.class) 和前端交互时,值比number数值更大,会导致精度缺失,使用JsonSerialize注解,可以帮助我们解决该问题。

在using = LongToStringUtil.class,可以使用我们自定义的类,来将我们传入的值转换为String类型,来传入到前端,可以解决精度问题,定义的LongToStringUtil类需要继承自JsonSerializer类。

  1. @JsonSerialize注解自定义class的使用方法:

关于这个注解的方法,可以自己定义class,作为using的值来使用。

/**
* 订单创建时间
*/
@JsonSerialize(using = DateToLongSerializer.class)
private Date createTime;

这个的意义就是当转成json时,把时间转成秒的格式。

public class DateToLongSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator,
                SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(date.getTime() / 1000);
}
}
  1. @JsonSerialize注解处理BigDecimal自定义方法:

  • BigDecimal 类型的字段,指定保留两位小数(或者更多自定义):

创建一个注解类,统一帮助我们实现对BigDecimal此类型字段数值的封装操作

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
public class BigDecimal2Serializer extends JsonSerializer<BigDecimal> {
public BigDecimal2Serializer() {
}
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider
serializers) throws IOException {
if (value != null) {
BigDecimal number = value.setScale(2, BigDecimal.ROUND_HALF_UP);
gen.writeNumber(number);
} else {
gen.writeNumber(value);
}
}
}

创建完注解类后,具体什么字段需要保留两位有效数字,就在对应的字段上加上此注解

@JsonSerialize(using = BigDecimal2Serializer.class)
private BigDecimal price;

最后返回的值就是保留两位有效数字的

  • 相关方法

构造器描述

BigDecimal(int) 创建一个具有参数所指定整数值的对象。

BigDecimal(double) 创建一个具有参数所指定双精度值的对象。

BigDecimal(long) 创建一个具有参数所指定长整数值的对象。

BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。

方法

add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。

subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。

multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。

divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。

toString() 将BigDecimal对象的数值转换成字符串。

doubleValue() 将BigDecimal对象中的值以双精度数返回。

floatValue() 将BigDecimal对象中的值以单精度数返回。

longValue() 将BigDecimal对象中的值以长整数返回。

intValue() 将BigDecimal对象中的值以整数返回。

4舍5入

BigDecimal.setScale() 方法用于格式化小数点

setScale(1) 表示保留一位小数,默认用四舍五入方式

setScale(1,BigDecimal.ROUND_DOWN) 直接删除多余的小数位,如2.35会变成2.3

setScale(1,BigDecimal.ROUND_UP) 进位处理,2.35变成2.4

setScale(1,BigDecimal.ROUND_HALF_UP) 四舍五入,2.35变成2.4

setScaler(1,BigDecimal.ROUND_HALF_DOWN) 四舍五入,2.35变成2.3,如果是5则向下舍

setScaler(1,BigDecimal.ROUND_CEILING) 接近正无穷大的舍入

setScaler(1,BigDecimal.ROUND_FLOOR) 接近负无穷大的舍入,数字>0和ROUND_UP作用一样,数字<0和ROUND_DOWN作用一样

setScaler(1,BigDecimal.ROUND_HALF_EVEN) 向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

更多

  • Long数据类型防止精度丢失,添加注解:@JsonFormat(shape = Shape.STRING)

  • BigDecimal数据类型的限制注解使用:@DecimalMin、@DecimalMax、@Digits

@ApiModelProperty(value = "报账总金额")
@DecimalMin(value = "0", inclusive = false, message = "报账总金额必须大于0")
@Digits(integer = 10, fraction = 2, message = "报账总金额 最大长度:10,允许精度:2")
private BigDecimal financeMoney;
@ApiModelProperty(value = "供应商", required = true)
@NotBlank(message = "供应商不能为空")
@Len(min = 1, max = 500)
private String provider;
@ApiModelProperty(value = "价格")
@NotNull(message = "价格不能为空")
@Min(value = 100, message = "价格不能低于100")
@Max(value = 5000, message = "价格不能超过5000")
@Size(min = 10, max = 50, message = "数量必须不低于10不超过50")
private Integer price;

@Valid和@Validated区别,参考链接

@JsonSerialize(using = ToStringSerializer.class)和@JsonSerialize注解的使用方法

如果本篇文章对你有帮助的话,很高兴能够帮助上你。

当然,如果你觉得文章有什么让你觉得不合理、或者有更简单的实现方法又或者有理解不来的地方,希望你在看到之后能够在评论里指出来,我会在看到之后尽快的回复你。