1、开发文档

微信开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

安全规范:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

  1. 1、签名算法
  2. (签名校验工具)
  3. 签名生成的通用步骤如下:
  4. 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA
  5. 特别注意以下重要规则:
  6. 参数名ASCII码从小到大排序(字典序);
  7. 如果参数的值为空不参与签名;
  8. 参数名区分大小写;
  9. 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
  10. 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
  11. 第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到signsignValue 注意:密钥的长度为32个字节。

2、配置信息 和 工具类

2.1 核心配置文件

application.yml

  1. #端口
  2. server:
  3. port: 8096
  4. #微信支付自定义配置参数
  5. wechat:
  6. pay:
  7. app-id: xxxx # 公众账号ID
  8. mch-id: xxxx # 商户号ID
  9. mch-key: xxxxx # 商户密钥
  10. order-uri: https://api.mch.weixin.qq.com/pay/unifiedorder # 请求微信支付接口统一下单地址
  11. notify-uri: http://xxxxx.natappfree.cc/wxpay/notifyresult # 微信支付结果回调地址
  12. view-order-status-uri: https://api.mch.weixin.qq.com/pay/orderquery # 查询订单状态地址

注意:其中的回调地址,需要内网穿透;

2.2 自定义配置类

  1. /**
  2. * Created On : 3/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 自定义配置类
  7. */
  8. @Data
  9. @Component
  10. @ConfigurationProperties(prefix = "wechat.pay")
  11. public class WechatPayConfig {
  12. /*
  13. 公众账号ID
  14. */
  15. private String appId;
  16. /*
  17. 商户号ID
  18. */
  19. private String mchId;
  20. /*
  21. 商户密钥
  22. */
  23. private String mchKey;
  24. /*
  25. 请求微信支付接口统一下单地址
  26. */
  27. private String orderUri;
  28. /*
  29. 微信支付结果回调地址
  30. */
  31. private String notifyUri;
  32. /*
  33. 主动查询订单状态地址
  34. */
  35. private String viewOrderStatusUri;
  36. }

2.3 常量类

  1. /**
  2. * Created On : 3/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 微信支付常量类
  7. */
  8. public class WechatPayConstant {
  9. //系统交易订单号的浅醉标识符
  10. public static final String WECHAT_PAY_TRADE_ORDER_PREFIX ="kh";
  11. //系统格式化日期字符串,到秒
  12. public static final String WECHAT_PAY_TIME_PATTERN_ALL = "yyyyMMddHHmmss";
  13. //系统格式化日期字符串,到天
  14. public static final String WECHAT_PAY_TIME_PATTERN_DAY = "yyyyMMdd";
  15. //微信支付的交易类型:naive
  16. public static final String WECHAT_PAY_TRADE_NATIVE = "NATIVE";
  17. //微信支付的签名方式MD5
  18. public static final String WECHAT_PAY_SIGN_TYPE_MD5= "MD5";
  19. //微信支付的签名参数名
  20. public static final String WECHAT_PAY_FIELD_SIGN = "sign";
  21. //微信支付下单请求的字符集编码
  22. public static final String WECHAT_PAY_ENCODING_UTF8="UTF-8";
  23. //微信支付下单结果的成功状态码
  24. public static final String WECHAT_PAY_RESULT_SUCCESS = "SUCCESS";
  25. //微信支付结果异步回调的同步响应,成功
  26. public static final String WECHAT_PAY_NOTIFY_SUCCESS="<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  27. //微信支付结果异步回调的同步响应,失败
  28. public static final String WECHAT_PAY_NOTIFY_FALL="<xml><return_code><![CDATA[FALL]]></return_code><return_msg><![CDATA[NOOK]]></return_msg></xml>";
  29. //订单查询 结果成功的状态码
  30. public static final String WECHAT_PAY_VIEW_ORDER_STATUS_SUCCESS = "SUCCESS";
  31. }

2.4 工具类

WechatPayUtil 和 WechatPayXmlUtil :https://www.cnblogs.com/xiaoqigui/p/16855921.html

HttpClient4Util http请求工具类:https://www.cnblogs.com/xiaoqigui/p/16839536.html

3、请求微信统一下单接口,下单支付订单,返回支付链接

  1. 获取参数,放进map集合中并按key值,字典排序。
  2. 通过参数生成签名(生成的签名也放进map集合)。
  3. 将map集合转成xml字符串。
  4. 获取微信支付统一下单地址,xml参数字符串作为参数发送请求。
  5. 返回支付的链接(可以生成二维码给用户扫码支付)。

3.0 参数列表

3.1 接口

  1. /**
  2. * Created On : 3/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 微信支付业务接口
  7. */
  8. public interface WechatPayService {
  9. /**
  10. * @author : huayu
  11. * @date : 3/11/2022
  12. * @param : []
  13. * @return : java.lang.String
  14. * @description : 生成请求微信支付接口的统一下单接口参数 ,返回xml格式字符串
  15. */
  16. String generateWxUnifyOrderXmlParams(String productBody,int totalFee) throws Exception;
  17. /**
  18. * @author : huayu
  19. * @date : 3/11/2022
  20. * @param : [unifyOrderXmlParams]
  21. * @return : java.util.Map<java.lang.String,java.lang.String>
  22. * @description : 请求微信支付统一下单
  23. */
  24. Map<String,String> getWchatPayUnifyOrderResult(String unifyOrderXmlParams) throws Exception;
  25. }

3.2 实现类

  1. /**
  2. * Created On : 3/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 微信支付业务接口实现类
  7. */
  8. @Service
  9. @Slf4j
  10. public class WechatPayServiceImpl implements WechatPayService {
  11. @Autowired
  12. private WechatPayConfig wechatPayConfig;
  13. @Override
  14. public String generateWxUnifyOrderXmlParams(String productBody,int totalFee) throws Exception {
  15. //微信支付接口签名参数要求
  16. //特别注意一下要求规则:参数名ASCII码从小到大排序(字典排序);如果参数值为空不参与签名;参数区分大小写;
  17. //定义微信支付解析参数集合:TreeMap(自动横距集合中key按照字典排序)
  18. TreeMap<String, String> paramsMap = new TreeMap<>();
  19. //公众账号ID appid 必传参数 微信支付分配的公众账号ID(企业号corpid即为此appid)
  20. paramsMap.put("appid",wechatPayConfig.getAppId());
  21. //商户号 mch_id 微信支付分配的商户号
  22. paramsMap.put("mch_id",wechatPayConfig.getMchId());
  23. //设备号 device_info 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
  24. paramsMap.put("device_info","WEB");
  25. //随机字符串 nonce_str 随机字符串,长度要求在32位以内。推荐随机数生成算法
  26. paramsMap.put("nonce_str",WechatPayUtil.generateNonceStr());
  27. //商品描述 body 商品简单描述,该字段请按照规范传递,具体请见参数规定
  28. paramsMap.put("body",productBody);
  29. //附件数据 attach
  30. paramsMap.put("attach","课工场KH96");
  31. //商户订单号 out_trade_no 商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号
  32. paramsMap.put("out_trade_no",WechatPayUtil.generateTradeOrderNo());
  33. //标价金额 total_fee 订单总金额,单位为分,详见支付金额
  34. paramsMap.put("total_fee",String.valueOf(totalFee));
  35. //终端IP spbill_create_ip 支持IPV4和IPV6两种格式的IP地址。用户的客户端IP
  36. paramsMap.put("spbill_create_ip","121.225.201.22");
  37. //通知地址 notify_url body 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 公网域名必须为https,如果是走专线接入,使用专线NAT IP或者私有回调域名可使用http
  38. paramsMap.put("notify_url",wechatPayConfig.getNotifyUri());
  39. //交易类型 trade_type NATIVE -Native 支付 JSAPI -JSAPI支付 NATIVE -Native支付 APP -APP支付
  40. paramsMap.put("trade_type", WechatPayConstant.WECHAT_PAY_TRADE_NATIVE);
  41. //商品ID trade_type=NATIVE时,此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
  42. paramsMap.put("product_id","互联网架构师");
  43. //签名,传送的sign参数不参与签名,会将生成的签名与该sign值作校验。如果不一致,签名失败
  44. //切记:签名都是再确定好接口参数后,指定签名操作,并将签名的结果加入参数集合
  45. paramsMap.put("sign",WechatPayUtil.generateSignature(paramsMap,wechatPayConfig.getMchKey()));
  46. return WechatPayUtil.generateMapToXml(paramsMap);
  47. }
  48. @Override
  49. public Map<String, String> getWchatPayUnifyOrderResult(String unifyOrderXmlParams) throws Exception {
  50. //发送post请求,请求微信支付统一下单接口,下预支付订单,并获取下单结果
  51. String unifyOrderXmlResult = HttpClient4Util.getResponse4PostByString(wechatPayConfig.getOrderUri()
  52. , unifyOrderXmlParams
  53. , WechatPayConstant.WECHAT_PAY_ENCODING_UTF8);
  54. return WechatPayUtil.generateXmlToMap(unifyOrderXmlResult);
  55. }
  56. }

3.3 请求方法

  1. /**
  2. * Created On : 3/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 微信支付接口对接测试入口
  7. */
  8. @Slf4j
  9. @RestController
  10. public class WechatPagController {
  11. @Autowired
  12. private WechatPayService wechatPayService;
  13. /**
  14. * @author : huayu
  15. * @date : 3/11/2022
  16. * @param : []
  17. * @return : com.kgc.scd.uitl.RequestResult<java.util.Map<java.lang.String,java.lang.String>>
  18. * @description : 请求微信统一下单接口,下单支付订单,返回支付链接
  19. */
  20. @PostMapping("/wxpay/unifyOrder")
  21. public RequestResult<Map<String,String>> wechatPagUnifyOrder(@RequestParam String productBody,
  22. @RequestParam int totalFree) throws Exception {
  23. //调用业务接口,生成微信支付接口,统一下单的完整参数,xml格式(微信支付的接口要求,交互参数必须是xml)
  24. String unifyOrderXmlParams = wechatPayService.generateWxUnifyOrderXmlParams(productBody, totalFree);
  25. log.info("------ 1.请求微信支付统一下单参数:{} -------",unifyOrderXmlParams);
  26. //调用业务接口,请求微信支付统一下单接口,获取下单结果
  27. Map<String, String> unifyOrderMapResult = wechatPayService.getWchatPayUnifyOrderResult(unifyOrderXmlParams);
  28. log.info("------ 2.请求微信支付统一下订单接口返回:{} --------",unifyOrderMapResult);
  29. //定义当前接口返回的map集合
  30. Map<String, String> resultMap = new HashMap<>();
  31. //解析微信支付下单结果,如果下单成功,获取用户进行扫码支付的连接,返回给前端,生成二维码,
  32. if(WechatPayConstant.WECHAT_PAY_RESULT_SUCCESS.equals(unifyOrderMapResult.get("return_code"))
  33. && WechatPayConstant.WECHAT_PAY_RESULT_SUCCESS.equals(unifyOrderMapResult.get("result_code"))){
  34. // 微信支付统一下单成功,省略签名校验
  35. // 获取成功的结果
  36. // 交易类型
  37. resultMap.put("trade_type", unifyOrderMapResult.get("trade_type"));
  38. // 预支付交易会话标识
  39. resultMap.put("prepay_id", unifyOrderMapResult.get("prepay_id"));
  40. // 二维码链接
  41. resultMap.put("code_url", unifyOrderMapResult.get("code_url"));
  42. // 返回统一下预支付单成功
  43. return ResultBuildUtil.success(resultMap);
  44. }
  45. // 统一下预支付单失败
  46. return ResultBuildUtil.fail(unifyOrderMapResult.get("return_code"), unifyOrderMapResult.get("return_msg"));
  47. }
  48. }

3.4 请求测试

3.4.1 发送请求

3.4.2 生成二维码

4、接收用户支付成功后,微信异步回调支付结果

  1. 支付后,微信官方,通过回调地址,返回用户信息通过数据流。
  2. 解析回调数据流。
  3. 解析异步回调的支付结果。
  4. 同步给微信官方响应结果。

4.1接口

  1. /**
  2. * @author : huayu
  3. * @date : 3/11/2022
  4. * @param : [wxpayNotifyXmlResult]
  5. * @return : java.lang.String
  6. * @description : 调用业务接口,解析异步回调的支付结果,并获取通知微信官方的结果
  7. */
  8. String getNotifyWechatXmlResult(String wxpayNotifyXmlResult) throws Exception;

4.2 实现类

  1. @Override
  2. public String getNotifyWechatXmlResult(String wxpayNotifyXmlResult) throws Exception {
  3. //将微信支付结果通知的xml格式字符串,转换位map集合,方便处理
  4. Map<String, String> wxpayNotifyXmlForMapResult = WechatPayUtil.generateXmlToMap(wxpayNotifyXmlResult);
  5. //解析回调结果
  6. if(WechatPayConstant.WECHAT_PAY_RESULT_SUCCESS.equals(wxpayNotifyXmlForMapResult.get("return_code"))){
  7. //官方提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄露导致出现“假通知”,造成资金损失。
  8. if(WechatPayUtil.isSignatureValid(wxpayNotifyXmlForMapResult,wechatPayConfig.getMchKey())){
  9. // 签名校验成功,说明回调结果是可信的,就可以进行业务处理,如果签名失败,说明回调来源不可信,不能进行业务处理
  10. // TODO 真实业务中,收到正确回调,就要进行对应的业务处理,比如修改订单状态,发送主题消息,给定用户加积分,给物流生成物流单等等
  11. // 业务处理成功后,需要同步给微信响应结果-成功
  12. //成功
  13. return WechatPayConstant.WECHAT_PAY_NOTIFY_SUCCESS;
  14. }
  15. }
  16. // 同步给微信响应结果-失败
  17. return WechatPayConstant.WECHAT_PAY_NOTIFY_FALL;
  18. }

4.3 请求方法

  1. /**
  2. * @author : huayu
  3. * @date : 3/11/2022
  4. * @param : [request, response]
  5. * @return : void
  6. * @description : 接收用户支付成功后,微信异步回调支付结果
  7. */
  8. @RequestMapping("/wxpay/notifyresult")
  9. public void receiveWechatPayNotifyResult(HttpServletRequest request, HttpServletResponse response){
  10. //支付完成后,微信会把相关支付结果及用户信息通过数据流的形式发送给商户,商户需要接收处理,并按文档规范返回应答。
  11. try(InputStream inputStream = request.getInputStream()){
  12. //解析回调数据流
  13. BufferedReader brf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
  14. //定义可变字符对象,保存返回的xml格式支付结果
  15. StringBuilder wxpayNotifyXmlResult = new StringBuilder();
  16. //逐行解析
  17. String readline = null;
  18. while ((readline = brf.readLine()) != null){
  19. wxpayNotifyXmlResult.append(readline);
  20. }
  21. log.info("------ 3.微信支付结果异步回调内容:{} ------",wxpayNotifyXmlResult);
  22. //调用业务接口,解析异步回调的支付结果,并获取通知微信官方的结果
  23. String respWechatXmlResult = wechatPayService.getNotifyWechatXmlResult(wxpayNotifyXmlResult.toString());
  24. //同步给微信官方响应结果
  25. PrintWriter out = response.getWriter();
  26. out.write(respWechatXmlResult);
  27. out.flush();
  28. out.close();
  29. log.info("------ 4、微信支付异步回调处理后,响应结果:{} ------",respWechatXmlResult);
  30. }catch (Exception e){
  31. log.info("------ 微信支付结果异步回调处理异常,异常信息:{} ------", e.getMessage());
  32. }
  33. }

4.4 请求测试(微信官方回调)

5、查看用户订单状态

  1. 获取参数,放进map集合中并按key值,字典排序。
  2. 通过参数生成签名(生成的签名也放进map集合)。
  3. 将map集合转成xml字符串。
  4. 获取订单状态查询地址,xml参数字符串作为参数发送请求。
  5. 返回订单状态信息。

5.0 参数列表

5.1 接口

  1. /**
  2. * @author : huayu
  3. * @date : 3/11/2022
  4. * @param : [orderNo]
  5. * @return : java.lang.String
  6. * @description : 通过订单好查询订单状态
  7. */
  8. Map<String, String> getOrderStatus(String orderNo) throws Exception;

5.2 实现类

  1. @Override
  2. public Map<String, String> getOrderStatus(String orderNo) throws Exception {
  3. log.info("++++++ 获取查询订单状态的参数 ++++++");
  4. //参数集合
  5. TreeMap<String, String> paramsMap = new TreeMap<>();
  6. //公众账号ID appid
  7. paramsMap.put("appid",wechatPayConfig.getAppId());
  8. //商户号 mch_id
  9. paramsMap.put("mch_id",wechatPayConfig.getMchId());
  10. //商户订单号 out_trade_no
  11. paramsMap.put("out_trade_no",orderNo);
  12. //随机字符串 nonce_str
  13. paramsMap.put("nonce_str",WechatPayUtil.generateNonceStr());
  14. //签名 sign
  15. paramsMap.put("sign",WechatPayUtil.generateSignature(paramsMap,wechatPayConfig.getMchKey()));
  16. //将map集合的参数转换成xml格式的字符串
  17. String paramsMapToXml = WechatPayUtil.generateMapToXml(paramsMap);
  18. log.info("++++++ 查询订单状态的参数:{} ++++++",paramsMapToXml);
  19. //发送post请求,获取订单状态 xml格式字符串
  20. String orderStatusXmlResult = HttpClient4Util.getResponse4PostByString(wechatPayConfig.getViewOrderStatusUri()
  21. , paramsMapToXml
  22. , WechatPayConstant.WECHAT_PAY_ENCODING_UTF8);
  23. log.info("++++++发送post请求,获取订单状态 xml格式字符串 orderStatusXmlResult: ++++++\n{}",orderStatusXmlResult);
  24. //将xml格式结果字符串转化成 map 集合
  25. Map<String, String> orderStatusXmlResultToMap = WechatPayUtil.generateXmlToMap(orderStatusXmlResult);
  26. //判断返回结果
  27. //交易成功判断条件: return_code、result_code和trade_state都为SUCCESS
  28. if(WechatPayConstant.WECHAT_PAY_VIEW_ORDER_STATUS_SUCCESS.equals(orderStatusXmlResultToMap.get("return_code"))
  29. && WechatPayConstant.WECHAT_PAY_VIEW_ORDER_STATUS_SUCCESS.equals(orderStatusXmlResultToMap.get("result_code"))
  30. && WechatPayConstant.WECHAT_PAY_VIEW_ORDER_STATUS_SUCCESS.equals(orderStatusXmlResultToMap.get("trade_state"))
  31. ){
  32. //返回订单信息
  33. return orderStatusXmlResultToMap;
  34. }
  35. return null;
  36. }

5.3 请求方法

  1. /**
  2. * @author : huayu
  3. * @date : 3/11/2022
  4. * @param : [orderNo]
  5. * @return : void
  6. * @description : 查看用户订单状态
  7. */
  8. @RequestMapping("/wxpay/viewOrderStatus")
  9. public RequestResult<String> viewOrderStatus(@RequestParam String orderNo) throws Exception {
  10. //调用业务层 查询订单状态
  11. String orderStatus = wechatPayService.getOrderStatus(orderNo);
  12. if(orderStatusInfoMap != null){
  13. return ResultBuildUtil.success(orderStatusInfoMap);
  14. }
  15. return ResultBuildUtil.fail(null);
  16. }

5.4 请求测试

5.4.1 发起请求

5.4.2 请求结果

SpringCloud(七) - 微信支付的更多相关文章

  1. 在Web应用中接入微信支付的流程之极简清晰版

    在Web应用中接入微信支付的流程之极简清晰版 背景: 在Web应用中接入微信支付,我以为只是调用几个API稍作调试即可. 没想到微信的API和官方文档里隐坑无数,致我抱着怀疑人生的心情悲愤踩遍了丫们布 ...

  2. 在Web应用中接入微信支付的流程之极简清晰版 (转)

    在Web应用中接入微信支付的流程之极简清晰版 背景: 在Web应用中接入微信支付,我以为只是调用几个API稍作调试即可. 没想到微信的API和官方文档里隐坑无数,致我抱着怀疑人生的心情悲愤踩遍了丫们布 ...

  3. Android开发 --微信支付开发(转载!)(开发工具:Eclipse)

    Android_APP 微信支付接口开发 日期:2015-10-06 12:47:33 作者: 来源: 人气:3549 1.首先说一下我们在开发微信支付接口的时候遇到最多和最疑惑的问题,那就是明明 a ...

  4. 浅析微信支付:公众平台卡券功能开通、HTML5线上发券(JS-SDK接口)、查看卡券详情

    本文是[浅析微信支付]系列文章的第十六篇,主要讲解如何使用微信公众平台的卡券功能.如何使用HTML5在网页展示用户领券以及微信卡券和商户平台代金券的关系. 浅析微信支付系列已经更新十六篇了哟-,没有看 ...

  5. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  6. 微信支付开发出现redirect_uri参数错误的解决方法

    我们在进行微信支付开发的时候会遇到出现“redirect_uri参数错误”这种情况,怎么办呢?下面就是我总结出现这种“redirect_uri参数错误”的七种可能情况,以及解决方式. 1.可能原因①: ...

  7. Java 微信支付分对接记录 (先享后付)

    微信支付分(先享后付)对接记录: 微信支付分对接步骤 填写开通支付分的申请表格 此步骤大概需要审核 1-3 个工作日; (模板-服务信息配置表-[先享后付免确认]-[商户名].xls) 填写商户信息 ...

  8. 【zhifu】web开发中的支付宝支付和微信支付

    一.支付类型: 支付宝支付: 支付宝app内的网页支付: app外(即普通浏览器)网页支付: 微信支付: 微信app内的支付(在这里叫公众号支付) app外的支付(微信H5支付): 微信公众号的支付宝 ...

  9. 微信支付万亿日志在Hermes中的实践

    导语 | 微信支付日志系统利用 Hermes 来实现日志的全文检索功能,自从接入以来,日志量持续增长.目前单日入库日志量已经突破万亿级,单集群日入库规模也已经突破了万亿,存储规模达 PB 级.本文将介 ...

随机推荐

  1. DL基础:cs231n assignment 2

    cs231n assignment 2 20210913 - 20211005. 目录 cs231n assignment 2 fully-connected nets 基本思想 编程细节 复习mul ...

  2. 认识Chrome扩展插件

    1.前言 现如今的时代,绝大多数人都要跟浏览器打交道的,说到浏览器那肯定是Chrome浏览器一家独大,具体数据请看 知名流量监测机构 Statcounter 公布了 7 月份全球桌面浏览器市场份额,主 ...

  3. P7727 风暴之眼 Eye of the Storm (树形 DP)

    谨 以 此 文 表 达 笔 者 个 人 观 点 , 如 有 冒 犯 官 解 , 可 在 评 论 区 诉 说 _{^{_{谨以此文表达笔者个人观点,如有冒犯官解,可在评论区诉说}}} 谨以此文表达笔者个 ...

  4. RestTemplate用法

    RestTemplate 用法 RestTemplate简介 RestTemplate 是一个同步的web http客户端请求模板工具,spring框架做的抽象模板, 常见的http客户端请求工具有: ...

  5. UIView Animation 动画学习总结

    目录 一.前言 二.UIView Animation 2.1 简单动画 2.2 关键帧动画 2.3 View 的转换 三.CALayer Animation 3.1 基本动画(CABasicAnima ...

  6. 第八十九篇:Vue 重学插槽slot

    好家伙, 1.什么是插槽? 插槽是vue为组件的封装者提供的能力.允许开发者在封装组件时, 把不确定的,希望由用户指定的部分定义为插槽   我们依然可以把它理解为一个占位符 1.1.插槽的基本用法 试 ...

  7. SpringMVC--从理解SpringMVC执行流程到SSM框架整合

    前言 SpringMVC框架是SSM框架中继Spring另一个重要的框架,那么什么是SpringMVC,如何用SpringMVC来整合SSM框架呢?下面让我们详细的了解一下. 注:在学习SpringM ...

  8. 01-MyBatisPlus简介

    一.简介 官网:http://mp.baomidou.com/ 参考教程:https://baomidou.com/pages/24112f/ MyBatis-Plus(简称 MP)是一个 MyBat ...

  9. 一文读懂,硬核 Apache DolphinScheduler3.0 源码解析

    ​ 点亮 ️ Star · 照亮开源之路 https://github.com/apache/dolphinscheduler 本文目录 1 DolphinScheduler的设计与策略 1.1 分布 ...

  10. 发布日志- kratos v2.1.4 发布!

    v2.1.4 release https://github.com/go-kratos/kratos/releases/tag/v2.1.4 New Features feat(registry/co ...