利用websocket實現微信二維碼碼掃碼支付


       由於業務需要引入微信掃碼支付,故利用websocket來實現消息推送技術。

       實現大致流程:首先客戶端點擊微信支付按鈕,觸發微信支付接口,同時微信支付響應成功參數后,連接websocket客戶端,此刻利用微信支付返回的參數生成一個二維碼彈框,此時連接websocket

客戶端時會發送一個指定的消息內容,然后等待用戶掃碼支付完成后,微信支付異步通知的地方執行websocket消息推送,根據指定的消息內容,獲取到websocketsession,然后對其進行消息推送,等客戶

端接收到消息之后,即可執行二維碼的關閉操作及成功跳轉至商戶頁面等。

  既然要利用一門技術來實現業務需求,必定要先了解其技術的原理,及這門技術用於解決什么問題。

  在項目中,常規都是前端向后端發送請求后,才能獲取到后端的數據。但是在一些及時消息的處理上,這樣的處理效率有些捉襟見肘;在以往獲得即時數據時,比較low的方案就是ajax輪詢查詢,或者可以使用socket的長連接;但是這些在實際的操作上都比較消耗資源;而websocket在這方面有效的解決這個問題--WebSocket協議是基於TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端,客戶端接收到消息可即時對消息進行處理,一些三方推送平台也提供了更為完善的消息推送技術如:GoEasy

 第一步:搭建一個簡易的springmvc的工程了

引入如下依賴

<dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.1.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.1.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.1.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.1.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>4.1.6.RELEASE</version>
    </dependency>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
      <version>4.1.6.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.47</version>
    </dependency>
  </dependencies>

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
  <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>
        

配置springmvc

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <context:component-scan base-package="com.test.*"></context:component-scan>
    <mvc:annotation-driven></mvc:annotation-driven>

    <mvc:resources location="/js/" mapping="/js/**" />
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
    </bean>
</beans>

工程目錄如下

核心代碼

package com.test.controller;

import com.test.websocket.MyHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Created by edison on 2019/1/13.
 */
@Controller
@RequestMapping("/index")
public class IndexController {

    @Autowired
    private MyHandler myHandler;
    //返回字符串
    @ResponseBody
    @RequestMapping(value ="/notice",produces="text/html;charset=UTF-8")
    public String notice(String outTradeNo){
        myHandler.sendMessageToUser(outTradeNo);
        return "支付成功";
    }


//返回jsp視圖
    @RequestMapping(value ="/pay")
    public String index(Model model) {
        model.addAttribute("name", "模擬支付頁面展示");
        return "index";
    }
}
<%--
  Created by IntelliJ IDEA.
  User: edison
  Date: 2019/1/13
  Time: 18:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${name}
</body>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript">
    $(function() {
        console.log("模擬支付開始");
        //假設微信返回的交易流水號是1234
        var outTradeNo = "1234";
        console.log("模擬調用支付返回參數結束");
        var ws = new WebSocket("ws://localhost:8080/websocket/myHandler")
        ws.onopen = function () {
            console.log("開始連接服務端websocket");
            var createobj = {}
            createobj.action = "create";
            createobj.outTradeNo = outTradeNo;
            ws.send(JSON.stringify(createobj));
        }
        ws.onclose = function () {
            console.log("onclose");
        }

        ws.onmessage = function (msg) {
            console.log(msg.data);
            var closeobj = {}
            closeobj.action = "remove";
            closeobj.outTradeNo = outTradeNo;
            ws.send(JSON.stringify(closeobj));
        }
    })
</script>
</html>

模擬步驟一

首先訪問模擬支付url

 

 其次再模擬異步回調

最終發現模擬支付頁面成功收到了異步回調,打印關閉二維碼的操作,同時再向服務端發送消息,移除掉map里面的連接

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM