电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉換的代碼詳解

瀏覽:98日期:2023-07-28 18:44:17

由于公司是支付平臺,所以很多項目都涉及到金額,業務方轉遞過來的金額是單位是元,而我們數據庫保存的金額單位是分。一般金額的流向有以下幾個方向:

外部業務方請求我們服務,傳遞過來的金額單位是元,需要把元轉換成分。比如:下單接口。 內部系統之間的流轉,不管是向下傳遞還是向上傳遞系統間的流程都是分,不需要扭轉。比如:調用支付引擎(向下傳遞),支付引擎回調收單業務(向上傳遞)。 向業務方返回數據,這個時候需要把分轉換成元。比如:商戶調用查詢訂單接口。 內部系統的展示,這個時候需要把分轉換成元。比如:顯示收入金額的報表。

如果我們對于請求參數是金額類型的參數逐一處理,這樣重復的操作就會顯得相當的不優雅。對于請求參數我們可以使用 Spring MVC 提供的擴展擴展。對于金額操作我們可以分為:

業務方傳入金額單位為元,需要把業務方傳入的元轉換成分,可以使用 Spring MVC Restful 請求參數擴展 RequestBodyAdvice 接口。 業務方需要查詢數據,需要把數據庫保存的分轉換成元,可以使用 Spring MVC Restful 響應參數擴展 ResponseBodyAdvice 接口。

下面我們就來看一下代碼實現。

1、FenToYuan.java

定義一個標注注解,用于標注到需要把元轉換成分的 BigDecimal 類型的參數上面。

FenToYuan.java

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FenToYuan {}2、YuanToFenRequestBodyAdvice.java

實現 Spring MVC Restful 請求參數擴展類,如果請求參數標注了 @RequestBody 注解,并且請求參數的字段類型為 BigDecimal 就會把傳入的參數由元轉換成分。

YuanToFenRequestBodyAdvice.java

@Slf4j@ControllerAdvicepublic class YuanToFenRequestBodyAdvice extends RequestBodyAdviceAdapter { @Override public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return methodParameter.hasParameterAnnotation(RequestBody.class); } @Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { if(body == null) { return null; } Class<?> clazz = body.getClass(); PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(clazz); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { String name = propertyDescriptor.getName(); if('class'.equals(name)){continue; } Field field = ReflectionUtils.findField(clazz, name); Class<?> fieldClazz = field.getType(); if(!fieldClazz.equals(BigDecimal.class) ){continue; } if(!field.isAnnotationPresent(YuanToFen.class)) {continue; } Method readMethod = propertyDescriptor.getReadMethod(); Method writeMethod = propertyDescriptor.getWriteMethod(); try {BigDecimal yuanAmount = (BigDecimal) readMethod.invoke(body);BigDecimal fenAmount = AmountUtils.yuan2Fen(yuanAmount);writeMethod.invoke(body, fenAmount); } catch (Exception e) {log.error('amount convert yuan to fen fail', e); } } return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType); }}3、YuanToFen.java

標注注解,當響應參數需要由分轉換成元的時候,就標注這個注解。響應值就會把數據庫或者下游傳遞過來的金額為分的參數轉換成元。

YuanToFen.java

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface YuanToFen {}4、FenToYuanResponseBodyAdvice.java

當 Spring MVC 方法上標注了 ResponseBody 或者類上標注了 RestController 注解時,如果響應對象的 BigDecimal 標注了 @YuanToFen 注解就會進行金額分轉換成元。

FenToYuanResponseBodyAdvice.java

@Slf4j@ControllerAdvicepublic class FenToYuanResponseBodyAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter returnType, Class converterType) { return returnType.hasParameterAnnotation(ResponseBody.class)|| returnType.getDeclaringClass().isAnnotationPresent(RestController.class); } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if(body == null) { return null; } Class<?> clazz = body.getClass(); PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(clazz); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { String name = propertyDescriptor.getName(); if('class'.equals(name)){continue; } Field field = ReflectionUtils.findField(clazz, name); Class<?> fieldClazz = field.getType(); if(!fieldClazz.equals(BigDecimal.class) ){continue; } if(!field.isAnnotationPresent(FenToYuan.class)) {continue; } Method readMethod = propertyDescriptor.getReadMethod(); Method writeMethod = propertyDescriptor.getWriteMethod(); try {BigDecimal fenAmount = (BigDecimal) readMethod.invoke(body);BigDecimal yuanAmount = AmountUtils.fen2yuan(fenAmount);writeMethod.invoke(body, yuanAmount); } catch (Exception e) {log.error('amount convert fen to yuan fail', e); } } return body; }}5、AmountUtils.java

金錢工具類,提供了金錢的元轉分以及分轉元這兩個功能。

AmountUtils.java

public abstract class AmountUtils { /** * 金額單位元轉分 */ public static BigDecimal yuan2Fen(BigDecimal amount) { if (amount == null) { return BigDecimal.ZERO; } return amount.movePointRight(2).setScale(0, BigDecimal.ROUND_DOWN); } /** * 金額單位分轉元 */ public static BigDecimal fen2yuan(BigDecimal amount) { return null2Zero(amount).movePointLeft(2).setScale(2, BigDecimal.ROUND_HALF_UP); } /** * 把 null 當作 0 處理 */ public static BigDecimal null2Zero(Number amount) { if (amount == null) { return BigDecimal.ZERO; } if (amount instanceof BigDecimal) { return (BigDecimal) amount; } else { return new BigDecimal(amount.toString()); } }}6、Order.java

實體類,用于接收請求對象以及響應測試金額轉換。

Order.java

@Datapublic class Order { private String orderId; private String productName; @FenToYuan @YuanToFen private BigDecimal orderAmount;}7、OrderController.java

訂單控制類,提供了兩個方法:訂單創建(/order/apply)標注了 @RequestBody,會把傳入的金額由元轉換成分,然后打印到控制臺。訂單查詢(order/query) 聲明方法的類上標注了 @RestController ,通過關鍵字 new 創建一個訂單金額為 1000 分的訂單。

OrderController.java

@RestController@RequestMapping('order')public class OrderController { @RequestMapping('apply') public void apply(@RequestBody Order order) { System.out.println(JSON.toJSONString(order)); } @RequestMapping('query/{id}') public Order query(@PathVariable String id) { Order order = new Order(); order.setOrderId(id); order.setOrderAmount(new BigDecimal('1000')); order.setProductName('test'); return order; }}8、測試

使用工具 Postman 發送 http 進行功能測試。

8.1 元轉分測試

通過 postman 請求 http:localhost:8080/order/apply發送以下請求:

Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉換的代碼詳解

控制臺打印如下:

Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉換的代碼詳解

業務方傳入金額為 1 元,控制臺打印的結果是 100 分。

8.2 測試分轉元

通過 postman 請求 http:localhost:8080/order/query/1發送以下請求:

Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉換的代碼詳解

這個時候得到訂單金額為 10 元。查詢訂單的邏輯如下:

Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉換的代碼詳解

這個時候訂單的金額是 1000 分,轉換成 10 元完成了我們的目標功能。

當然這種方式是有一個缺陷的,就是它不能遞歸的進行金額轉換,后面可以借鑒 Hibernate 的遞歸校驗邏輯來進行遞歸金額參數的轉換。

到此這篇關于Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉換的文章就介紹到這了,更多相關Spring Boot貨幣單位轉換內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
主站蜘蛛池模板: 温州在线网| 艺术涂料_进口艺术涂料_艺术涂料加盟_艺术涂料十大品牌 -英国蒙太奇艺术涂料 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | GAST/BRIWATEC/CINCINNATI/KARL-KLEIN/ZIEHL-ABEGG风机|亚喜科技 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 水质传感器_水质监测站_雨量监测站_水文监测站-山东水境传感科技有限公司 | 光泽度计_测量显微镜_苏州压力仪_苏州扭力板手维修-苏州日升精密仪器有限公司 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | 高压直流电源_特种变压器_变压器铁芯-希恩变压器定制厂家 | 真空乳化机-灌装封尾机-首页-温州精灌 | 热风机_工业热风机生产厂家上海冠顶公司提供专业热风机图片价格实惠 | 熔体泵|换网器|熔体齿轮泵|熔体计量泵厂家-郑州巴特熔体泵有限公司 | 冲锋衣滑雪服厂家-冲锋衣定制工厂-滑雪服加工厂-广东睿牛户外(S-GERT) | 煤矿支护网片_矿用勾花菱形网_缝管式_管缝式锚杆-邯郸市永年区志涛工矿配件有限公司 | 流程管理|流程管理软件|企业流程管理|微宏科技-AlphaFlow_流程管理系统软件服务商 | 美国查特CHART MVE液氮罐_查特杜瓦瓶_制造全球品质液氮罐 | 塑料瓶罐_食品塑料瓶_保健品塑料瓶_调味品塑料瓶–东莞市富慷塑料制品有限公司 | 折弯机-刨槽机-数控折弯机-数控刨槽机-数控折弯机厂家-深圳豐科机械有限公司 | 彭世修脚_修脚加盟_彭世修脚加盟_彭世足疗加盟_足疗加盟连锁_彭世修脚技术培训_彭世足疗 | 电主轴-高速精密电主轴-高速电机厂家-瑞德沃斯品牌有限公司 | 洗石机-移动滚筒式,振动,螺旋,洗矿机-青州冠诚重工机械有限公司 | 山东齐鲁漆业有限公司【官网】-工业漆专业生产厂家 | 恒温振荡混匀器-微孔板振荡器厂家-多管涡旋混匀器厂家-合肥艾本森(www.17world.net) | 珠宝展柜-玻璃精品展柜-首饰珠宝展示柜定制-鸿钛展柜厂家 | 千斤顶,液压千斤顶-力良企业,专业的液压千斤顶制造商,shliliang.com | 接地电阻测试仪[厂家直销]_电缆故障测试仪[精准定位]_耐压测试仪-武汉南电至诚电力设备 | 双相钢_双相不锈钢_双相钢圆钢棒_双相不锈钢报价「海新双相钢」 双能x射线骨密度检测仪_dxa骨密度仪_双能x线骨密度仪_品牌厂家【品源医疗】 | 脉冲除尘器,除尘器厂家-淄博机械| 预制舱-电力集装箱预制舱-模块化预制舱生产厂家-腾达电器设备 | 黑龙江京科脑康医院-哈尔滨精神病医院哪家好_哈尔滨精神科医院排名_黑龙江精神心理病专科医院 | 搜木网 - 木业全产业链交易平台,免费搜货、低价买货! | 面粉仓_储酒罐_不锈钢储酒罐厂家-泰安鑫佳机械制造有限公司 | 手持式浮游菌采样器-全排二级生物安全柜-浙江孚夏医疗科技有限公司 | 踏板力计,制动仪,非接触多功能速度仪,逆反射系数测试仪-创宇 | 太空舱_民宿太空舱厂家_移动房屋太空舱价格-豪品建筑 | 无轨电动平车_轨道平车_蓄电池电动平车★尽在新乡百特智能转运设备有限公司 | 飞扬动力官网-广告公司管理软件,广告公司管理系统,喷绘写真条幅制作管理软件,广告公司ERP系统 | 天然气分析仪-液化气二甲醚分析仪|传昊仪器| 对辊式破碎机-对辊制砂机-双辊-双齿辊破碎机-巩义市裕顺机械制造有限公司 | 变位机,焊接变位机,焊接变位器,小型变位机,小型焊接变位机-济南上弘机电设备有限公司 | 塑料检查井_双扣聚氯乙烯增强管_双壁波纹管-河南中盈塑料制品有限公司 |