webSocket implementation of code scanning login

Note: you must have spring 4.0 or above to integrate websocket

Three interfaces are designed to realize code scanning login, two of which are HTTP protocol

http interface 1 get QR code picture

/**
	 * 
	 * @Title:Get QR code picture
	 * @Description:Comment for non-overriding methods
	 * @author Zato-One
	 * @date 2018 1:57:44 p.m., March 5, 2010
	 * @param wsSessionId
	 *            websocket Session id (notification page login successful connection)
	 * @param request
	 */
	@RequestMapping("getQrCodeImg")
	public void getQrCodeImg(String wsSessionId, HttpServletRequest request, HttpServletResponse response) {
		// http://www.lhzsports.com:80/LoginMS/qrLogin?appid=?&json={"data":[{ED:"rigour2046"}]}
		try {
			String serverUrl = ServerUtil.getServerUrl(request);
			String qrLoginUrl = serverUrl + "/qrCodeLogin";// http://192.168.1.102:8080/ssoServer/auth/qrCodeLogin
			qrLoginUrl += "?appid=?";
			String clientId = wsSessionId == null ? request.getSession().getId() : wsSessionId;
			qrLoginUrl += "&json={\"data\":[{ED:\"" + clientId + "\"}]}";//The generated QR code has data, but there is no data layer when APP sends verification, which is embarrassing
			// http://192.168.1.102:8080/ssoServer/auth/qrCodeLogin?appid=?&json={"data":[{ED:"B49FBCF0B12A06899BF338F9ACE0CC52"}]}
			logger.debug("Scanning login address:" + qrLoginUrl);
			// Code used for content (code must be specified if there is Chinese)
			Map<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
			hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
			try {
				BitMatrix bitMatrix = new MultiFormatWriter().encode(qrLoginUrl, BarcodeFormat.QR_CODE, 200, 200,
						hints);
				EWCodeUtil.writeToStream(bitMatrix, "jpg", response.getOutputStream());
			} catch (WriterException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

Among them, QR code tools:


		<!-- QR code dependency -->
		<dependency>
			<groupId>com.google.zxing</groupId>
			<artifactId>core</artifactId>
			<version>3.3.0</version>
		</dependency>
package rg.sso.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
/**
 * QR code tools
 * @Title:EWCodeUtil
 * @Description:Comment for created type
 * @author Zato-One
 * @date 2016-12-13 03:00:33 PM
 * @version 1.0
 */
public class EWCodeUtil {
	private static final int BLACK = 0Xff000000;
	private static final int WHITE = 0xffffffff;

	public EWCodeUtil() {

	}

	public static BufferedImage toBufferedImage(BitMatrix matrix) {
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
			}
		}
		return image;
	}

	/**
	 * 
	 * @param matrix Byte array
	 * @param format Picture format
	 * @param file Picture file (incoming file name, path)
	 * @throws IOException
	 */
	public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		if (!ImageIO.write(image, format, file)) {
			throw new IOException("Could not write an image of format " + format + " to " + file);
		}
	}
	/**
	 * 
	 * @param matrix Byte array
	 * @param format Picture format
	 * @param stream Picture file stream
	 * @throws IOException
	 */
	public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		if (!ImageIO.write(image, format, stream)) {
			throw new IOException("Could not write an image of format " + format);
		}
	}

	public static void main(String[] args) {
		try {
			String content = "http://jingyan.baidu.com/article/915fc4149e1f9a51394b2007.html";

			// String path = "D:";
			String path = "D:/";
			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
			Map<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
			// Code used for content (code must be specified if there is Chinese)
			hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
			BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 200, 200, hints);
			// Generate QR code
			File outputFile = new File(path, "Zato-One.jpg");
			EWCodeUtil.writeToFile(bitMatrix, "jpg", outputFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

http interface 2 APP sends authentication login information

 

/**
	 * 
	 * @Title:QR code login interface
	 * @Description:APP Request server QR code login interface after scanning
	 * @author Zato-One
	 * @date 2018 March 5, 2010 10:38:57 am
	 * @param userid
	 *            User primary key
	 * @param secretType
	 *            Key type: 1: mobile number 2: email
	 * @param secretKey
	 *            Secret key Userid + mobile number / md5 of mailbox
	 * @param equipId
	 *            Device number, unique identification of QR code (return from QR code)
	 * @return
	 */
	//http://192.168.1.110:8080/ssoServer/auth/qrCodeLogin?appid=8a7d0ec2c8184d2aad329c55259bdee4&json={ED:"111111",userid:"00126ac4091749fe8da5e6745d155e7a"}
	@RequestMapping("qrCodeLogin")
	public void qrCodeLogin(String appid, String json, HttpServletRequest request, HttpServletResponse response) {
		response.setHeader("Content-type", "text/html;charset=UTF-8");  
		// TODO about appid login channel is not handled temporarily
		
		try {
			// Parsing json parameters
			ServletOutputStream outputStream = response.getOutputStream();
			
			JSONObject jsonObject = JSONObject.parseObject(json);
			if (json==null||jsonObject==null) {
				//Because the APP has completed intelligent receiving of information in this format, the returned classes will not be repackaged separately here
				outputStream.write("{success:false,msg:'json Can not be empty'}".getBytes());
				outputStream.flush();
				outputStream.close();
				return;
			}
			String userid = jsonObject.getString("userid");
			String ED = jsonObject.getString("ED");

			if (StringUtil.isEmpty(ED)) {
				outputStream.write("{success:false,msg:'ED Can not be empty'}".getBytes());
				outputStream.flush();
				outputStream.close();
				return;
			}
			if (StringUtil.isEmpty(userid)) {
				outputStream.write("{success:false,msg:'userId Can not be empty'}".getBytes());
				outputStream.flush();
				outputStream.close();
				return;
			}
			// Save user to http session
			User user = userService.selectUserById(userid);
			if (user==null) {
				outputStream.write("{success:false,msg:'user Non-existent'}".getBytes());
				outputStream.flush();
				outputStream.close();
				return;
			}
			request.getSession().setAttribute("user", user);
			// [push] notice page Jump
			Msg4Ws<Boolean> msg4Ws = new Msg4Ws<Boolean>(10001, "Login successfully", true);
			String message = new ObjectMapper().writeValueAsString(msg4Ws); // Turn to json
			websocketHandler.sendMsgToUser(ED.toString(), new TextMessage(message));
			logger.info("Push sent successfully");

			// Return to mobile terminal
			outputStream.write("{success:true,msg:'Verify success'}".getBytes());
			outputStream.flush();
			outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

[key] websocket interface

<!-- spring-websocket -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-websocket</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-messaging</artifactId>
		</dependency>

Add xsd reference to beans tag attribute in spring's configuration file header:

xmlns:websocket="http://www.springframework.org/schema/websocket"

Sum

http://www.springframework.org/schema/websocket 
http://www.springframework.org/schema/websocket/spring-websocket.xsd

After adding:

Then add the websocket configured node in the beans tab of the configuration file:

<!-- websocket -->
    <bean id="websocket" class="rg.sso.websocket.handler.WebsocketHandler"/>  
    <websocket:handlers allowed-origins="*">  
        <websocket:mapping path="/websocket" handler="websocket"/>  
        <websocket:handshake-interceptors>  
            <bean class="rg.sso.websocket.HandshakeInterceptor"/>  
        </websocket:handshake-interceptors>  
    </websocket:handlers>

Description: the WebsocketHandler class is a class for processing messages,

HandshakeInterceptor is a handshake interceptor

path="/websocket" indicates the request path

"Allowed origins" * "means that any IP domain name is allowed to access

HandshakeInterceptor class:

package rg.sso.websocket;

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;
/**
 * 
 * @Title:HandshakeInterceptor Handshake interceptor
 * @Description:Comment for created type
 * @author Zato-One
 * @date 2018 2:31:35 PM, March 5, 2015
 * @version 1.0
 */
public class HandshakeInterceptor 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);
	}
}

 

WebsocketHandler class:

package rg.sso.websocket.handler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * 
 * @Title:WebsocketEndPoint Message processing root class
 * @Description:Comment for created type
 * @author Zato-One
 * @date 2018 March 5, 2008 2:31:48 PM
 * @version 1.0
 */
public class WebsocketHandler extends TextWebSocketHandler {
	private static Logger logger = LoggerFactory.getLogger(WebsocketHandler.class);
	// Save all user session s
	private static Map<String, WebSocketSession> SESSION_MAP = new HashMap<String, WebSocketSession>();

	// process information
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		//super.handleTextMessage(session, message);
		String msgStr = message.getPayload();
		logger.info("Message received:" + message);
		logger.info("Received message content:" + msgStr);
		String resultMsg = msgStr + " received at server";
		logger.info("Return information:" + resultMsg);
		TextMessage returnMessage = new TextMessage(resultMsg);
		session.sendMessage(returnMessage);
	}

	// When the connection is ready
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		logger.debug("[{} : {}] has be connected...", session.getUri(), session.getId());
		SESSION_MAP.put(session.getId(), session);
		logger.info("Return id");
		TextMessage returnMessage = new TextMessage("wsSessionId:"+session.getId());
		session.sendMessage(returnMessage);
	}

	// When the connection is closed
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		logger.debug("[{} : {}]", session.getUri(), session.getId());
		SESSION_MAP.remove(session.getId());
	}

	// Exception processing transfer
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		// TODO Auto-generated method stub
		super.handleTransportError(session, exception);
	}

	// Local message support
	@Override
	public boolean supportsPartialMessages() {
		// TODO Auto-generated method stub
		return super.supportsPartialMessages();
	}

	/**
	 * 
	 * @Title:Push messages to all users
	 * @Description:Comment for non-overriding methods
	 * @author Zato-One
	 * @date 2018 3:47:50 PM, March 5, 2015
	 * @param message
	 * @throws Exception
	 */
	public void sendMsgToAllUsers(WebSocketMessage<?> message) throws Exception {
		for (WebSocketSession user : SESSION_MAP.values()) {
			user.sendMessage(message);
		}
	}

	/**
	 * @Title:Push a message to a user
	 * @Description:Comment for non-overriding methods
	 * @author Zato-One
	 * @date 2018 3:47:32 PM, March 5, 2010
	 * @param wsSessionId
	 * @param message
	 * @throws IOException
	 */
	public void sendMsgToUser(String wsSessionId, WebSocketMessage<?> message) throws IOException {
		WebSocketSession session = SESSION_MAP.get(wsSessionId);
		if (session == null) {
			throw new RuntimeException("Corresponding sessionid(" + wsSessionId + ")Of session Non-existent");
		}
		session.sendMessage(message);
	}
}

In this way, when tomcat starts, websocket starts listening for client connections.

Front end test page:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ws test</title>
</head>
<body>
<div class="wrapper">
  <header>
    <span class="title-txt">Robot customer service</span>
  </header>
  <ul id="chatLog">

  </ul>
  <footer>
    <input type="text" id="msg" placeholder="Please enter information...">
    <button id="btnSend">Send out</button><button id="btnClose">Close</button>
  </footer>
</div>
<script>
//	var url = "ws://192.168.1.102:8080/ssoServer/websocket";
//  var url = "ws://192.168.1.110:8080/ssoServer/websocket";
  var url = "ws://localhost:8080/ssoServer/websocket";
  
  //var ws = new WebSocket(url);
  var msgDom = document.getElementById('msg');
  var btnSend = document.getElementById('btnSend');
  var btnClose = document.getElementById('btnClose');
  var chatLog = document.getElementById('chatLog');
  var ws = new WebSocket(url);

  ws.addEventListener('open', function (ev) {
    ws.send('Hello');
    console.log('collected');
  });


  ws.onmessage = function(evt) {
    console.log( "Received Message: " + evt.data);
   // ws.close();
  };

</script>
</body>
</html>

Tags: Session Java JSON socket

Posted on Sun, 05 Apr 2020 03:02:06 -0700 by johnnyboy16