公众号开发(四)----接收事件推送之扫描带参数二维码事件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w_t_y_y/article/details/86668690

接着前面的博客进度。如现在再把扫描带参数二维码进入公众号的用户保存到数据库

一、临时二维码:

获取二维码需要先获取ticket,再用ticket来换图片。这里请求参数比较短,就不封装对象了,直接使用字符串拼接成json串。

1、方法一、使用scene_id获取ticket,建议使用这种方法:

(1)、先生成二维码加一张背景图的图片:

WechatUtil:

//生成临时二维码ticket scene_id json
private static final String QRCODE_TEMPORARY_TICKET_SCENE_ID = "{\"expire_seconds\": SECONDS, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": SCENEID}}}";
	
//生成临时二维码ticket scene_str json
private static final String QRCODE_TEMPORARY_TICKET_SCENE_STR = "{\"expire_seconds\": SECONDS, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": SCENESTR}}}";
	
//生成临时二维码ticket 的url
private static final String QR_TEMPORARY_TICKET_URL= "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
	


//使用scene_id生成临时二维码ticket
public static QrTicket getTemporaryQRTicketBySceneId(String appId, String appSecert,
			Long expireSeconds,  Long sceneId){
		AccessToken accessToken = getAccessToken(appId, appSecert);
		String url = QR_TEMPORARY_TICKET_URL.replace("TOKEN", accessToken.getAccessToken());
		String postJson = QRCODE_TEMPORARY_TICKET_SCENE_ID.replace("SECONDS", String.valueOf(expireSeconds))
				.replace("SCENEID", String.valueOf(sceneId));
		JSONObject res = HttpsUtil.httpRequest(url, "POST", postJson);
		QrTicket qrTicket = new QrTicket();
		qrTicket.setExpireSeconds((Integer) res.get("expire_seconds"));
		qrTicket.setTicket(res.getString("ticket"));
		qrTicket.setUrl("url");
		return qrTicket;
	}





/**
     * 将二维码和背景图片拼装成新的分享图片
     * @param shareImageUrl 分享背景图片的地址
     * @param qrCodeUrl 二维码图片的地址
     * @param content 文字内容
     * @return base64 String 的图片
     */
    public static String getQrImgUrl(String shareImageUrl, String qrCodeUrl, String content) {
        try {
            // 读取背景图片
            BufferedImage bgImage = ImageIO.read(new URL(shareImageUrl));
            // 读取二维码图片
            BufferedImage qrCodeImage = ImageIO.read(new URL(qrCodeUrl));

            // 创建一张原始图片
            BufferedImage bgPicture = new BufferedImage(bgImage.getWidth(null), bgImage.getHeight(null), BufferedImage.TYPE_INT_RGB);

            // 开启画图
            Graphics2D g = bgPicture.createGraphics();
            // 绘制背景图片
            g.drawImage(bgImage, 0, 0, null);
            // 设置目标重叠的混合处理方式和透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
            // 580*790
            int starX = bgImage.getWidth(null) * 45 / 580; // 二维码距背景图片X轴距离
            int startY = bgImage.getHeight(null) * 480 / 790; // 二维码距背景图片Y轴距离
            // 绘制二维码图片
            g.drawImage(qrCodeImage, starX, startY, 124, 124, null);
            // 绘制文字
//            g.setColor(new Color(139,142,147));
//            g.setFont(new Font("微软雅黑", Font.PLAIN, 18));
//            g.drawString(content, starX, startY + 124 + 30);
            g.dispose();

            // 将合成的图片转为base64String
            ByteArrayOutputStream compositeImageByte = new ByteArrayOutputStream();
            ImageIO.write(bgPicture, "png", compositeImageByte);
            //转换成base64串
            String pngBase64 =  new BASE64Encoder().encodeBuffer(compositeImageByte.toByteArray()).trim();
            pngBase64 = "data:image/png;base64," + pngBase64.replaceAll("\n", "").replaceAll("\r", "");

            System.out.println("create base64 image success");
            return pngBase64;
        } catch (Exception e) {
        	System.out.println("create base64 image error");
            return null;
        }
    }	

 controller:


package com.demo.wechat.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.demo.wechat.domain.Message;
import com.demo.wechat.domain.QrTicket;
import com.demo.wechat.util.WebUtil;
import com.demo.wechat.util.WechatUtil;

@Controller
@RequestMapping("/index")
public class ViewController {
	
	@Value(value="${app.secret}")
	private String appSecert;
	
	@Value(value="${app.id}")
	private String appId;

	private Long expireSeconds = 60000000L;

	private Long sceneId = 666L;

	private String backImgUrl = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=977119715,3452693422&fm=26&gp=0.jpg";

	
	//通过ticket获取二维码
	private static final String QR_CODE_URL ="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
		

	
	//根据scene_id生成临时二维码 返回页面
	@GetMapping("/getQrCodeBySceneId")
	public String goQrCodeBySceneId(){
		return "code";
	}	
		
	//根据scene_id生成临时二维码
	@PostMapping("/getQrCodeBySceneId")
	@ResponseBody
	public String getQrCodeBySceneId(){
		QrTicket qrTicket = WechatUtil.getTemporaryQRTicketBySceneId(appId, appSecert, expireSeconds, 
				 sceneId);
		String qrCodeUrl = QR_CODE_URL.replace("TICKET", qrTicket.getTicket());  
		String url = WechatUtil.getQrImgUrl(backImgUrl, qrCodeUrl, "扫描关注");
		System.out.println("结果"+url);
		return url;
	}
}

前端:

applcation.properties设置:

#返回的前缀   目录对应src/main/webapp下
spring.mvc.view.prefix:/WEB-INF/view/
#返回的后缀
spring.mvc.view.suffix: .jsp

code.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="../assets/js/jquery-3.2.1.min.js"></script>
<script>
	$(function(){
		alert("hello");
		$.post("getQrCodeBySceneId",function(data){
			alert(data)
			$("#shareImage").attr('src',data); 
		})
	}
 )
</script>
</head>
<body>
 <div id="shareBody" >
        <img id="shareImage" src="" />
        <!--<canvas id="shareCanvas"></canvas>-->
    </div>
</body>

</html>

在浏览器访问http://localhost:8080/wechat/index/getQrCodeBySceneId

(2)、二维码扫描事件:

/**
	 * 处理微信消息
	 * @param request request
	 * @param reqMsg 请求消息
	 * @param respMsg 回复消息
	 * @param remoteIp remoteIp
	 */
	private void handleMessage(HttpServletRequest request, WechatMsg reqMsg,  String remoteIp){
		String type = reqMsg.getMsgType();
		String fromUserName = reqMsg.getFromUserName();
		String event = reqMsg.getEvent();
		String eventKey = reqMsg.getEventKey();
		//event事件开始
		if(type.equals("event")){
			//关注/取消关注公众号事件
			WechatUser dbWechatUser = wechatUserService.getByOpenId(fromUserName);
			if(dbWechatUser == null){
				//还没有关注过
				System.out.println("还没有关注过");
				WechatUser wechatUser = new WechatUser();
				wechatUser.setCreateTime(new Date());
				wechatUser.setIsDelete(false);
				wechatUser.setUpdateTime(new Date());
				wechatUser.setUserOpenId(fromUserName);
				
				wechatUserService.insert(wechatUser);
			}
			
			//扫描带参数二维码关注事件
			if("subscribe".equals(event) && eventKey.startsWith("qrscene_")){
				//去掉前缀
				Long key = Long.valueOf(eventKey.replace("qrscene_", ""));
				if(sceneId == key || sceneId.equals(key)){
					System.out.println("扫描带参数二维码关注");
					QrCodeUser dbQrCodeUser = qrCodeUserService.getByOpenId(fromUserName);
					if(dbQrCodeUser == null){
						//还没有记录过
						QrCodeUser qrCodeUser = new QrCodeUser();
						qrCodeUser.setCreateTime(new Date());
						qrCodeUser.setIsDelete(false);
						qrCodeUser.setOpenId(fromUserName);
						qrCodeUser.setSceneId(String.valueOf(sceneId));
						qrCodeUser.setUpdateTime(new Date());
						qrCodeUserService.insert(qrCodeUser);
					}
				}
			}
			
			//扫描带参数二维码浏览(已关注)事件
			if("SCAN".equals(event)){
				Long key = Long.valueOf(eventKey);
				if(sceneId == key || sceneId.equals(key)){
					System.out.println(fromUserName+"扫描带参数二维码已经关注");
				}
			}
		}
		//event事件结束
	}

2、方法二、使用scene_str获取ticket。这种方法只有在用户未关注二维码时会把str参数值带过来: 

wechatUtil:

//使用scene_str生成临时二维码ticket
public static QrTicket getTemporaryQRTicketBySceneStr(String appId, String appSecert,
			Long expireSeconds, String sceneStr){
		AccessToken accessToken = getAccessToken(appId, appSecert);
		String url = QR_TEMPORARY_TICKET_URL.replace("TOKEN", accessToken.getAccessToken());
		String postJson = QRCODE_TEMPORARY_TICKET_SCENE_STR.replace("SECONDS", String.valueOf(expireSeconds))
				.replace("SCENESTR", sceneStr);
		JSONObject res = HttpsUtil.httpRequest(url, "POST", postJson);
		QrTicket qrTicket = new QrTicket();
		qrTicket.setExpireSeconds((Integer) res.get("expire_seconds"));
		qrTicket.setTicket(res.getString("ticket"));
		qrTicket.setUrl("url");
		return qrTicket;
	}

controller:

private String scendStr = "test";

//根据scene_str生成临时二维码 返回页面
@GetMapping("/getQrCodeBySceneStr")
	public String goQrCodeBySceneStr(){
		return "codeStr";
	}			
			
	
//根据scene_id生成临时二维码
@PostMapping("/getQrCodeBySceneStr")
	@ResponseBody
	public String getQrCodeBySceneStr(){
		QrTicket qrTicket = WechatUtil.getTemporaryQRTicketBySceneStr(appId, appSecert,
				expireSeconds, scendStr);
		String qrCodeUrl = QR_CODE_URL.replace("TICKET", qrTicket.getTicket());  
		String url = WechatUtil.getQrImgUrl(backImgUrl, qrCodeUrl, "扫描关注");
		System.out.println("结果"+url);
		return url;
	}	

消息:

二、永久二维码

猜你喜欢

转载自blog.csdn.net/w_t_y_y/article/details/86668690