舒大少博客

一个95后少年的个人博客

当前时间为:
欢迎大家来到舒大少博客https://www.9713job.com,广告合作以及淘宝商家推广请微信联系15357240395

java编写微信支付

2022-05-07 19:55:20
swq1822677238
  1. 注册微信商户
  2. 下载微信支付的 SDK
  3. 打开idea打开微信支付的sdk复制到自己的项目中
  4. 在项目里创建配置类,继承WXPayConfig类,在里面添加商户信息
    public class MyWxPayConfig extends WXPayConfig{
        @Override
        String getAppID() {
            return "商户appid";
        }
    
        @Override
        String getMchID() {
            return "商户号";
        }
    
        @Override
        String getKey() {
            return "证书秘钥";
        }
    
        @Override
        InputStream getCertStream() {
            return null;
        }
    
        @Override
        IWXPayDomain getWXPayDomain() {
            MyWXPayDomain domain=new MyWXPayDomain();
            return domain;
        }
    }
  5. 在项目中创建一个类实现IWXPayDomain接口
    @Override
    public void report(String domain, long elapsedTimeMillis, Exception ex) {
    
    }
    
    @Override
    public DomainInfo getDomain(WXPayConfig config) {
        DomainInfo info=new DomainInfo("api.mch.weixin.qq.com",true);
        return info;
    }
  6. 编写场景类支付
    public class TestPay {
        public static void main(String[] args) throws Exception {
            MyWxPayConfig config = new MyWxPayConfig();
    
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> data = new HashMap<String, String>();
            data.put("body", "腾讯充值中心-QQ会员充值");
            data.put("out_trade_no", "2022050719401100000012");
            data.put("device_info", "");
            data.put("fee_type", "CNY");
            data.put("total_fee", "1");
            data.put("spbill_create_ip", "123.12.12.123");
            data.put("notify_url", "http://www.example.com/wxpay/notify");
            data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
            data.put("product_id", "12");
    
            try {
                Map<String, String> resp = wxpay.unifiedOrder(data);
                System.out.println(resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
  7. 内网穿透
    网址 natapp.cn,注册登录完成实名,然后购买免费隧道,复制token,下载客户端,在exe当前目录打开cmd,输入 natapp -authtoken=token
  8. 回应消息给微信后台
    @RequestMapping("/notify_url")
    public void doPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        byte[] buffer=new byte[1024];
        int len=0;
        while( (len= inputStream.read(buffer))!=-1 ){
            System.out.println(new String(buffer,0,len));
        }
        response.getWriter().write("<xml>\n" +
                "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                "</xml>");
    }
  9. zxing二维码生成
    <!--zxing二维码生成-->
    <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.3.3</version>
    </dependency>
    <!--zxing二维码生成-->
    <!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>javase</artifactId>
        <version>3.4.0</version>
    </dependency>
  10. 绘制二维码
    // 绘制二维码
    @RequestMapping("/qrcode")
    public void qrcode(HttpServletResponse response)throws URISyntaxException, IOException {
        //二维码需要包含的文本内容
        String uri ="http://www.baidu.com";
        HashMap<EncodeHintType,Object> hints=new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN,2);
        try {
            BitMatrix bitMatrix=new MultiFormatWriter().encode(uri, BarcodeFormat.QR_CODE,200,200,hints);
            MatrixToImageWriter.writeToStream(bitMatrix,"PNG",response.getOutputStream());
            System.out.println("创建二维码完成");}
        catch(Exception e){
            e.printStackTrace();
        }
    }
  11. goeasy异步调用
    goeasy:网址:https://www.goeasy.io/
    加依赖

    <!-- goeasy 异步 -->
    <dependency>
        <groupId>io.goeasy</groupId>
        <artifactId>goeasy-sdk</artifactId>
        <version>0.3.16</version>
    </dependency>

    在 goeasy创建应用,获取Common key及hangzhou.goeasy.io

    在微信支付通知的控制层新增

    GoEasy goEasy = new GoEasy( "http://rest-hangzhou.goeasy.io/v2/pubsub/publish", "BC-3d456eb942cc4926b807cdb77dfb5216");
    goEasy.publish("wxpay", "success");

    下单页面

    <script src="http://hangzhou.goeasy.io/goeasy.js"></script>
    <script>
        //初始化
        var goeasy  = new GoEasy({
            host:"hangzhou.goeasy.io",  //若是新加坡区域:singapore.goeasy.io
            appkey:"BC-3d456eb942cc4926b807cdb77dfb5216",
            modules:['pubsub']//根据需要,传入‘pubsub’或'im’,或数组方式同时传入
        })
        var pubsub = goeasy.pubsub;
        goeasy.subscribe({
            channel: "wxpay",//替换为您自己的channel
            onMessage: function (message) {
                alert("收到:"+message.content);
                console.log("Channel:" + message.channel + " content:" + message.content);
            }
        });
    </script>

shiro权限框架

2022-05-06 09:58:45
swq1822677238

shiro依赖

<!--shiro-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.8.0</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.4.0</version>
</dependency>

数据库设计

drop database if exists springboot_shiro;
create database if not exists springboot_shiro;
use springboot_shiro;

create table shiro_user(
    id int auto_increment primary key ,
    username varchar(50),
    password varchar(50),
    salt varchar(50)
)charset=utf8;

shiro 框架相关的配置类 (更多…)

文件上传

2022-04-28 16:57:59
swq1822677238

upload工具类

public class UploadUtils {
    // 生成带有UUID新的文件名
    public static String newFileName(String filename){
        return UUID.randomUUID().toString().replaceAll("-","")+"_"+filename;
    }
    // 生成二级、三级目录
    public static String newFilePath(String basePath,String fileName){
        int hashCode = fileName.hashCode();
        int path1=hashCode&15;
        int path2=(hashCode>>4)&15;
        String newPath=basePath+ File.separator+path1+File.separator+path2;
        File file=new File(newPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return newPath;
    }
}

(更多…)

仓库 “MySQL 5.7 Community Server” 的 GPG 密钥已安装,但是不适用于此软件包。请检查仓库的公 钥 URL 是否配置正确

2022-04-27 22:30:08
swq1822677238

rpm –checksig package_name.rpm

rpm –checksig mysql-community-server-5.7.38-1.el8.x86_64.rpm

gpg –export -a 3a79bd29 > 3a79bd29.asc

rpm –import 3a79bd29.asc

rpm –import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

Java微服务架构:RabbitMQ

2022-04-26 17:40:57
swq1822677238

一、RabbitMQ 介绍

1.1 引言

  1. 模块之间的耦合过高,导致一个模块宕机后,全部功能都不能用了
  2. 同步通讯的成本偏高

 

1.2 RabbitMQ的介绍

市面上比较火爆的几款MQ:
ActiveMQ,RocketMQ,Kafka,RabbitMQ。

  1. 语言的支持:ActiveMQ,RocketMQ只支持Java语言,Kafka可以支持多门语言,RabbitMQ支持多种语言
  2. 效率问题:ActiveMQ,RocketMQ,Kafka效率都是毫秒级别的,RabbitMQ是微秒级别的
  3. 消息丢失,消息重复问题:RabbitMQ针对消息的持久化,和重复问题都有比较成熟的解决方案
  4. 学习成本:RabbitMQ非常简单

RabbitMQ 是由Rabbit公司去研发和维护的,最终是在Pivotal。

RabbitMQ 严格遵循AMQP协议,高级消息队列协议,帮助我们在进程之间传递异步消息。 (更多…)

Linux报错:Redirecting to /bin/systemctl stop mysqld.service

2022-04-23 17:20:44
swq1822677238

启动Linux上面的服务报错

[root@iZ25n5kdt0kZ ~]# service mysqld stop
Redirecting to /bin/systemctl stop mysqld.service

解决方案:

首先使用cd命令切换目录,例:cd bin,根据具体的报错提示在对应目录下面操作mysql

1.使用如下命令操作mysql:
systemctl restart mysqld.service
systemctl start mysqld.service
systemctl stop mysqld.service

微信小程序之WXS脚本

2022-04-22 15:06:00
swq1822677238
  1. 内嵌 WXS 脚本
    xxx.wxml

    <view>{{m1.toUpper(username)}}</view>
    <wxs module=”m1″>
      module.exports.toUpper=function(e){
        return e.toUpperCase()
      }
    </wxs>

    xxx.js

    data: {
        username:”username”
      },
  2. 定义外联 WXS 脚本
    在 tools文件夹下新建文件为 tools.wxs

    function toLower(str){
      return str.toLowerCase()
    }
    module.exports={
      toLower:toLower
    }
  3. 使用外联 WXS 脚本
    在WXML 中引入外联的wxs脚本时,必须为 wxs 标签添加 module 和 src 属性,其中:
    module 用来指定模块的名称
    src 用来指定要引入的脚本的绝对路径

微信小程序之下拉刷新及上拉触底事件

2022-04-22 10:03:54
swq1822677238
  1. 监听页面的下拉刷新事件
    在页面的.js 文件中,通过 onPullDownRefresh() 函数即可监听当前页面的下拉刷新事件
  2. 停止下拉刷新事件
    当处理完下拉刷新后,下拉刷新的 loading 效果会一直显示,不会主动消失。
    调用wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新
  3. 监听上拉触底事件
    在页面的.js 文件中,通过 onReachBottom() 函数即可监听当前页面的上拉触底事件
  4. 添加loading效果
  5. 对上拉触底进行节流处理

    data:{
    isLoding:false
    }
    getColor:{
    this.setData({
    isLoding:true
    })
    wx.request(){
    success下面
    complete:()=>{
    wx.hideLoading()
    this.setData({
    isLoding:false
    })
    }
    }
    }
    onReachBottom:function(){
    if(this.data.isLoading) return
    this.getColors()
    }

微信小程序之导航传参

2022-04-22 09:51:33
swq1822677238
  1. 声明式导航传参
    navigator组件的url属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数。
    参数与路径之间使用?分隔
    参数键与参数值用=相连
    不同参数用&分隔
    代码示例如下:
    <navigator url=”/pages/info/info?username=zs&age=22″>导航传参</navigator>
  2. 编程式导航传参
  3. 在 onLoad 中接收导航参数
    通过声明式或编程式导航传参所携带的参数,可以直接在 onLoad 事件中 直接获取到。示例代码

微信小程序之页面导航

2022-04-22 08:49:54
swq1822677238
  1. 小程序中实现页面导航的两种方式
    1、声明式导航:在页面上声明一个 navigator 导航组件,通过点击 navigator 组件实现页面跳转
    2、编程式导航:调用小程序的导航API,实现页面的跳转
  2. 声明式导航
    tabBar页面指的是被配置为tabBar的页面
    在使用 navigator 组件跳转到指定的 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中
    url 表示要跳转的页面的地址,必须以 / 开头
    open-type 表示跳转的方式,必须为 switchTab
    示例代码:
    <navigator url=”/pages/massage/message” open-type=”switchTab”>导航到消息页面</navigator>
  3. 导航到非 tabBar页面
    非tabBar页面指的是没有配置tabBar的页面
    在使用 navigator 组件跳转到普通的非 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中
    url 表示要跳转的页面的地址,必须以 / 开头
    open-type 表示跳转的方式,必须为 navigate
    示例代码:
    <navigator url=”/pages/massage/message” open-type=”navigate”>导航到消息页面</navigator>
  4. 后退导航
    如果要后退上一页面或多级页面,则需要指定 open-type 属性 和 delta 属性,其中:
    open-type 的值必须是 navigateBack,表示要进行后退导航
    dalta 的值必须是数字,表示要后退的层级
    示例代码:
    <navigator open-type=”navigateBack” delta=”1″>返回上一页</navigator>
    注意:可以省略 delta,默认值是1

1.  编程式导航

1、导航到tabBar页面

调用 wx.switchTab(Object obj)方法,可以跳转到 tabBar页面。其中Object 参数对象的属性列表如下:

 

2. 导航到非 tabBar页面

调用 wx.navigateTo(Object obj)方法,可以跳转到非tabBar页面。其中Object 参数对象的属性列表如下:

3. 后退导航

调用wx.navigateBack(Object obj)方法,可以返回上一级或多级页面,其中 Object参数对象 可选的属性列表如下:

 

微信小程序之九宫格布局

2022-04-21 18:52:28
swq1822677238

微信小程序之九宫格布局

页面:

<view class=”nav9″>
  <view wx:for=”{{nine}}” wx:key=”id”>
   <image src=”{{item.icon}}” style=”width: 50px;height:50px”></image>
   <text>{{item.name}}</text>
  </view>
 </view>
样式:
.nav9{
  display: flex;
  flex-wrap: wrap;
  border-top: 1rpx solid #eee;
  border-left: 1rpx solid #eee;
}
.nav9 view{
  box-sizing: border-box;
  width:33.33%;
  height:200rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-right: 1rpx solid #eee;
  border-bottom: 1rpx solid #eee;
}
.nav9 text{
  font-size: 24rpx;
  margin-top: 10px;
}

微信小程序之网络数据请求

2022-04-21 17:27:50
swq1822677238
  1. 小程序中网络数据请求的限制
    出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
    1、只能请求 https 类型的接口
    2、必须将接口的域名添加到信任列表里(右上角详情—>项目配置–>域名信息)
  2. 发起GET请求
    调用微信小程序提供的 wx.request() 方法,可以发起 GET数据请求,代码如下:

xxx.wxml

<button bindtap=”ajax”>获取请求</button>
xxx.js
ajax(){
    wx.request({
      url: ‘https://www.escook.cn/api/get’,
      method:’GET’,
      data:{
        name:’demo’,
        age:20
      },
      success:(res) =>{
        console.log(res.data)
      }
    })
  },
3. 发起 post 请求

xxx.wxml

<button bindtap=”ajax”>获取请求</button>
xxx.js
ajax(){
    wx.request({
      url: ‘https://www.escook.cn/api/post’,
      method:’POST’,
      data:{
        name:’demo’,
        age:20
      },
      success:(res) =>{
        console.log(res.data)
      }
    })
  },
5. 在页面刚加载时请求数据
在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据。
此时需要在页面的 onLoad 事件中调用获取数据的函数,代码如下:
xxx.js
onLoad: function (options) {
    this.ajax()
  },
6. 跳过 request 合法域名效验
如果后端程序员仅仅提供了 http 协议的接口、暂时没有提供 https协议的接口。
此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS 版本及HTTPS证书 选项
跳过request合法域名的校验。

微信小程序之全局配置tabBar

2022-04-21 16:29:35
swq1822677238
  1. 什么是tabBar
    tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换。
    小程序中通常将其分为:底部 tabBar、顶部 tabBar
    注意:tabBar 中只能配置 最少2个,最多5个tab页签,当渲染顶部 tabBar时,不显示 icon,只显示文本
  2. tabBar 的6个组成部分
  3. tabBar 节点的配置项
  4. 每个tab项的配置选项
    app.json:

    “tabBar”: {
        “list”: [
          {
            “pagePath”: “pages/home/home”,
            “iconPath”: “/images/home.png”,
            “selectedIconPath”: “/images/home-active.png”,
            “text”: “首页”
          },
          {
            “pagePath”: “pages/message/message”,
            “iconPath”: “/images/message.png”,
            “selectedIconPath”: “/images/message-active.png”,
            “text”: “消息”
          },
          {
            “pagePath”: “pages/contact/contact”,
            “iconPath”: “/images/contact.png”,
            “selectedIconPath”: “/images/contact-active.png”,
            “text”: “联系我们”
          }
        ]
      },

微信小程序之全局配置

2022-04-21 15:24:51
swq1822677238
  1. 全局配置文件及常用的配置项
    小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下:
    1:pages:记录当前小程序所有的页面存放路径
    2、window:全局设置小程序窗口的外观
    3、tabBar:设置小程序底部的 tabBar 效果
    4、style:是否启用新版的组件样式
  2. 全局配置-window
    1、小程序窗口的组成部分

    2、 了解 window 节点 常用的配置项
    3、设置导航栏的标题
    设置步骤:app.json–>window–>navigationBarTitleText
    演示:把导航条上的标题,从默认的 WeChat 修改为 我的第一个微信小程序,效果如图
    4、设置导航栏的背景色
    设置步骤:app.json–>window–>navigationBarBackgroundColor
    演示:把导航栏标题的背景色,从默认的 #fff 修改为 #994855,效果如图
    5、设置导航栏的标题颜色
    设置步骤:app/json–>window–>navigationBarTextStyle
    演示:把导航条上的标题,从默认的 black 修改为 white ,效果如图

    6、全局开启下拉刷新功能
    设置步骤:app.json–>window–>把 enablePullDownRefresh 设为 true,效果如图

    7、 设置下拉刷新时背景颜色
    当全局开启下拉刷新功能之后,默认的窗口背景为白色,如果自定义下拉刷新窗口背景色
    设置步骤:app.json–>window–>为 backgroundColor 指定16进制的颜色值 #9e9e9e,效果如下

    8、 设置下拉刷新时 loading 的样式
    当全局开启下拉刷新功能之后,默认窗口的 loading 样式为白色,如果要更改 loading 样式的效果
    设置步骤:app.json–>window–>为 backgroundTextStyle 指定 dark  值
    可选值为 light 和 dark

    9、设置上拉触底的距离
    概念:上拉加载更多数据
    设置步骤:app.json–>window–>为 onReachBottomDistance 设置新值。默认50px,px可省略

微信小程序之全局样式和局部样式

2022-04-21 15:07:26
swq1822677238
  1. 全局样式
    定义在 app.wxss 中的样式为全局样式,作用于每一个页面
  2. 局部样式
    在页面的.wxss 中的样式为局部样式,作用于当前页面

微信小程序之WXSS模板样式

2022-04-21 14:52:05
swq1822677238
  1. 什么是WXSS
    WXSS(WeiXin Style Sheets)是一套样式语言,用于美化 WXML 的组件样式,类似于网页开发中的 CSS
  2. WXSS 与 CSS 的 关系
    WXSS具有Css大部分特性,同时,WXSS 还对 CSS 进行了扩充以及修改,以适应微信小程序的开发。
    与 CSS 相比,WXSS 扩展的特性有:
    1、rpx 尺寸单位 2、@import 样式导入
  3. 什么是 rpx 尺寸单位
    rpx (responsive pixel) 是微信小程序独有的,用来解决屏适配的尺寸单位。
  4. rpx 实现原理
    rpx的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx把所有设备的屏幕,在宽度上等分为 750 份(即:当前屏幕的总宽度为750rpx)。
    小程序在不同设备上运行的时候,会自动把rpx的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。
  5. 样式导入
    使用WXSS 提供的 @import  语法,可以导入外联的样式表
  6. @import 的语法格式
    @import 后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束。示例:
    @import “xxx.wxss”;

微信小程序示例:列表渲染

2022-04-21 10:39:33
swq1822677238

1.wx:for

通过 wx:for 可以根据指定的数组,循环渲染重复的组件结构,语法如下:

<view wx:for=”{{array}}”>
  索引是:{{index}} 当前项是:{{item}}
</view>

js里data:

array:[‘第一个’,’第二个’,’第三个’]
2.wx:key
类似于 Vue 列表渲染中的 :key ,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的 key 值,从而提高渲染的效率,示例代码:
arrays:[
      {id:1,name:’aaa’},
      {id:2,name:’bbb’},
      {id:3,name:’ccc’},
    ]
<view wx:for=”{{arrays}}” wx:key=”id”>{{item.name}}</view>

微信小程序示例:条件渲染

2022-04-21 10:14:49
swq1822677238

1.wx:if

在小程序中,使用 wx:if=”{{condition}}” 来判断是否需要渲染该代码块

在 data里 设置属性 sex: 1

<view wx:if=”{{sex==0}}”>男</view>
<view wx:else>女</view>
2.结合 <block> 使用 wx:if
如果要使用一次性控制多个组件的展示与隐藏,可以使用一个 <block></block> 标签将多个组件包装起来,并在 <block> 标签上使用 wx:if 控制属性

true显示,false隐藏

<block wx:if=”{{true}}”>
  <view>男</view>
  <view>女</view>
</block>
3.hidden
在 data里 设置属性 type 为 true
<view hidden=”{{type}}”>条件为true则隐藏</view>

微信小程序示例:bindinput 语法格式

2022-04-21 10:00:07
swq1822677238

通过 bindinput 可以为文本框绑定输入事件

<input bindinput=”inputHeadler”></input>
inputHeadler(e){
    console.log(e.detail.value)
  },
实现文本框和 data 之间的数据同步
<input value=”{{msg}}” bindinput=”inputHeadler”></input>
data里设置 msg 变量
inputHeadler(e){
    //console.log(e.detail.value)
    this.setData({
      msg: e.detail.value
    })
  },