亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

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

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

瀏覽:63日期: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
相關文章:
主站蜘蛛池模板: 欧美精品日本一级特黄 | 久久99精品久久久久久首页 | 久草福利免费 | 国产精品爱啪在线线免费观看 | 欧美黄色大片免费看 | 国产精品视频久久久 | 欧美嘿咻 | 亚洲欧美精品伊人久久 | 日韩国产欧美在线观看 | 色欲综合视频天天天 | 久久精品国产99国产精品澳门 | 激情综合网五月激情 | 国产一区三区二区中文在线 | 精品中文字幕不卡在线视频 | 国产在线观看91精品2021 | 欧美成人v视频免费看 | 真人毛片免费全部播放完整 | 亚洲成人日韩 | 亚洲精品免费在线观看 | a免费国产一级特黄aa大 | 妞干网手机免费视频 | 国产无套在线播放 | 多男一女一级淫片免费播放口 | 天堂福利视频在线观看 | 国内在线观看精品免费视频 | 黄片毛片在线看 | 国产午夜精品不卡视频 | 中文在线免费不卡视频 | 我要看一级黄色录像 | 国产成人久久精品二区三区牛 | 国产精品久久久久久福利 | 国产成人激烈叫床声视频对白 | 色偷偷尼玛图亚洲综合 | 麻豆传媒入口直接进入免费 | 欧美日韩国产在线成人网 | 九一精品 | 久久国产主播 | 亚洲天天综合色制服丝袜在线 | 欧美精品在线免费观看 | 成人国产三级在线播放 | 亚洲精品久一区 |