SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案

📅 发布时间:2026/7/10 12:02:57 👁️ 浏览次数:
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
SpringBoot 优雅处理金额格式化拦截器自定义注解方案一、核心思路二、实现步骤1. 创建自定义注解 AmountFormat2. 编写金额格式化拦截器3. 注册拦截器并配置拦截路径4. 在实体类字段上使用注解三、拦截器执行时机说明四、注意事项五、方案优势六、总结SpringBoot 优雅处理金额格式化拦截器自定义注解方案在金融、电商等涉及金额的项目中我们经常需要对BigDecimal类型的金额字段统一保留指定小数位数。如果在每个业务方法中手动调用setScale方法会造成大量代码冗余且难以统一维护。本文将介绍一种基于SpringBoot 拦截器 自定义注解的方案实现金额字段的自动格式化让代码更简洁、更易维护。一、核心思路定义一个自定义注解AmountFormat用于标记需要格式化的金额字段并支持指定小数位数。编写一个拦截器AmountFormatInterceptor在请求处理阶段通过反射扫描被注解标记的字段。对扫描到的BigDecimal类型字段按照注解指定的小数位数进行格式化处理。注册拦截器配置拦截路径实现全局生效。二、实现步骤1. 创建自定义注解AmountFormat该注解用于标记需要格式化的金额字段支持通过scale属性指定小数位数默认保留2位小数。importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/** * 金额格式化注解用于标记需要统一处理小数位数的字段 */Retention(RetentionPolicy.RUNTIME)// 注解在运行时生效允许反射获取Target(ElementType.FIELD)// 注解仅作用于类的字段publicinterfaceAmountFormat{/** * 保留小数位数默认2位 */intscale()default2;}2. 编写金额格式化拦截器拦截器实现HandlerInterceptor接口在preHandle方法中完成核心逻辑扫描目标类的字段对被AmountFormat标记的BigDecimal字段进行格式化。importorg.springframework.web.method.HandlerMethod;importorg.springframework.web.servlet.HandlerInterceptor;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.lang.reflect.Field;importjava.math.BigDecimal;importjava.math.RoundingMode;/** * 金额格式化拦截器自动处理被AmountFormat标记的字段 */publicclassAmountFormatInterceptorimplementsHandlerInterceptor{OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{// 只处理 Controller 中的方法HandlerMethod 类型if(handlerinstanceofHandlerMethod){HandlerMethodhandlerMethod(HandlerMethod)handler;// 获取目标类的实例ObjecttargetBeanhandlerMethod.getBean();// 获取目标类的所有字段Field[]fieldstargetBean.getClass().getDeclaredFields();for(Fieldfield:fields){// 判断字段是否被AmountFormat注解标记if(field.isAnnotationPresent(AmountFormat.class)){// 设置私有字段可访问field.setAccessible(true);// 获取字段的值ObjectfieldValuefield.get(targetBean);// 仅处理BigDecimal类型的字段if(fieldValueinstanceofBigDecimal){AmountFormatannotationfield.getAnnotation(AmountFormat.class);intscaleannotation.scale();// 格式化金额四舍五入保留指定小数位数BigDecimalformattedValue((BigDecimal)fieldValue).setScale(scale,RoundingMode.HALF_UP);// 将格式化后的值设置回字段field.set(targetBean,formattedValue);}}}}// 返回true继续执行后续拦截器和Controller方法returntrue;}}关键说明preHandle方法在 Controller 方法执行前调用保证格式化逻辑优先执行。通过反射获取字段值时需要调用field.setAccessible(true)来访问私有字段。采用RoundingMode.HALF_UP模式进行四舍五入符合日常金额计算的需求。3. 注册拦截器并配置拦截路径通过配置类WebConfig实现WebMvcConfigurer接口注册拦截器并设置拦截范围。importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;/** * Web 配置类用于注册拦截器 */ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){// 注册金额格式化拦截器registry.addInterceptor(newAmountFormatInterceptor())// 拦截所有请求.addPathPatterns(/**)// 排除不需要拦截的路径可选.excludePathPatterns(/static/**,/error);}}4. 在实体类字段上使用注解在需要格式化的BigDecimal类型金额字段上添加AmountFormat注解即可实现自动格式化。importjava.math.BigDecimal;/** * 商品实体类 */publicclassProduct{privateLongid;privateStringproductName;// 金额字段默认保留2位小数AmountFormatprivateBigDecimalprice;// 金额字段自定义保留3位小数AmountFormat(scale3)privateBigDecimaldiscountPrice;// 省略 getter/setter 方法}三、拦截器执行时机说明SpringMVC 拦截器有三个核心方法各自的执行时机不同preHandle在 Controller 方法执行前调用。本文的格式化逻辑放在此方法保证业务逻辑处理的是格式化后的金额。postHandle在 Controller 方法执行后、视图渲染前调用。适合对处理结果进行二次加工。afterCompletion在整个请求结束后调用。适合做资源清理等收尾工作。四、注意事项字段类型限制拦截器仅对BigDecimal类型的字段生效其他类型如Double不会处理。建议金额字段统一使用BigDecimal避免精度丢失。反射权限问题必须调用field.setAccessible(true)否则无法访问实体类的私有字段会抛出IllegalAccessException异常。拦截路径配置通过addPathPatterns和excludePathPatterns精准控制拦截范围避免拦截静态资源、错误页面等不需要处理的请求。四舍五入模式本文使用RoundingMode.HALF_UP如果业务需要其他舍入模式如向下取整可以在注解中新增属性配置。五、方案优势解耦性强格式化逻辑与业务逻辑完全分离无需在业务代码中重复编写setScale方法。维护成本低如果需要调整小数位数只需修改注解的scale参数无需改动大量业务代码。全局生效拦截器配置后所有标记注解的字段都会自动格式化实现统一管控。六、总结通过拦截器 自定义注解的组合我们可以优雅地解决项目中金额字段格式化的问题。这种方案不仅减少了代码冗余还提高了代码的可维护性特别适合金融、电商等对金额精度要求高的项目。在实际开发中我们还可以基于此思路扩展更多功能比如对日期字段的统一格式化、对敏感字段的脱敏处理等。