spring-mvc+spring-websocket+mysql+mybits实现二维码注册

所需jar包
<!--spring-websocket-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>4.3.20.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>4.3.20.RELEASE</version>
</dependency>
<!-- google 的二维码写人jar-->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.2.1</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.2.0</version>
</dependency>

 

package com.bsd.hy.module.webSocketServet;

import java.io.Serializable;

public class Msg4Ws<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private int code;//消息编号
    private String msg;//消息描述
    private T data;//消息实体

    public Msg4Ws(int code) {
        this.code = code;
    }

    public Msg4Ws(int code, T data) {
        this.code = code;
        this.data = data;
    }

    public Msg4Ws(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Msg4Ws(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
package com.bsd.hy.module.webSocketServet;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.*;
@Service
public class MyHandler extends TextWebSocketHandler {
    private Logger logger = LoggerFactory.getLogger(MyHandler.class);
    // 保存所有的用户session
    private static final Map<String, WebSocketSession> users;

    static {
        users = new HashMap<>();
    }

    /**
     * 连接 就绪时
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.debug("[{} : {}] has be connected...", session.getUri(), session.getId());
        users.put(session.getId(), session);
        System.out.println(session);
        logger.info("返回id");
        Msg4Ws<String> msg4Ws=new Msg4Ws<String>(10000, "ws的sessionId", session.getId());
        // 转为json
        String message = new ObjectMapper().writeValueAsString(msg4Ws);
        TextMessage returnMessage = new TextMessage(message);
        session.sendMessage(returnMessage);
    }

    /**
     * 处理信息
     * @param session
     * @param message
     * @throws IOException
     */
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        String msgStr = message.getPayload();
        logger.info("收到消息:" + message);
        logger.info("收到消息内容:" + msgStr);
        String resultMsg = msgStr + " received at server";
        logger.info("返回信息:" + resultMsg);
        TextMessage returnMessage = new TextMessage(resultMsg);
        session.sendMessage(returnMessage);
    }

    /**
     * 处理传输时异常
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);
    }

    /**
     *  关闭 连接时
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        logger.debug("[{} : {}]", session.getUri(), session.getId());
        users.remove(session.getId());
    }

    @Override
    public boolean supportsPartialMessages() {
        return super.supportsPartialMessages();
    }
    /**
     *  发送信息给指定用户
     * @param userid
     * @param message
     * @throws IOException
     */
    public void  sendMessageToUser(String userid, TextMessage message) throws IOException {
        WebSocketSession session = users.get(userid);
        if (session == null) {
            throw new RuntimeException("对应sessionid(" + userid + ")的session不存在");
        }
        session.sendMessage(message);
    }

    /**
     * 向所有用户推送消息
     * @param message
     * @throws IOException
     */
    public void  sendMessageToAllUsers(TextMessage message) throws IOException {
        for (WebSocketSession user : users.values()) {
            user.sendMessage(message);
        }
    }
}
package com.bsd.hy.module.webSocketServet;

import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

public class MyWebSocketConfig extends HttpSessionHandshakeInterceptor{

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        System.out.println("Before Handshake");
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception ex) {
        System.out.println("After Handshake");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
package com.bsd.hy.module.wechat;

import com.bsd.hy.module.user.model.HyUser;
import com.bsd.hy.module.user.service.UserService;
import com.bsd.hy.module.webSocketServet.Msg4Ws;
import com.bsd.hy.module.webSocketServet.MyHandler;
import com.bsd.hy.util.http.HttpsUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.socket.TextMessage;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock;

import static com.bsd.hy.module.wechat.WechatString.APP_ID;
import static com.bsd.hy.module.wechat.WechatString.APP_SECRET;

/**
 * 调用微信授权登录的接口
 * step1 拼接授权url,url 如下:
 *      state=key1 (长度为5) 创建厂家        state=key2 (长度为6) 创建经销商       state=c  普通用户授权登录
 * https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe3a25a1e6b280c17&redirect_uri=http://23s60z8662.iask.in/wechat/step2&response_type=code&scope=snsapi_userinfo&state=dealer#wechat_redirect
 * https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe3a25a1e6b280c17&redirect_uri=http://23s60z8662.iask.in/wechat/step2&response_type=code&scope=snsapi_userinfo&state=factory#wechat_redirect
 * https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe3a25a1e6b280c17&redirect_uri=http://23s60z8662.iask.in/wechat/step2&response_type=code&scope=snsapi_userinfo&state=dealerfactory#wechat_redirect
 * step2 用户点击授权链接后的回调处理
 * step3 拉取用户信息
 */
@Controller
@RequestMapping("/wechat")
public class WechatAuthController {
    private static final ReentrantLock LOCK = new ReentrantLock();
    private static final Logger LOGGER = LoggerFactory.getLogger(WechatAuthController.class);
    @Autowired
    private UserService userService;
    @Autowired
    private MyHandler myHandler;
    private HttpSession session;
    /**
     * Method of obtaining a QR code
     */
    @RequestMapping("/step1")
    private void getobtainingQRcode(String type, HttpServletResponse response) throws Exception {
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APP_ID +
                "&redirect_uri=http://23s60z8662.iask.in/wechat/step2&" +
                "response_type=code&scope=snsapi_userinfo&state=" + type + "#wechat_redirect";
        ServletOutputStream stream = null;
        try {
            int width = 350;
            int height = 350;
            stream = response.getOutputStream();
            QRCodeWriter writer = new QRCodeWriter();
            BitMatrix m = writer.encode(url, BarcodeFormat.QR_CODE, height, width);
            MatrixToImageWriter.writeToStream(m, "png", stream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.flush();
                    stream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * step2 用户点击授权链接后的回调处理
     */
    @RequestMapping("/step2")
    public String callback(String code, String state,HttpServletRequest request) {
        // 获取access_token的链接
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                + APP_ID + "&secret=" + APP_SECRET + "&code=" + code + "&grant_type=authorization_code";
        try {
            session=request.getSession();
            LOCK.lock();
            String result = HttpsUtil.get(url);
            if (result == null) return "forward:/404.jsp"; // 获取数据失败
            JSONObject json = new JSONObject(result);
            String openId = json.getString("openid");
            String accessToken = json.getString("access_token");
            String[] strs = state.split("_");
            session.setAttribute("openId", openId);
            session.setAttribute("accessToken", accessToken);
            session.setAttribute("state", state);
            if (strs[0].toString().equals("dealer")) {
                session.setAttribute("type", 1);
            } else if (strs[0].toString().equals("factory")) {
                session.setAttribute("type", 2);
            } else {
                session.setAttribute("type", 0);
            }
            return "forward:/view/user/index.jsp";
        } catch (Exception ex) {
            LOGGER.error("/微信授权错误/");
            session.setAttribute("message", "授权失败,请重试");
            return "forward:/404.jsp";
        } finally {
            LOCK.unlock();
        }
    }

    /**
     * step3 拉取用户信息
     * {
     * "openid":" OPENID",
     * "nickname": NICKNAME,
     * "sex":"1",
     * "province":"PROVINCE"
     * "city":"CITY",
     * "country":"COUNTRY",
     * "headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
     * "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
     * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     * }
     * 以上信息皆可以拉取
     * <p>
     * 获取用户信息后,保存到数据库,在shiro加密过程中,openid 为shiro的username,
     * 以openid 为salt,进行 11 次加密,得到加密后的password
     */
    @RequestMapping("/step3")
    public String getUserInfo(HttpServletRequest request) throws Exception {
        session = request.getSession();
        String accessToken = session.getAttribute("accessToken").toString();
        String openId = session.getAttribute("openId").toString();
        int type = (int) session.getAttribute("type");
        String state = session.getAttribute("state").toString(); ;
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token="
                + accessToken + "&openid=" + openId + "&lang=zh_CN";
        String result = HttpsUtil.get(url);
        if (result == null) return null;
        JSONObject json = new JSONObject(result);
        HyUser hyUser = new HyUser();
        hyUser.setOpenId(openId);
        hyUser.setNickname(json.getString("nickname"));
        hyUser.setSex(json.getInt("sex"));
        hyUser.setProvince(json.getString("province"));
        hyUser.setCity(json.getString("city"));
        hyUser.setCountry(json.getString("country"));
        hyUser.setHeadimgurl(json.getString("headimgurl"));
        hyUser.setType(type);
        HyUser user = userService.getUserByOpenId(openId);
        if (user == null) {
            hyUser.setType(type);
            int user_id = userService.insertUser(hyUser);
        } else if (user.getType() == type) {
            hyUser.setType(type);
            int user_id = userService.update(hyUser);
        } else {
            hyUser.setType(3);
            int user_id = userService.update(hyUser);
        }
        String[] strs = state.split("_");
        if (type == 1) {
            //PC端的用户请求
            Msg4Ws<Boolean> msg4Ws = new Msg4Ws<Boolean>(10001, "/wechat/adddealer", true);
            /*json转换*/
            String message = new ObjectMapper().writeValueAsString(msg4Ws);
            myHandler.sendMessageToUser(strs[2], new TextMessage(message));

            return "forward:/view/user/add_dealer.jsp";
        } else if (type == 2) {
            //PC端的用户请求
            Msg4Ws<Boolean> msg4Ws = new Msg4Ws<Boolean>(10001, "/wechat/addfactory", true);
            /*json转换*/
            String message = new ObjectMapper().writeValueAsString(msg4Ws);
            myHandler.sendMessageToUser(strs[2], new TextMessage(message));

            return "forward:/view/user/add_factory.jsp";
        } else {
            return "/404.jsp";
        }
    }

    @RequestMapping("/adddealer")
    public String adddealer(){
        return "/view/user/add_dealer.jsp";
    }
    @RequestMapping("/addfactory")
    public String tttt(){
        return "/view/user/add_factory.jsp";
    }
}

前端代码

dealer.jsp

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%
   String base_path = request.getContextPath();
%>
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title></title>
      <link type="text/css" rel="stylesheet" href="<%=base_path%>/base/plugins/layui/css/layui.css" />
      <style type="text/css">
         .ad_img{
            width: 256px;
            margin: auto;
         }
         h3{
            text-align: center;
         }
      </style>
   </head>
   <body>
   <div class="layui-form-item" style="text-align:center; padding-top:10%">
      <div class="ad_img" id="erweima" >
         <h1>经销商授权码</h1>
         <img id="qrcode" src="" alt="">
      </div>
   </div>
      <script type="text/javascript" src="<%=base_path%>/js/jquery-3.3.1.min.js" charset="utf-8"></script>
      <script type="text/javascript" src="<%=base_path%>/layer/layer.js"></script>
      <script type="text/javascript" src="<%=base_path%>/base/plugins/layui/layui.js" charset="utf-8"></script>
      <script type="text/javascript" src="<%=base_path%>/js/global.js" charset="utf-8"></script>
   <script type="text/javascript">
      function randomString(len) {
         len = len || 32;
         var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz';
         var maxPos = $chars.length;
         var pwd = '';
         for (i = 0; i < len; i++) {
            pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
         }
         return pwd;
      }
      var str = randomString(32);

      /*首次进入js自动加载二维码*/
      $(function(){
         $("#qrcode").attr("src","<%=base_path%>/wechat/step1?type=dealer_"+str);
      });

      window.setInterval(function() {
         $("#qrcode").attr("src","<%=base_path%>/wechat/step1?type=dealer_"+str);
      }, 300000);

        var ws = null;
        if (WebSocket) {
            ws = new WebSocket("ws://localhost/websocket"); // 建立通道
        } else {
            alert("浏览器不支持websocket");
        }

      ws.addEventListener('open', function(ev) {
         console.log('websocket已经连接');
         ws.send('Hello');
      });

      ws.onmessage = function(evt) {
         console.log("Received Message: " + evt.data);
         //{"code":10001,"msg":"登录成功","data":true}
         var json = evt.data;
         var hasCode = json.match("code");
         if (hasCode == null) {
            return;
         }
         var dataObj = eval("(" + json + ")");
         var code = dataObj.code;
         console.log("code=" + code);

         if (code == 10000) {
            $("#qrcode").attr("src",
                  "<%=base_path%>/wechat/step1?type=factory_"+str+"_"+ dataObj.data);
         } else if (code == 10001) {
            ws.close();
            window.location.href=dataObj.msg;
         }
      };
   </script>
   </body>

</html>

factory.jsp

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%
   String base_path = request.getContextPath();
%>
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title></title>
      <link rel="stylesheet" type="text/css" href="<%=base_path%>/base/plugins/layui/css/layui.css" />
      <style type="text/css">
         .ad_img{
            width: 256px;
            margin: auto;
         }
         h1{
            text-align: center;
         }
      </style>
   </head>
   <body>
   <div class="layui-form-item" style="text-align:center; padding-top:10%">
      <div class="ad_img" id="erweima" >
         <h1>经销商授权码</h1>
         <img id="qrcode" src="" alt="">
      </div>
   </div>
      <script type="text/javascript" charset="utf-8" src="<%=base_path%>/js/jquery-3.3.1.min.js"></script>
      <script type="text/javascript" src="<%=base_path%>/layer/layer.js"></script>
      <script type="text/javascript" charset="utf-8" src="<%=base_path%>/base/plugins/layui/layui.js"></script>
      <script type="text/javascript" charset="utf-8" src="<%=base_path%>/js/global.js"></script>
      <script>
         function randomString(len) {
            len = len || 32;
            var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz';
            var maxPos = $chars.length;
            var pwd = '';
            for (i = 0; i < len; i++) {
               pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
            }
            return pwd;
         }
         var str = randomString(32);

         var ws = null;
         if (WebSocket) {
            ws = new WebSocket("ws://localhost/websocket"); // 建立通道
         } else {
            alert("浏览器不支持websocket");
         }

         ws.addEventListener('open', function(ev) {
            console.log('websocket已经连接');
            ws.send('Hello');
         });

         ws.onmessage = function(evt) {
            console.log("Received Message: " + evt.data);
            var json = evt.data;
            var hasCode = json.match("code");
            if (hasCode == null) {
               return;
            }
            var dataObj = eval("(" + json + ")");
            var code = dataObj.code;
            console.log("code=" + code);
            if (code == 10000) {
               $("#qrcode").attr("src",
                     "<%=base_path%>/wechat/step1?type=factory_"+str+"_"+ dataObj.data);
            } else if (code == 10001) {
               ws.close();
               window.location.href=dataObj.msg;
            }
         };
      </script>
   </body>

</html>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%
    String base_path = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/weui/1.1.3/style/weui.min.css">
    <link rel="stylesheet" href="https://cdn.bootcss.com/jquery-weui/1.2.1/css/jquery-weui.min.css">
</head>
<body>
<div class="weui-msg">
    <div class="weui-msg__icon-area"><i class="weui-icon-info weui-icon_msg"></i></div>
    <div class="weui-msg__text-area">
        <h2 class="weui-msg__title">授权登录</h2>
        <p class="weui-msg__desc">
            获取你的公开信息(昵称、头像等)
        </p>
    </div>
    <div class="weui-msg__opr-area">
        <p class="weui-btn-area">
            <a href="javascript:dexe()" class="weui-btn weui-btn_primary">确认授权</a>
        </p>
    </div>
</div>
</body>
<script src="https://cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-weui/1.2.1/js/jquery-weui.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-weui/1.2.1/js/swiper.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-weui/1.2.1/js/city-picker.min.js"></script>
<script type="text/javascript" charset="utf-8" src="<%=base_path%>/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    function dexe() {
        $.ajax({
            type: "get",
            data:{},
            url: '<%=base_path%>/wechat/step3',
            success: function (page) {
                alert("授权成功");
            },
            error: function () {
                alert("授权失败");
            }
        });
    }
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值