JAVA - 手機掃描二維碼,頁面響應(不是掃碼登入)
我是剛入職幾個月的萌新,這幾個月,遇到了許多沒接觸過的功能,雖然代碼很簡單,但是也曾一時讓我煩惱,思路不通。
為了不讓自己學到的一點新東西忘記,所以,開始寫起了我的第一個部落格。希望能讓協助到需要的人,也可以讓我自己保留這些回憶。
下面放圖。是我需求裡的一個功能,我所在的是公司的OA項目組。
我會把這個功能抽出來,做成一個簡單的demo。
該功能需求:1、掃碼驗證登入;2、如果重新整理頁面,跳過掃碼,直接到“查詢頁面”
這個功能用的是輪詢的方式。應該是叫輪詢(第一次接觸,不清楚)吧。聽說這種方式代碼簡單,但是比較耗效能,如果用的人少,是可以,但是多人就不是很好。
幸運的是,這個功能是給特定的群體用的。
************基於SSM*****************
若需要改成servlet,只需要把每個方法都寫成獨立的servlet即可
上代碼
代碼所需2個jar包的下載地址:http://download.csdn.net/detail/cj_zyz/9821271
CertificationController.java
package com.ssm.controller;import java.io.File;import java.io.IOException;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.MultiFormatWriter;import com.google.zxing.WriterException;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.google.zxing.common.BitMatrix;import com.ssm.pojo.User;/** * Certification 認證 */@Controller@RequestMapping("/certification")public class CertificationController {/** * 步驟一 :跳轉到二維碼頁面<br> * 訪問url:http://localhost:8080/項目名/certification/QRcode * @return */@RequestMapping(value="QRcode")public String form2(HttpServletRequest request) {//每個使用者登入,使用者資訊都會儲存到session裡面,//這個session的id是唯一的,獲得sessionId//判斷是否已經認證過,認證過,跳過二維碼頁面String sessionId = request.getSession(true).getId(); String value = User.getSessionIdMap().get(sessionId);if ( value == null ) {return "QRcode";//跳轉到二維碼頁面進行掃碼} else {return "success";//跳過二維碼頁面,直接成功}}/** * 步驟二 :產生二維碼,並返回二維碼圖片地址 * @return */@RequestMapping(value="getQRcode")@ResponseBodypublic Map<String, String> getQRcode() {int width = 150; // 二維碼圖片寬度 76int height = 150; // 高度 76String format = "jpg"; // 圖片格式//JDK內建的UUID, 通過Random數字產生, 中間無-分割.String uuid = UUID.randomUUID().toString().replaceAll("-", "");//二維碼內容,寫入uuid,可以讓手機掃描後把uuid傳到後台String content = "uuid=" + uuid;Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");BitMatrix bitMatrix = null;try {// 編碼bitMatrix = new MultiFormatWriter().encode(content,BarcodeFormat.QR_CODE, width, height, hints);} /*catch (WriterException e1) {}*/catch (Exception e1) {e1.printStackTrace();}String fileName = "QRcode.png";//絕對路徑,把產生的二維碼放到 C盤 根目錄下String path = "C:/" + fileName;//相對路徑,用於顯示圖片String photo = path;File outputFile = new File(path);if (!outputFile.exists() && !outputFile.isDirectory()) {outputFile.mkdirs();}try {// 輸出二維碼圖片MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);} catch (IOException e) {e.printStackTrace();}Map<String, String> map = new HashMap<>();map.put("photo", photo);map.put("uuid", uuid);return map;}/** * 步驟三 :二維碼頁面 ajax 迴圈調用這個方法 * @return 1成功,0失敗 */@RequestMapping(value="login")@ResponseBodypublic Integer login(String uuid, HttpServletRequest request) {int count = 1;boolean result = true;while (true) {try {Thread.sleep(1000);//睡眠1秒} catch (InterruptedException e) {e.printStackTrace();}System.out.println("頁面傳遞的uuid : " + uuid);// 檢測登入,檢測手機是否已掃碼String value = User.getLoginUserMap().get(uuid);if ( value != null ) {result = true;//認證成功//把認證成功的sessionId儲存起來String sessionId = request.getSession(true).getId(); User.getSessionIdMap().put(sessionId, "這裡隨便填,只是用於判斷是否為null而已");break;} else {if (count == 5) {result = false;//認證失敗,未掃描二維碼break;}}//end if..elsecount++;//計數+1}//end whilereturn result ? 1 : 0;}/** * 步驟四 : 手機掃描二維碼後,<br> * 調用 appScanner 介面,並傳遞uuid */@RequestMapping(value="appScanner")@ResponseBodypublic String appScanner(String uuid) {System.out.println("手機端傳遞的uuid : " + uuid);//將uuid存入mapString value = User.getLoginUserMap().get(uuid);if( value == null ){ User.getLoginUserMap().put(uuid, "隨便給值,該值只做非空判斷"); } //給手機端返回認證成功訊息,雖然還沒真正驗證,但是告訴手機端已經掃碼了 return "認證成功";}/** * 清空 getSessionIdMap * @return */@RequestMapping(value="clear")public String clear() {User.getSessionIdMap().clear();return "redirect:QRcode";}}
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;%> <c:set var="base" value="<%=basePath %>"/> <html><head><title></title></head><body><h1><a href="${base }/certification/QRcode">認證(跳轉到二維碼頁面)</a></h1><h1><a href="${base }/certification/clear">清空儲存Session的Map</a></h1></body></html>
QRcode.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;%> <c:set var="base" value="<%=basePath %>"/> <c:set var="ctx" value="${pageContext.request.contextPath}"/> <html><head><title></title><script type="text/javascript" src="${ctx }/jquery/jquery-1.8.3.js"></script><script type="text/javascript">$(document).ready(function() {//步驟二 : 頁面載入完後ajax請求產生二維碼圖片var uuid;$.ajax({type:"post",url:"${base }/certification/getQRcode",success:function(data) {//儲存UUIDuuid = data.uuid;//顯示二維碼,chrome出於安全機制,不能訪問本地檔案,打不開圖片//可以把photo放到瀏覽器的地址欄訪問。圖片會顯示var photo = 'file:///' + data.photo;$("#QRcode").attr("src",photo);//開始驗證登入login();}});//步驟三 : 驗證登入,發送uuid,迴圈調用function login() {$.ajax({type:"post",url:"${base }/certification/login",data:{uuid:uuid},success:function(result) {if (result == 1) {window.location.href = "${base }/certification/QRcode";//跳到認證成功頁面} else {login();//如果沒有認證不成功,繼續調用}}});}});</script></head><body><!-- 顯示二維碼圖片 --><img id="QRcode" src="" style="width: 200px; height: 200px;" /></body></html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><html><head></head><body><h1>認證成功</h1></body></html>