All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xnx3.weixin.WeiXinUtil Maven / Gradle / Ivy

The newest version!
package com.xnx3.weixin;

//import org.dom4j.Document;
//import org.dom4j.DocumentException;
//import org.dom4j.DocumentHelper;
//import org.dom4j.Element;
import net.sf.json.JSONObject;

import java.util.Map;

import com.xnx3.BaseVO;
import com.xnx3.DateUtil;
import com.xnx3.StringUtil;
import com.xnx3.net.HttpResponse;
import com.xnx3.weixin.bean.AccessToken;
import com.xnx3.weixin.bean.JsapiTicket;
import com.xnx3.weixin.bean.SignatureBean;
import com.xnx3.weixin.bean.UserInfo;

/**
 * 微信公众号的基本操作-不涉及小程序。微信小程序使用 {@link WeiXinAppletUtil}
 * @author 管雷鸣
 */
public class WeiXinUtil implements java.io.Serializable{
	public static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";	//获取普通access_token的url
	public static String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";	//获取用户个人信息的url
	public static String OAUTH2_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";	//网页授权跳转的url
	public static String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";	//网页授权,获取access_token
	public static String OAUTH2_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";	//网页授权,获取用户信息
	public static String JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";	//获取jsapi_ticket的接口。jsapi_ticket是公众号用于调用微信JS接口的临时票据,效果同access_token,也是7200秒刷新一次
	
	public static int ACCESS_TOKEN_DELAY_TIME = 5000;	//access_token获取后使用的时长,单位为秒,官方给出的access_token获取后最大有效时间是7200秒,一个access_token的有效期最大只能是7200秒之内有效,超出后就要重新获取。这里设定获取到access_token后最大持续5000秒,超过后便再次获取新的access_token
	public static int JSAPI_TICKET_DELAY_TIME = 5000;	//jsapi_ticket获取后使用的时长,单位为秒
	
	/**
	 * 持久化的 JsapiTicket 数据,用于JS SDK。
	 * 请使用 {@link #getJsapiTicket()} 获取 jsapi_ticket ,会自动判断时间是否过期,过期会自动获取新的
	 * @deprecated
	 */
	public JsapiTicket jsapiTicket;	
	/**
	 * 持久化access_token数据
	 * 请使用 {@link #getAccessToken()} 获取 access_token ,会自动判断时间是否过期,过期会自动获取新的
	 * @deprecated
	 */
	public AccessToken accessToken;
	public boolean debug = true;	//调试日志是否打印
	public String appId;	//AppID(应用ID)
	private String appSecret;	//AppSecret(应用密钥)
	private String token;	//用户于微信公众平台双方拟定的令牌Token
	
	/**
	 * 微信基本操作-不涉及小程序。微信小程序使用 {@link XiaoChengXuUtil}
	 * @param appId AppID(应用ID)
	 * @param appSecret AppSecret(应用密钥)
	 * @param token 用户于微信公众平台双方拟定的令牌Token。可为空。
	 * @deprecated 请使用 {@link WeiXinUtil#WeiXinUtil(String, String)}
	 */
	public WeiXinUtil(String appId, String appSecret, String token) {
		this.appId = appId;
		this.appSecret = appSecret;
		this.token = token;
	}
	
	/**
	 * 微信公众号的基本操作-不涉及小程序。微信小程序使用 {@link XiaoChengXuUtil}
	 * @param appId AppID(应用ID)
	 * @param appSecret AppSecret(应用密钥)
	 */
	public WeiXinUtil(String appId, String appSecret) {
		this.appId = appId;
		this.appSecret = appSecret;
	}
	
	/**
	 * 获取最新的普通access_token
	 * @return AccessToken 若返回null,则获取access_token失败
	 */
	public AccessToken getAccessToken(){
		boolean refreshToken = false;	//需重新刷新获取token,默认是不需要
		
		if(accessToken == null){
			accessToken = new AccessToken();
			refreshToken = true;
		}
		
		//是否过时,需要重新获取token
		if(DateUtil.timeForUnix10()>(accessToken.getGainTime()+ACCESS_TOKEN_DELAY_TIME)){
			refreshToken = true;
		}
		
		//避免一次可能网络中断,连续获取三次,减小误差
		boolean success = !refreshToken;
		int i = 0;
		for (; i < 3 && !success ; i++) {
			success = refreshAccessToken();
		}
		
		if(!success){
			debug("连续获取"+i+"次access_token,均失败!" );
			return null;
		}else{
			return accessToken;
		}
	}
	
	/**
	 * 通过openId,获取用户的信息
	 * @param openId 普通用户的标识,对当前公众号唯一
	 * @return UserInfo	
	 * 			
    *
  • 若返回null,则获取失败
  • *
  • 若不为null,先判断其subscribe,若为true,已关注,则可以取到其他的信息
  • *
*/ public UserInfo getUserInfo(String openId){ com.xnx3.net.HttpUtil httpUtil = new com.xnx3.net.HttpUtil(); UserInfo userInfo = null; HttpResponse httpResponse = httpUtil.get(USER_INFO_URL.replace("ACCESS_TOKEN", getAccessToken().getAccess_token()).replace("OPENID", openId)); JSONObject json = JSONObject.fromObject(httpResponse.getContent()); if(json.get("subscribe") != null){ userInfo = new UserInfo(); userInfo.setSubscribe(json.getString("subscribe").equals("1")); if(userInfo.isSubscribe()){ userInfo.setCity(json.getString("city")); userInfo.setCountry(json.getString("country")); userInfo.setHeadImgUrl(json.getString("headimgurl")); userInfo.setLanguage(json.getString("language")); userInfo.setNickname(json.getString("nickname")); userInfo.setOpenid(json.getString("openid")); userInfo.setProvince(json.getString("province")); userInfo.setSex(json.getInt("sex")); userInfo.setSubscribeTime(json.getInt("subscribe_time")); userInfo.setUnionid(json.getString("unionid")); userInfo.setRemark(json.getString("remark")); userInfo.setGroupid(json.getInt("groupid")); userInfo.setSubscribeScene(json.getString("subscribe_scene")); userInfo.setQr_scene(json.getString("qr_scene")); userInfo.setQrSceneStr(json.getString("qr_scene_str")); } }else{ debug("获取用户信息失败!用户openid:"+openId+",微信回执:"+httpResponse.getContent()); } return userInfo; } /** * 刷新重新获取access_token * @return 获取成功|失败 */ private boolean refreshAccessToken(){ com.xnx3.net.HttpUtil httpUtil = new com.xnx3.net.HttpUtil(); HttpResponse httpResponse = httpUtil.get(ACCESS_TOKEN_URL.replace("APPID", this.appId).replace("APPSECRET", this.appSecret)); JSONObject json = JSONObject.fromObject(httpResponse.getContent()); if(json.get("errcode") == null){ //没有出错,获取access_token成功 accessToken.setAccess_token(json.getString("access_token")); accessToken.setExpires_in(json.getInt("expires_in")); accessToken.setGainTime(DateUtil.timeForUnix10()); debug("refreshAccessToken:"+accessToken.toString()+", appid:"+this.appId); return true; }else{ int errcode = json.getInt("errcode"); if(errcode - 40164 == 0){ debug("需要登录微信公众平台,找到左侧菜单的开发-基本配置 ,点开,找到其中的 公众号开发信息 - IP白名单,将您的ip加入其中,即可解决此错误"); } debug("获取access_token失败!返回值:"+httpResponse.getContent()); return false; } } /** * 获取网页授权的URL跳转地址 * @param redirectUri 授权后重定向的回调链接地址,无需URL转码,原始url * @param scope 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) * @param state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 * @return url地址 */ public String getOauth2Url(String redirectUri,String scope,String state){ return OAUTH2_URL.replace("APPID", this.appId).replace("REDIRECT_URI", StringUtil.stringToUrl(redirectUri)).replace("SCOPE", scope).replace("STATE", state); } /** * 获取网页授权的URL跳转地址,弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 * @param redirectUri 授权后重定向的回调链接地址,无需URL转码,原始url * @return url地址 */ public String getOauth2SimpleUrl(String redirectUri){ return getOauth2Url(redirectUri, "snsapi_userinfo", "STATE"); } /** * 获取网页授权的URL跳转地址,不会出现授权页面,只能拿到用户openid * @param redirectUri 授权后重定向的回调链接地址,无需URL转码,原始url * @return url地址 */ public String getOauth2ExpertUrl(String redirectUri){ return getOauth2Url(redirectUri, "snsapi_base", "STATE"); } /** * 获取网页授权,获取用户的openid * @param code 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE,授权成功会get方式传过来 * @return 用户openid 若为null,则获取失败 */ public String getOauth2OpenId(String code){ com.xnx3.net.HttpUtil httpUtil = new com.xnx3.net.HttpUtil(); HttpResponse httpResponse = httpUtil.get(OAUTH2_ACCESS_TOKEN_URL.replace("APPID", this.appId).replace("SECRET", this.appSecret).replace("CODE", code)); JSONObject json = JSONObject.fromObject(httpResponse.getContent()); if(json.get("errcode") == null){ //没有出错,获取网页access_token成功 return json.getString("openid"); }else{ debug("获取网页授权access_token失败!返回值:"+httpResponse.getContent()); } return null; } /** * 网页授权获取用户的个人信息 * @param code 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE,授权成功会get方式传过来 * @return 结果: *
    *
  • 若成功,返回{@link UserInfo} (无 subscribeTime 项)
  • *
  • 若失败,返回null
  • *
*/ public UserInfo getOauth2UserInfo(String code){ com.xnx3.net.HttpUtil httpUtil = new com.xnx3.net.HttpUtil(); HttpResponse httpResponse = httpUtil.get(OAUTH2_ACCESS_TOKEN_URL.replace("APPID", this.appId).replace("SECRET", this.appSecret).replace("CODE", code)); JSONObject json = JSONObject.fromObject(httpResponse.getContent()); if(json.get("errcode") == null){ //没有出错,获取网页access_token成功 HttpResponse res = httpUtil.get(OAUTH2_USER_INFO_URL.replace("ACCESS_TOKEN", json.getString("access_token")).replace("OPENID", json.getString("openid"))); JSONObject j = JSONObject.fromObject(res.getContent()); if(j.get("errcode") == null){ UserInfo userInfo = new UserInfo(); userInfo.setCity(j.getString("city")); userInfo.setOpenid(j.getString("openid")); userInfo.setNickname(j.getString("nickname")); userInfo.setSex(j.getInt("sex")); userInfo.setProvince(j.getString("province")); userInfo.setCountry(j.getString("country")); userInfo.setHeadImgUrl(j.getString("headimgurl")); userInfo.setLanguage("zh_CN"); return userInfo; }else{ debug("获取网页授权用户信息失败!返回值:"+res.getContent()); } }else{ debug("获取网页授权access_token失败!返回值:"+httpResponse.getContent()); } return null; } /** * 调试日志打印 * @param message 日志内容 */ private void debug(String message){ if(debug){ System.out.println("WeiXinUtil:"+message); } } /** * 接收xml格式消息,用户通过微信公众号发送消息,有服务器接收。这里将微信服务器推送来的消息进行格式化为 {@link MessageReceive}对象 *

通常此会存在于一个Servlet中,用于接收微信服务器推送来的消息。

* @param request 这里便是微信服务器接收到消息后,将消息POST提交过来的请求,会自动从request中取微信post的消息内容 * @return 返回 {@link MessageReceive} * @throws DocumentException 异常 */ // public MessageReceive receiveMessage(HttpServletRequest request) throws DocumentException{ // StringBuffer jb = new StringBuffer(); // String line = null; // try { // BufferedReader reader = request.getReader(); // while ((line = reader.readLine()) != null) // jb.append(line); // } catch (Exception e) { // e.printStackTrace(); // } // String messageContent = jb.toString(); // // return receiveMessage(messageContent); // } /** * 接收xml格式消息,用户通过微信公众号发送消息,有服务器接收。这里将微信服务器推送来的消息进行格式化为 {@link MessageReceive}对象 *

通常此会存在于一个Servlet中,用于接收微信服务器推送来的消息。例如SpringMVC中可以这样写:

*
	 * 	MessageReceive message = new WeiXinUtil(......).receiveMessage(request);
	 * 
* @param messageContent 这里便是微信服务器接收到消息后,将消息POST提交过来消息内容 * @return 返回 {@link MessageReceive} * @throws DocumentException 异常 */ // public MessageReceive receiveMessage(String messageContent) throws DocumentException{ // MessageReceive mr = new MessageReceive(); // // if(messageContent == null || messageContent.length() == 0){ // //为空,那么直接返回mr,当然,mr中的各项都是空的 // return mr; // } // // mr.setReceiveBody(messageContent); // // Document doc = DocumentHelper.parseText(messageContent); // Element e = doc.getRootElement(); // // if(e.element("CreateTime") != null){ // mr.setCreateTime(Lang.stringToInt(e.element("CreateTime").getText(), 0)); // } // if(e.element("FromUserName") != null){ // mr.setFromUserName(e.element("FromUserName").getText()); // } // if(e.element("MsgType") != null){ // mr.setMsgType(e.element("MsgType").getText()); // } // if(e.element("ToUserName") != null){ // mr.setToUserName(e.element("ToUserName").getText()); // } // if(e.element("MsgId") != null){ // mr.setMsgId(e.element("MsgId").getText()); // } // if(e.element("Content") != null){ // mr.setContent(e.element("Content").getText()); // } // if(e.element("Description") != null){ // mr.setDescription(e.element("Description").getText()); // } // if(e.element("Format") != null){ // mr.setFormat(e.element("Format").getText()); // } // if(e.element("MediaId") != null){ // mr.setMediaId(e.element("MediaId").getText()); // } // if(e.element("PicUrl") != null){ // mr.setPicUrl(e.element("PicUrl").getText()); // } // if(e.element("ThumbMediaId") != null){ // mr.setThumbMediaId(e.element("ThumbMediaId").getText()); // } // if(e.element("Title") != null){ // mr.setTitle(e.element("Title").getText()); // } // if(e.element("Url") != null){ // mr.setUrl(e.element("Url").getText()); // } // if(e.element("Event") != null){ // mr.setEvent(e.element("Event").getText()); // } // // if(e.element("EventKey") != null){ // mr.setEventKey(e.element("EventKey").getText()); // } // if(e.element("Ticket") != null){ // mr.setTicket(e.element("Ticket").getText()); // } // // return mr; // } /** * 微信服务器接收消息或者事件后,推送到我们的服务器。我们服务器会自动处理并给微信服务器返回一个响应:微信公众号会自动给这个用户发送一条文字消息 *

相当于:

*
	 * 	MessageReply messageReply = new MessageReply(messageReceive.getFromUserName(), messageReceive.getToUserName());
	 *	messageReply.replyText(response, content);
	 * 
* @param response {@link HttpServletResponse}响应,输出返回值给微信服务器。 * @param messageReceive 使用{@link #receiveMessage(HttpServletRequest)}方法获取到的 {@link MessageReceive}。这里面可以拿到是要回复给哪个用户。 * @param content 微信公众号自动给触发此响应的用户发送的文字消息,这里便是文字消息的内容 */ // public void autoReplyText(HttpServletResponse response, MessageReceive messageReceive, String content){ // MessageReply messageReply = new MessageReply(messageReceive.getFromUserName(), messageReceive.getToUserName()); // messageReply.replyText(response, content); // } /** * 微信公众号开发,需首先填入与微信服务器交互的我方URL地址, 填写的URL需要正确响应微信发送的Token验证。这里便是接入时的验证的作用 *

使用时,如 SpringMVC 中:

*
	 * 	@RequestMapping("weixin")
	 *	public void verify(HttpServletRequest request, HttpServletResponse response){
	 *		WeiXinUtil.joinVerify(request, response);
	 *	}
	 * 
* @param request {@link HttpServletRequest} * @param response {@link HttpServletResponse} */ // public void joinVerify(HttpServletRequest request, HttpServletResponse response){ // response.setContentType("text/html"); // PrintWriter out = null; // try { // out = response.getWriter(); // } catch (IOException e1) { // e1.printStackTrace(); // } // String signature = request.getParameter("signature"); // String timestamp = request.getParameter("timestamp"); // String nonce = request.getParameter("nonce"); // String echostr = request.getParameter("echostr"); // // String reSignature = null; // try { // String[] str = { token, timestamp, nonce }; // Arrays.sort(str); // String bigStr = str[0] + str[1] + str[2]; // reSignature = new SHA1().getDigestOfString(bigStr.getBytes()).toLowerCase(); // } catch (Exception e) { // e.printStackTrace(); // } // if (null != reSignature && reSignature.equals(signature)) { // //请求来自微信 // out.print(echostr); // } else { // out.print("error request! the request is not from weixin server"); // } // out.flush(); // out.close(); // } /** * 获取 JS SDK 的 ticket * @return 当前可用的 ticket */ public JsapiTicket getJsapiTicket(){ boolean refreshToken = false; //需重新刷新获取token,默认是不需要 if(jsapiTicket == null){ jsapiTicket = new JsapiTicket(); refreshToken = true; } //是否过时,需要重新获取token if(DateUtil.timeForUnix10()>(jsapiTicket.getGainTime()+JSAPI_TICKET_DELAY_TIME)){ refreshToken = true; } //避免一次可能网络中断,连续获取三次,减小误差 boolean success = !refreshToken; int i = 0; for (; i < 3 && !success ; i++) { success = refreshJsapiTicket(); } if(!success){ debug("连续获取"+i+"次 jsapi_ticket ,均失败!" ); return null; }else{ return jsapiTicket; } } /** * 刷新重新获取 jsapi_ticket ,其实直接使用 getJsapiTicket() 获取可用的 ticket 即可。 * @return 获取成功|失败 */ private boolean refreshJsapiTicket(){ com.xnx3.net.HttpUtil httpUtil = new com.xnx3.net.HttpUtil(); HttpResponse httpResponse = httpUtil.get(JSAPI_TICKET_URL.replace("ACCESS_TOKEN", getAccessToken().getAccess_token())); JSONObject json = JSONObject.fromObject(httpResponse.getContent()); if(json.get("errcode") != null && json.getInt("errcode") == 0){ //没有出错,获取成功 jsapiTicket.setExpires_in(json.getInt("expires_in")); jsapiTicket.setGainTime(DateUtil.timeForUnix10()); jsapiTicket.setTicket(json.getString("ticket")); debug("refreshJsapiTicket:"+jsapiTicket.toString()); return true; }else{ debug("获取access_token失败!返回值:"+httpResponse.getContent()); return false; } } /** * JS-SDK 生成 signature 签名,可以在页面中直接使用,如分享到朋友圈等 * 注意事项: *

1.签名的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

*

2.签名用的url必须是调用JS接口页面的完整URL。

*

3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

* @param url 当前网页的URL,不包含#及其后面部分,如 http://mp.weixin.qq.com?params=value * @return signature 签名,已处理好,拿来即可直接使用 */ public SignatureBean getJsSignature(String url){ SignatureBean bean = new SignatureBean(); bean.setNoncestr(StringUtil.getRandomAZ(8)); bean.setTimestamp(DateUtil.timeForUnix10()); bean.setUrl(url); String str = "jsapi_ticket="+getJsapiTicket().getTicket()+"&noncestr="+bean.getNoncestr()+"×tamp="+bean.getTimestamp()+"&url="+url; String signstr = new SHA1().getDigestOfString(str.getBytes()).toLowerCase(); bean.setSignature(signstr); return bean; } /** * 微信生成带参数的永久二维码,拉取微信的 ticket *
微信官方限制最多生成10万永久二维码,慎用 *
微信接口文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542 * @param scene_str 带参数的二维码,这里便是参数。字符串类型,长度限制为1到64 * @return 若成功,则通过 getInfo() 获取生成的 ticket */ public BaseVO getParamQrcodeTicket(String scene_str){ BaseVO vo = new BaseVO(); JSONObject json = new JSONObject(); // json.put("expire_seconds", 604800); json.put("action_name", "QR_LIMIT_STR_SCENE"); JSONObject scene = new JSONObject(); JSONObject scene_id_json = new JSONObject(); scene_id_json.put("scene_str", scene_str); scene.put("scene", scene_id_json); json.put("action_info", scene); // HttpUtil http = new HttpUtil(); // JSONObject j = http.doPost("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+getAccessToken().getAccess_token(), json); String result = HttpsUtil.post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+getAccessToken().getAccess_token(), json.toString()); if(result == null || result.length() == 0){ vo.setBaseVO(BaseVO.FAILURE, "微信api响应结果为null"); return vo; } JSONObject j = JSONObject.fromObject(result); if(j != null && j.toString().indexOf("\"ticket\"") > -1){ vo.setInfo(j.getString("ticket")); }else{ vo.setBaseVO(BaseVO.FAILURE, "异常:"+(j == null? "null":j.toString())); } return vo; } /** * 发送微信公众号服务号的模板消息 *

注:url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。

* @param accessToken 通过 appId 跟 appSecret 得到的 access_token * @param openid 接收的用户openid,如 oa04fwGxDJsbIzzfwp4VPEBNGM21 * @param templateId 模板id,如 3YV61HeNU6k59PfswwGs8zDCQxLUr2CaHre5GWyHu61 * @param dataMap 模板消息的信息。如 *
	 * 		Map<String, String> dataMap = new HashMap<String, String>();
	 *		dataMap.put("first", "测试的");
	 * 		dataMap.put("tradeDateTime", "我是时间");
	 * 	
* @param url 点击消息跳转到的url,如果不需要点击跳转,则传入 null * @param miniprogram 用户点击这条消息跳到小程序所需数据,这个map固定就是appid、pagepath这两个参数。 如果不需跳小程序,可不用传该数据,传入null即可 *
	 * 		Map<String, String> miniprogram = new HashMap<String, String>();
	 *		miniprogram.put("appid", "xiaochengxuappid12345"); // 小程序的appid
	 * 		miniprogram.put("pagepath", "index?foo=bar");	//打开小程序的页面
	 * 	
* @return {@link BaseVO} 如果 result() 为 BaseVO.SUCCESS ,那么是成功。 如果是 BaseVO.FAILURE ,可以用 getInfo() 获得失败原因 */ public BaseVO sendTemplateMessage(String templateId, String openid, Map dataMap, String url, Map miniprogram){ JSONObject json = new JSONObject(); json.put("touser", openid); //护理美容 json.put("template_id", templateId); if(url != null && url.length() > 0){ json.put("url", url); } if(miniprogram != null) { JSONObject miniProgramJson = JSONObject.fromObject(miniprogram); json.put("miniprogram", miniProgramJson); } JSONObject dataJson = new JSONObject(); for(Map.Entry entry : dataMap.entrySet()){ JSONObject item = new JSONObject(); item.put("value", entry.getValue()); dataJson.put(entry.getKey(), item); } json.put("data", dataJson); AccessToken at = getAccessToken(); if(at == null) { return BaseVO.failure("自动获取token失败,请检查appid、appsercrt是否传入错误,或者你电脑或者服务器ip未加入白名单(登录微信公众平台,再设置与开发-基本设置里)"); } return TemplateMessageUtil.sendMessage(at.getAccess_token(), json.toString()); } @Override public String toString() { return "WeiXinUtil [debug=" + debug + ", accessToken=" + accessToken + ", jsapiTicket=" + jsapiTicket + ", appId=" + appId + ", appSecret=" + appSecret + ", token=" + token + "]"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy