wechat-0050,微信公众号,带参数的二维码获取与扫码事件推送

获取二维码

1. 二维码类型

临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景

永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。

2. 获取带参数的二维码的过程包括两步,首先创建二维码ticket,然后凭借ticket到指定URL换取二维码。

具体步骤:

获取ticket:

1.简要步骤:获取token,拼凑参数(json数据),调用微信接口获取ticket

1.1 获取token

public class AccessTokenUtil {
	private static String ACCESSTOKENURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={appSecret}";
	/**
	 * 获取access_Token
	 * 
	 * @return
	 */
	public static String getAccessToken(String appId, String appSecret) {
		String url = ACCESSTOKENURL.replace("{appId}", appId).replace("{appSecret}", appSecret);
		String accessTokenJsonStr = Browser.httpGet(url);
		Gson gson = new Gson();
		AccessToken accessToken = gson.fromJson(accessTokenJsonStr, AccessToken.class);
		if(accessToken.getErrcode() != 0) {
			return null;
		}else {
			return accessToken.getAccess_token();
		}
	}
}

将appid和appSectet替换成自己的。

1.2 json数据拼凑

临时二维码json数据

{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}

或(两者的区别在于场景值的表示方法不同,上面是数字,下面是字符串)

{"expire_seconds": 604800, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}

永久二维码json数据(和临时的区别在于没有时间限制)

{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}

或(同上)

{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}

注意格式一定要确保正确,获取可能会造成可以获取二维码,但在扫码事件中无法获取场景值。

为了获取上述json数据,这边先进行实体类封装,然后利用Gson序列化

二维码实体类,最大的类

/**
 * 二维码实体类
 * 
 * @author WRY
 *
 */
public class QrCode {
	// 二维码类型
	// 临时整形
	public static final String QRSCENE = "QR_SCENE";
	// 临时字符串
	public static final String QRSTRSCENE = "QR_STR_SCENE";
	// 永久整形
	public static final String QRLIMITSCENE = "QR_LIMIT_SCENE";
	// 永久字符串
	public static final String QRLIMITSTRSCENE = "QR_LIMIT_STR_SCENE";

	// expire_seconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
	@SerializedName("expire_seconds")
	private Long expireSeconds;
	// action_name
	// 二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值
	@SerializedName("action_name")
	private String actionName;
	// action_info 二维码详细信息
	@SerializedName("action_info")
	private ActionInfo actionInfo;

	public long getExpireSeconds() {
		return expireSeconds;
	}

	public void setExpireSeconds(long expireSeconds) {
		this.expireSeconds = expireSeconds;
	}

	public String getActionName() {
		return actionName;
	}

	public void setActionName(String actionName) {
		this.actionName = actionName;
	}

	public ActionInfo getActionInfo() {
		return actionInfo;
	}

	public void setActionInfo(ActionInfo actionInfo) {
		this.actionInfo = actionInfo;
	}

}

二维码详情类

public class ActionInfo {
	// 场景值信息
	private Scene scene;

	public Scene getScene() {
		return scene;
	}

	public void setScene(Scene scene) {
		this.scene = scene;
	}
	
}

场景类

/**
 * 二维码场景
 * @author WRY
 *
 */
public class Scene {
	// scene_id 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
	@SerializedName("scene_id")
	private Long sceneId;
	// scene_str 场景值ID(字符串形式的ID),字符串类型,长度限制为1到64
	@SerializedName("scene_str")
	private String sceneStr;

	public long getSceneId() {
		return sceneId;
	}

	public void setSceneId(long sceneId) {
		this.sceneId = sceneId;
	}

	public String getSceneStr() {
		return sceneStr;
	}

	public void setSceneStr(String sceneStr) {
		this.sceneStr = sceneStr;
	}

}
有了上述封装,后续就可以很简单拼凑json数据

1.3 封装一个可以发送post请求的浏览器类,基于httpClient封装,这边附上主要代码,整个类比较大,如果有需要知道全部的封装类,请给我留言

/**
	 * post请求
	 * 
	 * @param url
	 * @param param
	 *            json格式的请求数据
	 * @return
	 */
	public static String httpPost(String url, String param) {
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
		RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(5000).setConnectTimeout(5000)
				.setSocketTimeout(5000).build();
		HttpPost httpPost = new HttpPost(url);
		httpPost.setConfig(config);
		// 设置请求数据
		StringEntity entity = new StringEntity(param, Charset.forName("UTF-8"));
		entity.setContentEncoding("UTF-8");
		// 发送Json格式的数据请求
		entity.setContentType("application/json");
		httpPost.setEntity(entity);
		CloseableHttpResponse httpResponse = null;
		String soundCode = "";
		try {
			httpResponse = httpClient.execute(httpPost);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				HttpEntity entitytemp = httpResponse.getEntity();
				soundCode = EntityUtils.toString(entitytemp, "utf-8");
			}
		} catch (ClientProtocolException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		} finally {
			if (httpResponse != null) {
				try {
					httpResponse.close();
					httpResponse = null;
				} catch (IOException e) {
				}
			}
			if (httpClient != null) {
				try {
					httpClient.close();
					httpClient = null;
				} catch (IOException e) {
				}
			}
		}
		return soundCode;
	}

1.4 service类

/**
 * 二维码的业务类
 * @author WRY
 *
 */
public class QrCodeService {
	// 获取临时ticket
	private static String GETTEMPTICKETURL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={accessToken}";
	// 获取永久ticket
	private static String GETPERMANENTTICKETURL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={accessToken}";
	/**
	 * 获取临时ticket
	 * @return
	 */
	public String getTempTicket(String accessToken, String param) {
		String url = GETTEMPTICKETURL.replace("{accessToken}", accessToken);
		return Browser.httpPost(url, param);
	}
	
	/**
	 * 获取永久ticket
	 * @param accessToken
	 * @param param
	 * @return
	 */
	public String getPermanentTicket(String accessToken, String param) {
		String url = GETPERMANENTTICKETURL.replace("{accessToken}", accessToken);
		return Browser.httpPost(url, param);
	}
}

1.5 测试类

public class QrCodeServiceTest {
	private static final String accessToken = "9_0Zo6BjMhLNF7RACUjJ1sWg9Tk0IpkH8TvgkPx_WlrvZ0a5Ow7ZGxg_dY2_ECnaJSUHR8Aaz3K9AT4keuq4GMqHLgwXMt5lsNrElRWvEQ9uMC7RV3KS9VPl9jvgkXGGbAEARAA";

	/**
	 * 获取临时ticket
	 */
	@Test
	public void testGetTempTicket() {
		// 建立场景值
		Scene scene = new Scene();
		scene.setSceneId(0001);
		// 二维码详细信息
		ActionInfo actionInfo = new ActionInfo();
		actionInfo.setScene(scene);
		// 构建获取二维码的信息
		QrCode qrCode = new QrCode();
		qrCode.setActionName(QrCode.QRSCENE);
		qrCode.setActionInfo(actionInfo);
		// 序列化数据
		Gson gson = new Gson();
		String param = gson.toJson(qrCode);
		System.out.println(param);
		// 获取二维码
		QrCodeService service = new QrCodeService();
		String soundCode = service.getTempTicket(accessToken, param);
		System.out.println(soundCode);
		ReturnMessage returnMessage = gson.fromJson(soundCode, ReturnMessage.class);
		System.out.println(returnMessage);
	}
	// {"ticket":"gQHx7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyTDNXY2h4SlJmM2sxVjAxTk5xMU0AAgQwc-FaAwQQDgAA","expire_seconds":3600,"url":"http:\/\/weixin.qq.com\/q\/02L3WchxJRf3k1V01NNq1M"}
	// 换取二维码
	// https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQFE8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUjV3LWdUSlJmM2sxU3ZuT05xMXYAAgSPSfJaAwQQDgAA

	/**
	 * 获取永久ticket
	 */
	@Test
	public void testGetPermanentTicket() {
		// 建立场景值
		Scene scene = new Scene();
		scene.setSceneId(10000);
		// 二维码详细信息
		ActionInfo actionInfo = new ActionInfo();
		actionInfo.setScene(scene);
		// 构建获取二维码的信息
		QrCode qrCode = new QrCode();
		qrCode.setActionName(QrCode.QRLIMITSCENE);
		qrCode.setActionInfo(actionInfo);
		// 序列化数据
		Gson gson = new Gson();
		String param = gson.toJson(qrCode);
		System.out.println(param);
		// 获取二维码
		QrCodeService service = new QrCodeService();
		String soundCode = service.getPermanentTicket(accessToken, param);
		System.out.println(soundCode);
		ReturnMessage returnMessage = gson.fromJson(soundCode, ReturnMessage.class);
		System.out.println(returnMessage);
	}
	// {"ticket":"gQF38TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyZzczZGdLSlJmM2sxMDAwMHcwMzEAAgSLWPJaAwQAAAAA","url":"http:\/\/weixin.qq.com\/q\/02g73dgKJRf3k10000w031"}

}

返回信息


2 用ticket获取二维码

https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET

ticket替换成自己获取的ticket(左为临时,右为永久)


扫码推送事件

1.首先确保你的微信公众号或则测试号已经接入自己的项目中,具体流程参考

https://blog.csdn.net/wrongyao/article/details/80203929

2、推送事件


详见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454

3. 后台事件获取(部分代码)

                        String event = map.get("Event");
                        // 返回的xml
			String result = "";
			// 订阅事件
			if (null != event && event.equals("subscribe")) {
				result = new MessageService().subscribeHandle(map);
				// 取消订阅事件
			} else if (null != event && event.equals("unsubscribe")) {
				result = "退订";
				// 扫码事件
			} else if(null != event && event.equals("SCAN")){
				
			}else {
				if (null != keyWord && keyWord.equals("图片")) {
					result = new MessageService().imageHandle(map);
				} else if (null != keyWord && keyWord.equals("图文")) {
					result = new MessageService().ArticleHandle(map);
				} else {
					result = new MessageService().textHandle(map);
				}
			}

大体思路就是获取微信服务器向我们项目推送的xml数据,具体数据上述截图中已列出,针对不同的事件做出不同的相应。



猜你喜欢

转载自blog.csdn.net/wrongyao/article/details/80250418