目录

前言

准备

Websocket服务器

实现

页面

演示


前言

最近在做公司项目时使用websocket在支付回调接口中刷新页面状态时,忽然想起今年毕业做毕业设计的时候,做的是一个电商系统,那么支付是必不可少的,当时还没有听说过websocket,去网上查阅资料,申请支付宝或者微信授权肯定是不现实的,还搞了很久的沙箱支付,现在想想真是傻,没有早一点接触到websocket,至于websocket是一门怎样的技术我们在此不做过多介绍,大家可自行查阅资料,我们这里只是简单写一个demo来做模拟支付,没什么太大的技术含量,但对于在校的想实现一个模拟支付的你确是雪中送炭!

准备

首先新建一个简单的springboot项目,当然了,普通的web项目也是可以的,这里敏捷开发

引入jar包,不是用maven的就只能下载jar进行导入了

        <!-- websocket包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId></dependency><!-- 二维码相关包 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.3.3</version></dependency>

下面两个jar包是二维码相关的jar包,二维码的工具类此文就不再贴出了,在 【二维码】——生成二维码并转为base64中有代码贴出。

Websocket服务器

WebSocketConfig:开启websocket配置

/*** 开启WebSocket支持* @author zhengkai*/
@Configuration
public class WebSocketConfig {@Bean  public ServerEndpointExporter serverEndpointExporter() {  return new ServerEndpointExporter();  }  }

WebsocketServer:webSocket服务器

/** webSocket服务器* @author WangZhiJun*/
@ServerEndpoint("/ws/{sid}")
@Component
public class WebSocketServer {private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);/*** 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/private static int onlineCount = 0;/*** concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();/** 与某个客户端的连接会话,需要通过它来给客户端发送数据*/private Session session;/*** 接收sid*/private String sid="";/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session,@PathParam("sid") String sid) {this.session = session;//加入set中webSocketSet.add(this);//在线数加1addOnlineCount();logger.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());this.sid=sid;try {sendMessage("连接成功");} catch (IOException e) {logger.error("websocket IO异常");}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {//从set中删除webSocketSet.remove(this);//在线数减1subOnlineCount();logger.info("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {logger.info("收到来自窗口"+sid+"的信息:"+message);//群发消息for (WebSocketServer item : webSocketSet) {try {item.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}/*** * @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {logger.error("发生错误");error.printStackTrace();}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 群发自定义消息* */public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException {logger.info("推送消息到窗口"+sid+",推送内容:"+message);for (WebSocketServer item : webSocketSet) {try {//这里可以设定只推送给这个sid的,为null则全部推送if(sid==null) {item.sendMessage(message);}else if(item.sid.equals(sid)){item.sendMessage(message);}} catch (IOException e) {continue;}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}
}

实现

OrderController:项目中生成二维码的接口,将订单的信息存储在二维码中,二维码生成请查看【二维码】——生成二维码并转为base64

/*** @author: WangZhiJun* @create: 2019-09-21 12:31**/
@RestController
@RequestMapping("/api/v1/order")
public class OrderController {/*** 系统内生成支付二维码接口*/@GetMapping(value = "/payOrder")public Result pay(@RequestParam String orderId) {Result result = new Result();String orderName = "XXSuperMarketPay";BigDecimal orderMoney = new BigDecimal(100);System.out.println("订单"+orderId+orderName+"需支付:"+orderMoney+"元");String wxPayUrl = "http://192.168.1.101:8080/wx/pay/pay?orderId="+orderId+"&orderName="+orderName+"&orderMoney="+orderMoney;System.out.println("生成支付二维码链接:"+wxPayUrl);result.setData(BarCodeUtils.getImage2Base64String(BarCodeUtils.generateBarcodeWithoutWhite(wxPayUrl, Color.BLACK)));return result;}/*** 结果实体类,这里为简化开发写为内部类,且只有一个data属性*/class Result {String data;public void setData(String data) {this.data = data;}public String getData() {return data;}}
}

WxPayController:这里模仿微信支付API接口,方便使用也放在此项目中

/** 假设这是微信支付的接口* @author: WangZhiJun* @create: 2019-09-21 12:31**/
@RestController
@RequestMapping("/wx/pay")
public class WxPayController {/*** 模仿微信支付API*/@GetMapping(value = "/pay")public void paySuccess(@RequestParam String orderId,@RequestParam String orderMoney,@RequestParam String orderName) {System.out.println("订单"+orderId+orderName+"支付:"+orderMoney+"元");System.out.println("支付成功");//通知页面支付成功,实际是微信调用系统回调接口,在系统回调接口中进行通知try {WebSocketServer.sendInfo("支付成功",orderId);} catch (IOException e) {e.printStackTrace();}}
}

页面

pay.html:简单开发并未做过多的样式

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>微信支付</title>
</head>
<script type="text/javascript" src="jquery.min.js"></script>
<script>let orderId = getParameter("orderId");getUrl(orderId);let socket;if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else{console.log("您的浏览器支持WebSocket");//实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接${12123}socket = new WebSocket("ws://192.168.1.101:8080/ws/"+orderId);//打开事件socket.onopen = function() {console.log("Socket 已打开");//socket.send("这是来自客户端的消息" + location.href + new Date());};//获得消息事件socket.onmessage = function(msg) {console.log("接收到消息:"+msg.data)if (msg.data === '支付成功') {$("#div").html(msg.data);}//发现消息进入    开始处理前端触发逻辑};//关闭事件socket.onclose = function() {console.log("Socket已关闭");};//发生了错误事件socket.onerror = function() {alert("Socket发生了错误");//此时可以尝试刷新页面};}function getUrl(url) {$.ajax({url: `/api/v1/order/payOrder?orderId=`+url,type: "get",dataType: "json",success: function (result) {const img = document.getElementById("img");img.setAttribute("src","data:image/png;base64,"+result.data);},error: function (result) {alert(result);}});}function getParameter(param) {const query = window.location.search;const iLen = param.length;let iStart = query.indexOf(param);if (iStart === -1) {return "";}iStart += iLen + 1;let iEnd = query.indexOf("&", iStart);if (iEnd === -1) {return query.substring(iStart);}return query.substring(iStart, iEnd);}
</script>
<body><div id="div"><img style="width:200px;height: 200px;" id="img" src=""/></div>
</body>
</html>

其中的jquery.min.js可自行百度下载,资源很多

演示

1.首先访问页面,生成二维码并连接上socket

这个二维码看起来是比较复杂的,因为里面存储的链接比较长,如果对长链接转短链接感兴趣的可以看:【短链接】——自己实现一个短网址服务

2.用手机扫描二维码,这里要保证手机和电脑在同一个局域网内

注意:OrderController中的IP和pay.html中的IP要保持一致,且是电脑当前所在局域网的IP,电脑和手机连接同一WiFi或者手机给电脑开热点

最后放一下项目结构图:

实现效果可以去我的个人主页进行测试:模拟支付

大功告成!

【支付】——毕业设计中利用websocket做模拟支付相关推荐

  1. java怎么解决重复支付问题_支付系统设计中,如何防止重复支付?

    wallet-2292428_1280.jpg 在我们支付系统设计中,经常会遇到这样一个问题,防止用户重复支付.用户明明只想购买一次,却因为系统问题,导致重复支付,带来额外的物流成本和扯皮退货的运营成 ...

  2. 支付系统设计中,如何防止重复支付?

    在我们支付系统设计中,经常会遇到这样一个问题,防止用户重复支付.用户明明只想购买一次,却因为系统问题,导致重复支付,带来额外的物流成本和扯皮退货的运营成本,对商家的信誉和系统的体验很不好. 那么实际我 ...

  3. 微信支付SDK 中 PHP Certificate Downloader 微信支付 APIv3 平台证书的命令行下载工具 使用教程

    使用环境 在linux 环境中使用 (没有服务器可以使用虚拟机 复制到本地) windows环境很麻烦 使用前准备 商户号.商户证书序列号.商户私匙文件(pem格式).ApiV3密钥 安装好 微信支付 ...

  4. Python中利用正则表达式做数据清洗(re)

    目录 1.常用正则表达式 Python中常用正则表达式 2.正则表达式做数据清洗 2.1 从网页HTML标签中提取文本 2.2 去掉英文文章中标点符号,提取词汇 2.3 提取以.com结尾的邮箱 1. ...

  5. 用python做毕业设计多少钱_我的毕业设计是利用Python做一个淘淘购物系统!

    此篇文章是纯代码!更多精彩案例加群:626017123 #首页 def tao_first(): t1 = '欢迎进入淘淘购物'.center(110) print(t1) print('~' * 1 ...

  6. 第三方支付流程中,如何利用回调来解决用户掉单的问题

    目前,第三方支付的流程大致包含了三大部分:发起支付,发起退款,接收回调.例如电商就是通过交易驱动的产品类型,因此订单的每一步都要考虑转化率,提高转化率是电商的基础要求.在支付的过程中,用户可能因为拍错 ...

  7. 实现微信支付(Native支付),使用WebSocket进行推送——3.创建支付订单,接收付款结果

    实现微信支付(Native支付),使用WebSocket进行推送--3.创建支付订单,接收付款结果 注:本实验使用springboot框架 一.创建订单 1.流程 2.创建支付订单所需参数 2. AP ...

  8. 【新技术】:移动支付过程中的NFC技术

    这个技术由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司).诺基亚和索尼共同研制开发,其基础是RFID及互连技术.近场通信(Near Field Communication, ...

  9. 实现微信支付(Native支付),使用WebSocket进行推送——1.简单介绍

    实现微信支付(Native支付),使用WebSocket进行推送--1.简单介绍 一.实现逻辑 1.由于本人的项目是web版本的,因此选用native实现微信支付,在网站生成支付二维码,然后用户在手机 ...

  10. 实现微信支付(Native支付),使用WebSocket进行推送 ——4.配置SpringBoot支持WebSocket,推送结果

    实现微信支付(Native支付),使用WebSocket进行推送 --4.配置SpringBoot支持WebSocket,推送结果 依赖 <dependency><groupId&g ...

最新文章

  1. Debug Multithread DLL 与 Debug Multithread
  2. 云原生DevOps的5步升级路径
  3. json转string示例_C.示例中的String.Copy()方法
  4. css background 一半_CSS小技巧
  5. 【警惕】大量未修复WebLogic WSAT组件RCE漏洞的主机被挖矿程序攻击
  6. Inno Setup 插件 CallbackCtrl V1.1 (回调函数插件)
  7. Libra客户端使用
  8. IAR 8.3 for Arm 安装与注册
  9. USB转串口,JLINK驱动安装(亲测有效)
  10. 英语在计算机上的应用研究,计算机在英语教学中的应用
  11. uva 10247 - Complete Tree Labeling(dp)
  12. pc端和移动端有什么区别?
  13. 德勤,普华永道,安永,毕马威这四大会计师事务所,有什么区别
  14. android监听软键盘弹出弹回事件
  15. java后台证件号15转18位
  16. ASIC芯片设计生产流程
  17. 试编程判断输入的正整数是否既是5又是7的整数倍,若是输出“yes”,否则输出“no”。
  18. oracle下k M G,【性能调优】Oracle AWR报告指标全解析(2)
  19. 【后续还会补充】Sublime Text 4 常用插件安装及配置方法
  20. 班尼机器人维修方法_工业机器人常见故障和修理方法

热门文章

  1. C++中2、8、10、16进制数字的表示及计算
  2. boren -飞机大战6
  3. 一个变量对应多个标量的结果(平均值加标准差),Excel作图方法(多数据作图方法)
  4. 双非本科地信前端面试题目
  5. IcedTea6版本1.8
  6. raid服务器怎么装win7系统安装,win7系统安装raid的方法(图文)
  7. 精益创业实战 - 第8章 针对解决方案做客户访谈
  8. 火狐浏览器书签无法删除解决方案
  9. Jeecg-Boot 使用技巧
  10. Linux中用tar命令对文件夹进行打包压缩