- 前言
- 1. 支付安全
- 1.1 对称加密和非对称加密
- 1.2 身份认证
- 1.3 摘要算法
- 1.4 数字签名和数字证书
- 2. 项目初期
- 2.1 构建测试
- 2.2 引入Swagger
- 2.3 引入lombok
- 3. 数据库
- 3.1 实体类
- 3.2 映射类
- 3.3 service类
- 3.4 配置类
- 3.5 业务逻辑
- 4. 前端界面
- 4.1 vue
- 5. 主要功能
- 5.1 微信支付参数
- 5.2 配置类
- 5.3 加载私钥文件
本项目主要通过以下链接进行学习
【尚硅谷】微信支付开发,基于SpringBoot+Vue架构的Java在线支付视频教程
这篇文章结合了自已的思考以及笔记
该项目主要是基于
后端技术有:springboot+springmvc+restful+vue+mybatis-plus+mysql
前端技术有:html+css+vue
本文的框架主要介绍
- 微信支付的一些引言,关于支付的证书、密钥以及签名
- 项目的构建到实现
- 基础支付API接口
本文的框架涉及的知识点 可看我之前的文章
基础知识:
- java零基础从入门到精通(全)
- javaSE从入门到精通的二十万字总结(一)
- javaSE从入门到精通的二十万字总结(二)
- javaSE从入门到精通的二十万字总结(三)
服务端:
- Spring框架从入门到学精(全)
- SpringMVC从入门到精通(全)
- Mybatis从入门到精通(全)
- MyBatis-plus从入门到精通(全)
数据库:
- 数据库中增删改常用语法语句(全)
- 数据库查询常用语句语法
web服务器:Tomcat详细配置(全)
项目管理:
- Maven实战从入门到精通(全)
- Maven详细配置(全)
前端知识点:
- html从入门到精通(全)
- css属性从入门到精通(全)
- Javascript从入门到精通(全)
- 明文:加密前的消息叫“明文”(plain text)
- 密文:加密后的文本叫“密文”(cipher text)
- 密钥:只有掌握特殊“钥匙”的人,才能对加密的文本进行解密,这里的“钥匙”就叫做“密钥”(key)
按照密钥的使用方式,加密可以分为两大类:对称加密和非对称加密
1.1 对称加密和非对称加密对称加密
特点:只使用一个密钥,密钥必须保密,常用的有 AES算法
- 优点:运算速度快
- 缺点:秘钥需要信息交换的双方共享,一旦被窃取,消息会被破解,无法做到安全的密钥交换
非对称加密
特点:使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,常用的有 RSA
- 优点:黑客获取公钥无法破解密文,解决了密钥交换的问题
- 缺点:运算速度非常慢
- 公钥加密,私钥解密的作用是加密信息
- 私钥加密,公钥解密的作用是身份认证
一般来说公钥加密之后,公钥都是公开的,通过私钥进行解密
而如果反过来,通过私钥加密,公钥解密,那就是身份认证,专属自已的唯一钥匙
1.3 摘要算法主要为了保证数据没有被修改过,保证信息的完整性
摘要算法就是我们常说的散列函数、哈希函数(Hash Function),它能够把任意长度的数据“压缩”成
固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。
主要的特性有:
- 不可逆:只有算法,没有秘钥,只能加密,不能解密
- 难题友好性:想要破解,只能暴力枚举
- 发散性:只要对原文进行一点点改动,摘要就会发生剧烈变化
- 抗碰撞性:原文不同,计算后的摘要也要不同
为了凸显数据的完整性,通过加入摘要算法,将其添加进数据中
而拿到数据的人为了验证数据完整性,通常也要通过摘要算法,也就是哈希,判断数据前后是否一致,依次判定是否有修改
但如果中间被截获,生成新的摘要算法,很难判断是否又被其他人修改
1.4 数字签名和数字证书数字签名:
将数据通过摘要算法之后还要再用私钥加密变成数字签名
而获得数据的人,需要通过公钥进行解密以及通过摘要算法来验证数据的完整性
上面的公钥可以伪造
为此多了一个数字证书
数字证书:
数字证书解决“公钥的信任”问题,可以防止黑客伪造公钥。
不能直接分发公钥,公钥的分发必须使用数字证书,数字证书由CA颁发
具体数字证书生成流程如下:
通过哈希算法也就是摘要算法生成信息再通过CA的私钥加密变成数字证书
A用数字证书发送数据,B取到数据后,通过哈希算法也就是摘要算法进行确定完整性,再通过CA的公钥判定是否可以取出,取出之后就是A的公钥了。B再用取到的A公钥进行解密,以及摘要算法确定数据的完整性
在科普一下https的数字证书:
创建springboot的项目
通过idea编译器 new 一个spring initializr的项目,java8的版本
以及服务器使用https://start.aliyun.com,会比较快
具体关于springboot的相关知识可看我之前的文章
springboot从入门到精通(全)
此处修改以下pom文件下的依赖文件改成web,主要为了网页的启动
org.springframework.boot spring-boot-starter-web
配置一个端口号(资源文件下)
server: port: 8090 #服务端口 spring: application: name: payment-demo #应用的名字
配置一个界面,进行测试springboot的启动
@RestController //主要是为了传输json数据的一个注解 @RequestMapping("/api/product") public class ProductController { @GetMapping("/test") public String test(){ return "hello"; } }
在浏览器中输入url为
http://localhost:8090/api/product/test 进行测试
几个注意事项:
在搭建springboot的时候
使用maven管理jar包的时候不要混乱使用版本号
(注解不要混乱使用jar包各个版本)
自动生成接口文档和相关的测试界面
测试get post delete等界面的时候比较方便
一个是依赖文件一个是ui的展示界面依赖包
io.springfox springfox-swagger22.7.0 io.springfox springfox-swagger-ui2.7.0
配置一个配置类
通过bean对象注入
如一个文本的文档对象
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.spi.documentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket docket(){ return new Docket(documentationType.SWAGGER_2) .apiInfo(new ApiInfoBuilder().title("码农研究僧微信支付案例接口文档").build()); } }
之后在网址中输入如下页面http://localhost:8090/swagger-ui.html#/
为了更好的通过url与swagger的更好融合
可以在业务层的代码模块中增加如下,@Api(tags = "商品管理"),@ApiOperation("测试接口")
这个注解@ApiOperation(" )只有一个value值 ,所以value值可以省略
@Api(tags = "商品管理") @RestController //主要是为了传输json数据的一个注解 @RequestMapping("/api/product") public class ProductController { @ApiOperation("测试接口") @GetMapping("/test") public String test(){ return "hello"; } }
之后在页面中就会这么显示
2.3 引入lombok为了前后端更好的交互,定义一个统一的结果
主要显示响应码,响应消息
再依赖包中要放一个lombok
主要是可以简化开发,自动生成get、set等方法
(前提是有lombok的插件)
org.projectlombok lombok
主要的代码模块为
@Data public class R { private Integer code; //响应码 private String message; //响应消息 private Mapdata = new HashMap<>(); public static R ok(){ R r = new R(); r.setCode(0); r.setMessage("成功"); return r; } public static R error(){ R r = new R(); r.setCode(-1); r.setMessage("失败"); return r; } public R data(String key, Object value){ this.data.put(key, value); return this; } }
通过@Data这个注解查看其structure结构,也可以看到自动生成了get和set等方法
关于@Data这个注解可看我之前的文章
spring中@Data注解详细解析
给前端传输一些具体的信息
通过data这个哈希进行传输
public R data(String key, Object value){ this.data.put(key, value); return this; }
在显示界面中通过输入一定的值就可看到
链式 *** 作,可以多个值传输
@ApiOperation("测试接口") @GetMapping("/test") public R test(){ return R.ok().data("message", "hello").data("now", new Date()); }
特别补充一下如果这样传输new Date()的数据,不是一个标准的格式
如果要换成想要的格式
可以在资源文件中进行添加(本身时json的数据格式)
yyyy-MM-dd HH:mm:ss 年月日,分时秒,GMT+8以及时区
jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+83. 数据库
通过navicat软件或者本机的mysql进行构建数据库
通过运行特定的数据库脚本或者自已书写数据库
具体sql的脚本如下
USE `payment_demo`; CREATE TABLE `t_order_info` ( `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单id', `title` varchar(256) DEFAULT NULL COMMENT '订单标题', `order_no` varchar(50) DEFAULT NULL COMMENT '商户订单编号', `user_id` bigint(20) DEFAULT NULL COMMENT '用户id', `product_id` bigint(20) DEFAULT NULL COMMENT '支付产品id', `total_fee` int(11) DEFAULT NULL COMMENT '订单金额(分)', `code_url` varchar(50) DEFAULT NULL COMMENT '订单二维码连接', `order_status` varchar(10) DEFAULT NULL COMMENT '订单状态', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; CREATE TABLE `t_payment_info` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '支付记录id', `order_no` varchar(50) DEFAULT NULL COMMENT '商户订单编号', `transaction_id` varchar(50) DEFAULT NULL COMMENT '支付系统交易编号', `payment_type` varchar(20) DEFAULT NULL COMMENT '支付类型', `trade_type` varchar(20) DEFAULT NULL COMMENT '交易类型', `trade_state` varchar(50) DEFAULT NULL COMMENT '交易状态', `payer_total` int(11) DEFAULT NULL COMMENT '支付金额(分)', `content` text COMMENT '通知参数', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; CREATE TABLE `t_product` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '商品id', `title` varchar(20) DEFAULT NULL COMMENT '商品名称', `price` int(11) DEFAULT NULL COMMENT '价格(分)', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; insert into `t_product`(`title`,`price`) values ('Java课程',1); insert into `t_product`(`title`,`price`) values ('大数据课程',1); insert into `t_product`(`title`,`price`) values ('前端课程',1); insert into `t_product`(`title`,`price`) values ('UI课程',1); CREATE TABLE `t_refund_info` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '退款单id', `order_no` varchar(50) DEFAULT NULL COMMENT '商户订单编号', `refund_no` varchar(50) DEFAULT NULL COMMENT '商户退款单编号', `refund_id` varchar(50) DEFAULT NULL COMMENT '支付系统退款单号', `total_fee` int(11) DEFAULT NULL COMMENT '原订单金额(分)', `refund` int(11) DEFAULT NULL COMMENT '退款金额(分)', `reason` varchar(50) DEFAULT NULL COMMENT '退款原因', `refund_status` varchar(10) DEFAULT NULL COMMENT '退款状态', `content_return` text COMMENT '申请退款返回参数', `content_notify` text COMMENT '退款结果通知参数', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
在java代码模块中
引入数据库的依赖包
mysql mysql-connector-javacom.baomidou mybatis-plus-boot-starter3.3.1
添加数据库的连接
datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/payment_demo?serverTimezone=GMT%2B8&characterEncoding=utf-8 username: root password: 123456
数据库的版本号如果是5左右,版本名字叫做com.mysql.jdbc.Driver
如果是8的版本号,版本名字叫做com.mysql.cj.jdbc.Driver,即使在pom文件中不给版本号,系统也会默认给8的版本
具体下载方式可以通过maven工程
也可以通过如下进行下载
- mysql-connector-java-8.0.26.rar
- MySql Connector Java 5.1.23.rar
代码模块中关于数据库
需要数据库表的实体类,映射文件,以及业务逻辑的代码模块
可以通过mybatis的逆向工程一键生成
具体可看我之前的文章
mybatis逆向工程详细配置讲解(全)
一共有四张表格,而也有公共的列名称,所以可以设置一个公有类,之后通过继承
在命名的时候如果表格与实体类不一样,可以通过@TableName("t_order_info")这个注解进行映射
如果列名和数据库的列名不一样,也可以映射,但最好使用驼峰的命名规则,mybatisplus就会帮忙转换
(通过lombok的插件 可以自动生成get、set等方法)
如果数据库有主键还需要再主键中配备一个注解
定义主键策略:跟随数据库的主键自增@TableId(value = "id", type = IdType.AUTO)
继承baseMapper
这个类,是mybatis-plus中的统用maper
动态的生成一些特定的接口
xml文件也没有一些书写代码
补充:
再编译之后 target目录中,没有生成xml文件
默认情况下,java目录下非java代码生成不了
资源路径搭配的选项
让maven 中把非java文件也生成
src/main/java **/*.xml false
让运行文件能够找到xml文件
应用程序的mapper如何找到
主要是这一行代码
mapper-locations: classpath:com/paymentdemo/mapper/xml/*.xml
顺便补充一下日志的配置文件
3.3 service类继承了IService
定义了一些增删改查等抽象方法还有一些分页以及批量处理的方法
主要是开启事务
以及扫描映射文件
import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @MapperScan("com.paymentdemo.mapper") @EnableTransactionManagement //启用事务管理 public class MyBatisPlusConfig { }3.5 业务逻辑
添加完数据库之后
就可以通过调用数据库的数据
@CrossOrigin //开放前端的跨域访问 @Api(tags = "商品管理") @RestController @RequestMapping("/api/product") public class ProductController { @Resource private ProductService productService; @GetMapping("/list") public R list(){ Listlist = productService.list(); return R.ok().data("productList", list); } }
之后在页面中就可以访问到数据
http://localhost:8090/swagger-ui.html#!/21830216973164929702/listUsingGET
同时在终端中也可以看到日志的输出
前端界面主要是vue+javascript+html
刚开始是安装node的安装包,可以通过官网进行安装
安装完之后,再cmd命令下搜node -v即可查到版本号
在前端搭建的项目中输入 npm run serve
默认是开启了前端的界面
但是搭建了后端界面,以及前端界面之后,是没有进行连接的,所以登陆进去会出错
前端的端口号中有为8080,但是后端的端口号为8090,所以是不一样的端口号,需要进行跨域
通信的方式为ajax方式
在后端的代码中需要添加一个注解,代表是进行跨域的请求访问
@CrossOrigin //开放前端的跨域访问
具体打开vue的代码模块通过vscode这个软件
具体怎么安装可通过官网进行下载
一般新手添加三个插件比较好(chinese的中文包、vuehelper的帮助文档等)
一般如果不安装镜像进行下载的话,会通过国内的链接进行下载,一般会比较卡
所以再cmd命令行下面输入这两行命令
-
npm config set registry https://registry.npm.taobao.org ,npm install的安装都会经过淘宝的镜像地址进行下载
-
npm install -g @vue/cli 进行全局的安装脚手架
正常安装情况下:(出现warn不要怕,出现error要害怕)
如果不能安装可查看我这篇文章
出现npm ERR code EPERM npm ERR syscall mkdir npm ERR path B:nodejsnode_global_cacache 的解决方法
vscode的快捷键:
crtl + ~ 打开终端
ctrl + l 滚动终端到上面
新建一个项目 vue create 项目名
运行这个项目 npm run serve -- --port 端口号
第一个-- 代表是占位符,可以不用填写,第二个–是端口号
vue的页面组件:
- 页面显示的文件
- 需要的脚本
- 页面的样式
具体简单的vue页面架构如下:
App.vue的页面内容主要有:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)