国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

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

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

瀏覽:75日期: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久久免费看国产精品 | 日本在线视频播放 | 久久亚洲不卡一区二区 | 欧美国产亚洲一区 | 在线播放免费一级毛片欧美 | 国产免费一区二区三区在线 | 久久久精品国产免费观看同学 | 精品三级内地国产在线观看 | 亚洲图片一区二区 | 国产精品极品 | 日韩国产欧美精品综合二区 | 91最新网站免费 | 成人精品一区二区三区中文字幕 | 99精品视频一区在线观看miya | 日韩国产欧美成人一区二区影院 | 日韩黄色一级毛片 | 成年人在线免费网站 | 欧美一区二区三区四区在线观看 | 一级特黄特黄毛片欧美的 | 日韩精品永久免费播放平台 | 国产成人18黄网站免费网站 | 亚洲无吗| 久久99亚洲精品久久99 | 亚洲一区在线播放 | 欧美三级中文字幕 | 99久久精品久久久久久清纯 | 在线免费观看成年人视频 | 成年大片免费视频播放二级 | 成人黄色毛片 | 天天摸天天爽视频69视频 |