苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket

这篇具有很好参考价值的文章主要介绍了苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

HM新出springboot入门项目《苍穹外卖》,笔者打算写一个系列学习笔记,“苍穹外卖项目解读”,内容主要从HM课程,自己实践,以及踩坑填坑出发,以技术,经验为主,记录学习,也希望能给在学想学的小伙伴一个参考。

注:本文章是直接拿到项目的最终代码,然后从代码出发,快速逆向学习技术经验! 可能需要一些前置知识

觉得文章有用可以关注点赞收藏期待更新^^,期待您的评论留言

苍穹外卖项目解读(一) 完整代码本地部署运行
苍穹外卖项目解读(二) 管理端JWT令牌、AOP注解开发、分页
苍穹外卖项目解读(三) redis、cache缓存解读
苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket
苍穹外卖项目解读(五 完结) POI Easyexcel excel操作

苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket,JAVA开发,微信小程序,websocket,java,定时任务

微信小程序支付

微信小程序开发

1、微信小程序开发需要到微信小程序服务平台注册,分为个人、企业、媒体、政府等,提供需要的注册文件即可。不同的注册主体所获得的开发权限有所不同:个人版就无法使用微信支付功能

2、注册完成之后,对于后端开发来说,我们需要在开发管理中获取所注册小程序ID:AppID、小程序秘钥:AppSecret。对应Java配置文件中:

wechat:
    appid: wxffb3637a228223b8
    secret: 84311df9199ecacdf4f12d27b6b9522d

3、微信开发者工具,前端交互开发工具,请大家自行探索^^

4、小程序发布上线,在微信开发者工具中,上传按钮到微信服务器(此时为开发版本),在小程序网页管理端,找到上传的版本小程序,提交审核(审核版本),审核通过之后,即可发布(线上版本)

微信支付

1、已经进行了企业小程序的注册,在微信支付的商户平台接入微信支付,提交资料、签署协议、绑定场景(小程序支付,网页扫码支付,app调用支付等)。(一般开发人员不接触,都是企业注册完成之后拿到后续开发所需要的信息)

微信小程序的支付流程笔者在这里结合日常举例(现金)

我去水果店买东西,挑了一个大西瓜,给老板称重算价格(下单,图例123)。我告诉管着钱的女友买的啥,在哪买的,多大的西瓜,总共花了多少钱并向她要钱(申请微信下单接口,图例456)。女友看了看西瓜跟老板议论这瓜保熟吗xxx(密文,图例78)。我说买了吧,大夏天好热吃个瓜爽歪歪(确定支付 图例9)。女友给老板钱,老板给我西瓜我提着(支付结果,图例10 11 12)。女友走时跟老板说“这瓜保熟,瓜甜的话还来买”(回调,图例13 14)
其中我就是用户,老板水果店是商户,管钱的女友是微信后台
在程序中需要注意的点:
1、向她要钱(申请微信下单接口):准备好参数,去主动请求微信后台(生成预支付交易单)
2、跟老板议论这瓜保熟吗xxx(密文):告诉用户加密好了一些内容,供用户去确定支付
3、吃个瓜爽歪歪(确定支付):真正给钱,微信后台支付
4、回调:指明回调地址,得到结果信息

苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket,JAVA开发,微信小程序,websocket,java,定时任务
5调用微信下单接口 请求图
苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket,JAVA开发,微信小程序,websocket,java,定时任务
9用户确定支付请求图(参数来自7、8封装)
苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket,JAVA开发,微信小程序,websocket,java,定时任务
更多开发细节可关注文档中心

------配置项解析------
  wechat:
    appid: wxffb3637a228223b8  小程序id
    secret: 84311df9199ecacdf4f12d27b6b9522d  小程序秘钥
    mchid : 1561414331  商户号
    mchSerialNo: 4B3B3DC35414AD50B1B755BAF8DE9CC7CF407606  构造请求客户端build使用 WechatPayHttpClientBuilder
    privateKeyFilePath: D:\pay\apiclient_key.pem  商户私钥文件
    apiV3Key: CZBK51236435wxpay435434323FFDuv3  解密回调内容的key
    weChatPayCertFilePath: D:\pay\wechatpay_166D96F876F45C7D07CE98952A96EC980368ACFC.pem  平台证书文件
    notifyUrl: https://58869fb.r2.cpolar.top/notify/paySuccess  回调地址公网ip
    refundNotifyUrl: https://58869fb.r2.cpolar.top/notify/refundSuccess  回调地址

定时任务

spring对定时调度的开发又很友好的开发方式,即启动类上@EnableScheduling,在定时任务上使用@Scheduled,并搭配cron表达式。下面从源码解析spring是如何进行定时调度的。

@EnableScheduling

1、ScheduledAnnotationBeanPostProcessor

其中postProcessAfterInitialization方法中,主要对标注@Scheduled和聚合注解@Schedules的类成员方法进行处理,主要分为2步:
1)识别标注@Scheduled和聚合注解@Schedules的方法;
2)对注解方法调用processScheduled方法进行处理;

2、processScheduled处理过程如下

1)将调用目标方法的过程包装为ScheduledMethodRunnable类
2)构造CronTask并进行调度
3)构造FixedDelayTask并进行调度
4)构造FixedRateTask并进行调度

3、调度框架支持的Task类型
苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket,JAVA开发,微信小程序,websocket,java,定时任务

Spring调度框架中重要支持3种调度任务类型(继承结构如上图),具体说明如下:
1)CronTask:cron表达式调度的任务
2)FixedDelayTask:固定延迟时间执行的任务
3)FixedRateTask:固定速率执行的任务

4、3种的调度执行实现近似,以常用的cron为例

	@Nullable
	public ScheduledTask scheduleCronTask(CronTask task) {
		ScheduledTask scheduledTask = this.unresolvedTasks.remove(task);
		boolean newTask = false;
		if (scheduledTask == null) {
			scheduledTask = new ScheduledTask(task);
			newTask = true;
		}
		if (this.taskScheduler != null) {
			scheduledTask.future = this.taskScheduler.schedule(task.getRunnable(), task.getTrigger());
		}
		else {
			addCronTask(task);
			this.unresolvedTasks.put(task, scheduledTask);
		}
		return (newTask ? scheduledTask : null);
	}

1)将调度任务包装为ScheduledTask类型,其中封装了执行结果ScheduledFuture
2)存在任务调度器(taskScheduler)时,直接进行调度执行.
3)不存在任务调度器(taskScheduler)时,将任务暂存到addCronTask中,待调用afterPropertiesSet方法时再进行调度执行

5、任务调度器支持自定义,当无自定义调度器时,调度框架提供了默认的任务调度器;
自定义任务调度器的处理逻辑在方法finishRegistration中

上述获取任务调度器的优先级顺序为:
1)当Bean后处理器中定义了任务调度器时,优先取Bean后处理器的任务调度器
2)在BeanFactory中获取Bean类型为SchedulingConfigurer的实例,在其方法configureTasks中可以自定义任务调度器
3)获取BeanFactory中TaskScheduler类型的bean(如有)
4)获取BeanFactory中ScheduledExecutorService类型的bean(如有)
5)当上述方式获取的任务调度器都不存在时,会使用框架中默认的任务调度器,如下:

		if (this.taskScheduler == null) {
			this.localExecutor = Executors.newSingleThreadScheduledExecutor();
			this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
		}

6、框架内提供的任务调度器

框架内提供的任务调度器主要包括:

1)ConcurrentTaskScheduler

2)ThreadPoolTaskScheduler
继承结构如下:
苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket,JAVA开发,微信小程序,websocket,java,定时任务
以上述框架默认的ConcurrentTaskScheduler进行说明,在调用调度器方法scheduleWithFixedDelay执行时,具体执行逻辑为:

public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
		try {
			if (this.enterpriseConcurrentScheduler) {//默认false
				return new EnterpriseConcurrentTriggerScheduler().schedule(decorateTask(task, true), trigger);
			}
			else {
				ErrorHandler errorHandler =
						(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
				return new ReschedulingRunnable(task, trigger, this.clock, this.scheduledExecutor, errorHandler).schedule();
			}
		}
		catch (RejectedExecutionException ex) {
			throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
		}
	}

这里主要包含2部分:
1)首先把task任务包装为DelegatingErrorHandlingRunnable类型(支持嵌入错误处理器逻辑),具体是在方法decorateTask中实现
2)调用线程池方法ReschedulingRunnable().schedule()进行调度执行this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);

@Scheduled

fixedDealy

在上一次调用结束和下一次调用开始之间的固定时间内执行注释方法。时间单位默认为毫秒,但可以通过 timeUnit 重载。

fixedRate

以固定的调用间隔执行注释方法。时间单位默认为毫秒,但可以通过 timeUnit.Me 方法重载。

cron表达式

包括秒、分、时、月、月日和星期的触发器。
例如,"0 * * * MON-FRI “表示在工作日每分钟触发一次(在分钟的顶部,即第 0 秒)。
从左到右读取的字段解释如下。
秒 分钟 小时 日 月 星期
特殊值”-"表示禁用 cron 触发器,主要用于由 ${…} 占位符解析的外部指定值。

WebSocket

WebSocket 是一种支持双向通讯网络通信协议。
意思就是服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息
属于服务器推送技术的一种.

特点:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据(blob对象或Arraybuffer对象)

(5)收到的数据类型 可以使用binaryType 指定, 显式指定收到的二进制数据类型

(6)没有同源限制,客户端可以与任意服务器通信。

(7)协议标识符是ws(握手http)(如果加密,则为wss(tcp +TLS)),服务器网址就是 URL。

WebSocket对象
WebSocket对象提供了用于创建和管理WebSocket 连接,以及可以通过该连接发送和接收数据的 API。

使用 WebSocket() 构造函数来构造一个 WebSocket 。

前后端都需要实现websocket的open close message方法

@Component
@ServerEndpoint("/ws/{sid}") //此处类似controller的方式,由前端访问到
public class WebSocketServer {

    //存放会话对象 建立websocket连接的对象,此处的Session为websocke包下
    private static Map<String, Session> sessionMap = new HashMap();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端:" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message) {
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
<script type="text/javascript">
    var websocket = null;
    var clientId = Math.random().toString(36).substr(2);

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        //连接WebSocket节点 建立服务端连接
        websocket = new WebSocket("ws://localhost:8080/ws/"+clientId); 
    }
    else{
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(){
        setMessageInnerHTML("连接成功");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
	
	//关闭连接
    function closeWebSocket() {
        websocket.close();
    }
</script>

reference:
https://blog.csdn.net/supzhili/article/details/131324690
https://baijiahao.baidu.com/s?id=1706643919026404240&wfr=spider&for=pc文章来源地址https://www.toymoban.com/news/detail-721912.html

到了这里,关于苍穹外卖项目解读(四) 微信小程序支付、定时任务、WebSocket的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖微信小程序端(十二)

    1.1.1 产品原型 用户可以将菜品或者套餐添加到购物车。对于菜品来说,如果设置了口味信息,则需要选择规格后才能加入购物车;对于套餐来说,可以直接点击+将当前套餐加入购物车。在购物车中可以修改菜品和套餐的数量,也可以清空购物车。 效果图: 1.1.2 接口设计 通过

    2024年01月18日
    浏览(43)
  • 基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖微信小程序端(九)

    1.1 入门 在进行微信登录之前我们要先知道HttpClient是什么,它是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。 HttpClient作用: 发送HTTP请求 接收响应数据 HttpClient应用场景

    2024年02月03日
    浏览(49)
  • 基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖微信小程序端(十一)

    1.1 问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。 结果 :系统响应慢、用户体验差 1.2 实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: 每个分类下的菜品保存一份缓存数据

    2024年01月24日
    浏览(49)
  • 苍穹外卖day10——订单状态定时处理(Spring Task)、来单提醒和客户催单(WebSocket)

       对于超时没处理的需要定时程序处理。基于SpringTask实现。 来单提醒和客户催单。基于WebSocket实现。     周几通常不能和日一起指定。   cron表达式在线生成器 在线Cron表达式生成器  创建定时任务类     新建一个task包中一个类如下 在OrderMapper中 运行测试无误。     导

    2024年02月14日
    浏览(49)
  • 【苍穹外卖 | 项目日记】第一天

    我打算用16天的时间写完黑马程序员的苍穹外卖项目,为了督促自己每天坚持写以及记录项目知识点,所以用这种项目日记的方式鞭策自己 目录 前言: 今日完结任务: 今日收获: 1.阅读代码框架: 2.新增员工接口: 3.分页查询接口: 4.员工状态修改接口: 杂项知识点: 总

    2024年02月08日
    浏览(43)
  • 项目实战————苍穹外卖(DAY11)

    Apache ECharts 营业额统计 用户统计 订单统计 销量排名Top10 功能实现: 数据统计 数据统计效果图: 1.1 介绍 Apache ECharts 是一款基于 Javascript 的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。 官网地址:Apache ECharts 常见效果展示: 1). 柱形图

    2024年01月20日
    浏览(49)
  • 苍穹外卖day02项目日志

    参考产品原型,设计表和接口。 1.1.1设计表 看员工管理的产品原型: 有员工姓名、账号、手机号、账号状态、最后操作时间等。 注意,操作一栏不是字段,其中的启用禁用才是。 再看添加员工的原型:  可以发现还有性别和身份证号。 不要忘了旁边: 还有密码。 总结出了

    2024年02月14日
    浏览(73)
  • 苍穹外卖-第一章项目介绍

    1)管理端功能 员工登录/退出 , 员工信息管理 , 分类管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 订单管理 ,数据统计,来单提醒。 2)用户端功能 微信登录 , 收件人地址管理 , 用户历史订单查询 , 菜品规格查询 , 购物车功能 , 下单 , 支付、分类及菜品浏览。 1)管理端 餐饮企业

    2024年02月08日
    浏览(44)
  • uniapp项目编译成H5后跳转到微信小程序(支持微信扫码、支付宝扫码)

    uniapp项目编译成 H5 后跳转到 微信小程序 (支持微信H5、支付宝H5) 场景:1、微信扫码跳转到该H5中后点击某事件(或者不点击直接跳转)需要跳转到微信小程序;2、支付宝扫码跳转到H5中后点击某事件(或者不点击直接跳转)需要跳转到微信小程序 思路:调用后端接口返回

    2024年02月13日
    浏览(56)
  • 基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(四)

    1.1 需求分析与设计 1.1.1 产品原型 在员工管理列表页面点击 “编辑” 按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击 “保存” 按钮完成编辑操作。 修改页面原型 : 注:点击修改时,数据应该正常回显到修改页面。 1.1.2 接口设计 根据上述原型图分

    2024年02月05日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包