Solo  当前访客:3 登录 注册

喧哗博客-http://blog.xuahua.com

繁华过后的沉寂--技术经验分享
浏览次数: 95,037    文章总数: 91    评论总数: 3
标签:

微信公众号,高级群发接口,如何增加外链直接让推送的图文消息点 有更新!

最近弄这个头大了。。

如何实现点击微信图文信息直接跳转至外部链接

有知道的没有?请留言!

微信接口开发系列之九群发消息上传图片 有更新!

微信接口定义如下

上传图文消息内的图片获取URL【订阅号与服务号认证后均可用】

请注意,本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下。

接口调用请求说明

http请求方式: POST
https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
事后证明,上传图片的接口请使用 http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=image 调用示例(使用curl命令,用FORM表单方式上传一个图片): curl -F media=@test.jpg "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN"

参数说明

参数是否必须说明
access_token 调用接口凭证
media form-data中媒体文件标识,有filename、filelength、content-type等信息

返回说明 正常情况下的返回结果为:

{
    "url":  "http://mmbiz.qpic.cn/mmbiz/gLO17UPS6FS2xsypf378iaNhWacZ1G1UplZYWEYfwvuU6Ont96b1roYs CNFwaRrSaKTPCUdBK9DgEHicsKwWCBRQ/0"
}

其中url就是上传图片的URL,可用于后续群发中,放置到图文消息中。

错误时微信会返回错误码等信息,请根据错误码查询错误信息。

 

 

使用httpclient 上传图片代码如下:

/**
	 * 微信客服消息,上传文件接口使用
	 * @param url  微信提供的上传地址
	 * @param file 上传图片地址,此处必须是本地文件路径
	 * @param filename 对应的上传文件名
	 * @return
	 */
	public static String postfile(String url,String file,String filename){
		StringBuilder sb = new StringBuilder();
		CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost httppost = new HttpPost(url); 
        postRequestconfig(httppost);
        
        try {
        	HttpEntity entityfile = MultipartEntityBuilder.create()  
        			.addBinaryBody("file", new File(file), ContentType.DEFAULT_BINARY, file).addTextBody("filename",filename)  
        			.build();  
        	httppost.setEntity(entityfile);  
	    	HttpResponse response = httpclient.execute(httppost);
			int statusOk = response.getStatusLine().getStatusCode();
			if(logger.isInfoEnabled()){
		        	logger.info(url+"result-statusCode=>>"+statusOk);
		    }
	        if(statusOk == HttpStatus.SC_OK){
	        	HttpEntity entity = response.getEntity();
	        	BufferedInputStream instream = new BufferedInputStream(entity.getContent()); 
		        byte[] chars = new byte[2048];
		        int len=0;
		        while((len=instream.read(chars))!=-1){
		        	sb.append(new String(chars,0,len));
		        }
	        }else{
	        	logger.error(url+"result->网络异常.."+statusOk);
	        }
	        if(logger.isInfoEnabled()){
	        	logger.info(url+"result->"+sb.toString());
	        }
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	    return sb.toString();
	}

微信接口开发系列之八批量获取用户信息 有更新!

1,微信提供了批量获取用户信息以及union_id;

文档请见 https://mp.weixin.qq.com/wiki/14/bb5031008f1494a59c6f71fa0f319c66.html 



批量获取用户基本信息

开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。

接口调用请求说明

http请求方式: POST
https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
POST数据示例

{
    "user_list": [
        {
            "openid": "otvxTs4dckWG7imySrJd6jSi0CWE", 
            "lang": "zh-CN"
        }, 
        {
            "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg", 
            "lang": "zh-CN"
        }
    ]
}
参数说明

参数	是否必须	说明
openid	是	用户的标识,对当前公众号唯一
lang	否	国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN
返回说明

正常情况下,微信会返回下述JSON数据包给公众号(示例中为一次性拉取了2个openid的用户基本信息,第一个是已关注的,第二个是未关注的):

{
   "user_info_list": [
       {
           "subscribe": 1, 
           "openid": "otvxTs4dckWG7imySrJd6jSi0CWE", 
           "nickname": "iWithery", 
           "sex": 1, 
           "language": "zh_CN", 
           "city": "Jieyang", 
           "province": "Guangdong", 
           "country": "China", 
           "headimgurl": "http://wx.qlogo.cn/mmopen/xbIQx1GRqdvyqkMMhEaGOX802l1CyqMJNgUzKP8MeAeHFicRDSnZH7FY4XB7p8XHXIf6uJA2SCunTPicGKezDC4saKISzRj3nz/0", 
           "subscribe_time": 1434093047, 
           "unionid": "oR5GjjgEhCMJFyzaVZdrxZ2zRRF4", 
           "remark": "", 
           "groupid": 0
       }, 
       {
           "subscribe": 0, 
           "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg", 
           "unionid": "oR5GjjjrbqBZbrnPwwmSxFukE41U", 
       }
   ]
}
参数说明

参数	说明
subscribe	用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息,只有openid和UnionID(在该公众号绑定到了微信开放平台账号时才有)。
openid	用户的标识,对当前公众号唯一
nickname	用户的昵称
sex	用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
city	用户所在城市
country	用户所在国家
province	用户所在省份
language	用户的语言,简体中文为zh_CN
headimgurl	用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
subscribe_time	用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
unionid	只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。详见:获取用户个人信息(UnionID机制)
remark	公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
groupid	用户所在的分组ID
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}

实现代码要点:


//微信批量定义每次最多100条记录,做循环获取。
		    Page page = userService.findAllTMemBind(1, i, 100);
		    while(page!=null && page.getResult()!=null && !page.getResult().isEmpty()){
		    	count = count + page.getResult().size();
		    	
		    	//调用本地的方法,获取之前保存的access_token 此token也称为全局acess_token;区别于网页用户显示授权acess_token
		    	String access_token = loadGZWXtoken();
		    	
		    	//具体拼接方法,并请求微信服务器,返回数据
		    	batchupdate(page.getResult(),access_token);
		    	
		    	//处理完成以后,再次拉取。重复循环
		    	page = userService.findAllTMemBind(1, i++, 100);
		    }
batchupdate 方法实现



private void batchupdate(List<TMemBinduser> userlist,String access_token){
		if(userlist ==null || userlist.isEmpty()) return ;
		
		JSONArray ary  =new JSONArray();
		for(TMemBinduser user:userlist){
			Map<String,String> openids = new HashMap<String,String>();
			openids.put("openid",user.getBindid());
			openids.put("lang","zh-CN");
			ary.add(JSON.toJSON(openids));
		}
		Map<String,Object> ulist = new HashMap<String,Object>();
		ulist.put("user_list",ary);
		String url = PropertiesUtil.getValue("wx.gz.batchget");
		url = url.replaceFirst("ACCESS_TOKEN", access_token);
		String result = Posturl.postRequestJson(url, ulist, "", "");
		//正确返回的
		//{"user_info_list":[{"subscribe":1,"openid":"oPMQVwqVrRlrr6Pdmgxr-P3Zh6aI","nickname":"kingman","sex":1,"language":"zh_CN","city":"Shenzhen","province":"Guangdong","country":"China","headimgurl":"http:\/\/wx.qlogo.cn\/mmopen\/6gxkh8CsLWewtkLGib6vxW6NrkJMgChp8ibAIH8SEBEKHYeADeibuDAAv8G5EibjvXAYbjQBwedoJD5lrVKSsic25Qx4smSxRQSqib\/0","subscribe_time":1458718222,"unionid":"oIzlcwLjHriVyXG9KsqJ6i7ggbjg","remark":"","groupid":0,"tagid_list":[]},{"subscribe":1,"openid":"oPMQVwlPuNN0Dztus7oGi2UeFv14","nickname":"Bdb","sex":0,"language":"zh_CN","city":"","province":"","country":"","headimgurl":"http:\/\/wx.qlogo.cn\/mmopen\/Q3auHgzwzM7VtmYVicjQhxcLJGkefRWz6HJN4PNmYibyKicB231FgOwj8dlxQTcDXAbIGN2a1SOgDy4ROJwaHXOzQ\/0","subscribe_time":1459932319,"unionid":"oIzlcwGRoh8JDn8rP3AXvSjSGOy4","remark":"","groupid":0,"tagid_list":[]}]}
		if(log.isInfoEnabled()){
			log.debug("==微信通知-批量拉取用户id==="+result);
		}
	}



微信开发系列 有更新!

1,配置 

               http://blog.xuahua.com/articles/2016/06/30/1467251027592.html

2,授权 

        http://blog.xuahua.com/articles/2016/06/30/1467254772371.html

3,获取用户信息 

        http://blog.xuahua.com/articles/2016/06/30/1467255584587.html

4,模版消息 

         http://blog.xuahua.com/articles/2016/06/30/1467256108292.html

5,微信支付服务器接收通知 

        http://blog.xuahua.com/articles/2016/06/30/1467256973822.html

6,移动应用获取微信用户信息 

        http://blog.xuahua.com/articles/2016/07/13/1468397068875.html

7,微信开放平台支付加密java类 

        http://blog.xuahua.com/articles/2016/07/13/1468399623674.html

8, 微信批量获取用户信息 

    http://blog.xuahua.com/articles/2016/07/30/1469860455915.html

微信接口开发系列之七微信开放平台支付加密java类 有更新!

如题。微信开放平台支付加密类代码如下


// 微信支付 md5认证
	public static  String getMd5WeixinToPay(String str) {
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
			md.reset();
			md.update(str.getBytes("UTF-8"));
			return  byteToStr(md.digest()).toUpperCase();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
/**
	* 将字节数组转换为十六进制字符串
	* 
	* @param byteArray
	* @return
	*/
	public static String byteToStr(byte[] byteArray) {
		 String strDigest = "";
		 for (int i = 0; i < byteArray.length; i++) {
			 strDigest += byteToHexStr(byteArray[i]);
		 }
	 return strDigest;
	}
/**
	* 将字节转换为十六进制字符串
	* 
	* @param btyes
	* @return
	*/
	public static String byteToHexStr(byte bytes) {
		 char[] Digit = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		 char[] tempArr = new char[2];
		 tempArr[0] = Digit[(bytes >>> 4) & 0X0F];
		 tempArr[1] = Digit[bytes & 0X0F];
		 String s = new String(tempArr);
		 return s;
	}
源地址 :http://blog.xuahua.com/articles/2016/07/13/1468399623674.html


微信接口开发系列之六微信开放平台-移动应用获取微信用户信息 有更新!

如题,如果之前已经申请了微信公众号并且通过审核。那么你还需要移动应用,网站以及其他的应用,那么申请一个微信开放平台账号是不二之选。

今天我们要讲的是微信开放平台移动应用获取微信用户信息。此获取方式有别于微信公众号获取。

具体步骤如下:

1,申请微信开放平台账号,并通过资质审核。

2,登录账号  ,点击 “管理中心”--》移动应用--》创建移动应用,提交相关资料等待微信审核通过。

3,此时,移动应用审核通过后,可以添加移动应用相关的开发信息。获取移动应用微信登录代码如下

1)移动应用获取服务器返回的appid,appsecret,通过此参数调用本地微信应用接口,获取微信应用用户临时授权code。

2)根据临时授权code,交互微信服务器取得登录用户access_token,openid,unionid,scope。

3)如果scope不包含有snsapi_userinfo授权说明用户禁止获取微信用户基本信息。如果有,则进入获取用户信息代码

关键代码:

//=================================================================================微信公众平台账号调用代码
	
	private String getGZURLTokenByCode(String code,String appid,String secret){
		String url = PropertiesUtil.getValue("wx.accessTokenCode");
		//https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
		// url = url.replace("CODE", code);
		String result = "";
		try {
			result = Posturl.getRequest(url);
			if (log.isInfoEnabled()) {
				log.info("根据网页授权code,获取openid,网页授权access_token:---------" + result);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

//========
Object obj = resultmap.get("access_token");
						if (obj != null) {
							Object scope = resultmap.get("scope");
							Object openid = resultmap.get("openid");
							Object unionid = resultmap.get("unionid");
							result.put("openid", openid == null ? "" : openid);
							result.put("scope", scope == null ? "" : scope);
							result.put("unionid", unionid == null ? "" : unionid);
							if(scope!=null && scope.toString().indexOf("snsapi_userinfo")<0){
								result.put("status", "-1");
								result.put("msg", "用户禁止授权,无snsapi_userinfo权限");
								return result;
							}
							// D:获取微信用户信息
							Map<String,Object> resulttmp = getGZWeiXinUserinfo(obj.toString(), String.valueOf(openid));
							if(resulttmp.get("status") == null){
								result.put("data",JSON.toJSON(resulttmp));
							}else{
								result.putAll(resulttmp);
							}
						}else{
							result.putAll(resultmap);
						}
						return result;


注意:此处有坑,,,很大的坑

微信开放平台移动应用获取微信用户信息请求接口地址为  https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

而微信公众号获取微信用户信息请求接口为 https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

微信公众号需要通过code获取access_token以后,再根据微信基础接口调用的 access_token 去取微信用户信息。
d

微信接口开发系列之五微信支付服务器接收通知 有更新!

微信服务器 异步通知服务器接收通知

1,业务防止多次重复;

2,以此通知到账为准,实现到账业务逻辑实现。

注意事项:

 微信服务器 通知消息,以流形式接收消息;

  校验消息;

  解析消息按状态,实现对应业务处理。

接收消息关键代码:

response.setCharacterEncoding("utf-8");
			request.setCharacterEncoding("utf-8");
			//response.setContentType("text/xml");
			pw = response.getWriter();
			InputStream in = request.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(in);
			byte[] bytes = new byte[2048];
			int len = -1;
			StringBuilder sb = new StringBuilder();
			while ((len = bis.read(bytes)) != -1) {
				sb.append(new String(bytes, 0, len));
			}
			bis.close();
			String result = sb.toString();


解析消息关键代码:

    

 Document doc = null;		
try {
			// 读取并解析XML文档
			// SAXReader就是一个管道,用一个流的方式,把xml文件读出来
			// SAXReader reader = new SAXReader(); //aa.xml表示你要解析的xml文档
			// Document document = reader.read(new File("aa.xml"));
			// 下面的是通过解析xml字符串的
			doc = DocumentHelper.parseText(xmlstring); // 将字符串转为XML
			Element root = doc.getRootElement(); // 获取根节点
			if(root.element("result_code")!=null){
				vo.setResult_code(trims(root.elementTextTrim("result_code")));
			}
}catch(Exception e){
 
}

微信接口开发系列之四模版消息

发送模版消息,必须从模版库取得匹配的模版template_id并模版内容以及发送给谁的openid

在开发环境中,可在 测试号管理 -- 测试号二维码 扫码添加测试微信号,并在右侧可见 此微信号即测试开发中的openid。此处openid仅用于测试与生产不同。

测试例子

 状态更新提醒模版  template_id => zdcmSDVbJ9SQvUVLeAeWF9XsoWBvE29QR42Tx9gcSaE

模版内容 

{{first.DATA}}
状态来源:{{keyword1.DATA}}
处理进度:{{keyword2.DATA}}
提交时间:{{keyword3.DATA}}
{{remark.DATA}}

代码实现如下

	/**
	 * 状态更新提醒  zdcmSDVbJ9SQvUVLeAeWF9XsoWBvE29QR42Tx9gcSaE

{{first.DATA}}
状态来源:{{keyword1.DATA}}
处理进度:{{keyword2.DATA}}
提交时间:{{keyword3.DATA}}
{{remark.DATA}}
	 */
	public static Map<String,Object> notifyEventChange(String openid,String templateid,String url,String title,String key1,String key2,String key3,String remark){
		Map<String,Object> data =  new HashMap<String,Object>();
		data.put("touser",openid);
		if(StringUtils.isBlank(templateid)){
			templateid = "zdcmSDVbJ9SQvUVLeAeWF9XsoWBvE29QR42Tx9gcSaE";
		}
		data.put("template_id",templateid);
		data.put("url",url);

		Map<String,Object> datasub  = new HashMap<String,Object>();
		
		Map<String,String> firstmap = new HashMap<String,String>();
		firstmap.put("value",title);
		 
		firstmap.put("color","#173177");
		datasub.put("first", JSON.toJSON(firstmap));
		
		Map<String,String> ordermap = new HashMap<String,String>();
		ordermap.put("value",key1);
		ordermap.put("color","#173177");
		datasub.put("keyword1", JSON.toJSON(ordermap));
		
		Map<String,String> statusmap = new HashMap<String,String>();
		statusmap.put("value",key2);
		statusmap.put("color","#173177");
		datasub.put("keyword2", JSON.toJSON(statusmap));
		
		Map<String,String> key3map = new HashMap<String,String>();
		key3map.put("value",key3);
		key3map.put("color","#173177");
		datasub.put("keyword3", JSON.toJSON(key3map));
		
		Map<String,String> remarkmap = new HashMap<String,String>();
		remarkmap.put("value",remark);
		remarkmap.put("color","#173177");
		
		datasub.put("remark",JSON.toJSON(remarkmap));
		data.put("data",JSON.toJSON(datasub));
		return data;
	} 

 

微信接口开发系列之三获取用户信息

关键信息: 微信服务器返回的微信公众号  有效7200秒的access_token 凭据

在有效的时间内,根据access_token,用户openid,获取用户授权的用户信息

关键代码:

// 获取微信用户信息
	public String getUserinfoByTokenOpenid(String accesstoken, String openid) {
		String url = PropertiesUtil.getValue("wx.userinfo");
		// String url =
		// "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
		url = url.replace("ACCESS_TOKEN", accesstoken);
		url = url.replace("OPENID", openid);
		String result = "";
		try {
			// 定义HttpClient
			HttpClient client = new HttpClient();
			// 实例化HTTP方法
			GetMethod request = new GetMethod(url);
			// 定义访问地址的链接状态
			int statusCode = client.executeMethod(request);
			// 客户端请求url数据
			// 请求成功状态-200
			if (statusCode == HttpStatus.SC_OK) {
				// 解决微信用户信息返回乱码的问题
				result = new String(request.getResponseBody(), "utf-8");
			} else {
				log.info("请求返回状态:" + statusCode);
			}
			if (log.isInfoEnabled()) {
				log.info("获取微信用户信息---------" + result);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

微信接口开发系列之二授权

授权  微信公众号用户显式授权

原理      用户关注公众号 或进入指定地址,前端JS-SDK 调用微信授权接口,用户显示确认授权后,微信会给予一个授权码code,通过授权码code 可以去微信服务器获取一个有效时长为7200秒的access-token;

此token具有很重要作用,且获取频率做了日限制100000次/天;测试号则只有2000次/天。

前端授权获取代码略。

服务器代码关键如下:

/**
	 * @param code
	 * @return 根据网页授权code 获取 openid,网页授权的access_token
	 */
	public String getUrlTokenBycode(String code) {
		// String url =
		// "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
		String url = PropertiesUtil.getValue("wx.accessTokenCode");

		// 微信正式公众号
		url = url.replace("APPID", PropertiesUtil.getValue("wx.appid"));
		url = url.replace("SECRET", PropertiesUtil.getValue("wx.appsecret"));
		url = url.replace("CODE", code);

		// 微信公众测试号
		// url = url.replace("APPID", "wxd39f718d218f90a1");
		// url = url.replace("SECRET", "71f7001a9c38fe13e5bb96bd8283f463");
		// url = url.replace("CODE", code);
		String result = "";
		try {
			result = Posturl.getRequest(url);
			if (log.isInfoEnabled()) {
				log.info("根据网页授权code,获取openid,网页授权access_token:---------" + result);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

 

微信接口开发系列之一配置 有更新!

本题主要从技术实现来讲讲微信开发。

微信开发之前,必须先申请微信订阅号/服务号/企业号,不管哪种类型都是微信针对不同专业,领域做的区分,在某些功能上有所限制。

一般在开发之前,都是开发模式,所以在获得了微信号之后,先申请微信测试号进行测试。

第一步:进入公众平台,在左侧菜单栏找到 开发 -- 开发者工具 在右侧选择 公众平台测试帐号 进入

第二步:在 测试号信息 可以看到 appID  和 appsecret 此为后续接口开发重要账号与密钥。

第三步:在 接口配置信息 中,填写以后需要对接微信入口校验以及接收消息接口的url访问地址以及校验参数token。

第四步: 设完配置信息以后,需要在服务器建立一个应用,并对外暴露一个网址即在第三步中填写的访问地址。本人对外的地址为 http://xxx.com/wx/index

主要用于微信服务器校验,接收微信消息通知。

校验主要参数四个: 

signature,timestamp,nonce,echostr
微信消息通知则是需要通过流的接收方式,代码如下


 

public class XMLUtil {
	
	public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		InputStream inputStream = request.getInputStream();
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		Element root = document.getRootElement();
		List<Element> elementList = root.elements();
		for (Element e : elementList)
			map.put(e.getName(), e.getTextTrim());
		inputStream.close();
		inputStream = null;
		return map;
	}

 下面为完整的具体接口关键代码:

/**
 * 
 * 类名称:WeixinController.java 类描述: 微信公共平台开发
 * 
 * @author wyong 
 *  联系方式:343886028
 *  创建时间:2016年1月10日
 * @version 1.0
 */
@Controller
@RequestMapping("/wx")
public class WeixinController extends BaseAction {
	Logger logger = Logger.getLogger(getClass());

	
	@Autowired
	MsgService msgService;
	/**
	 * 微信接口总入口
	 * @param out
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/index")
	public void index(@RequestParam(value = "signature", defaultValue = "") String signature, @RequestParam(value = "timestamp", defaultValue = "") String timestamp,
			@RequestParam(value = "nonce", defaultValue = "") String nonce, @RequestParam(value = "echostr", defaultValue = "") String echostr, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

			if (logger.isInfoEnabled()) {
				logger.info("signature=" + signature + "|timestamp=" + timestamp + "|nonce=" + nonce + "|echostr=" + echostr);
			}
			 
			PrintWriter out = response.getWriter();
			if (StringUtils.isNotBlank(signature) && StringUtils.isNotBlank(timestamp) &&StringUtils.isNotBlank(nonce)&& StringUtils.isNotBlank(echostr)) {/* 接口验证 */
				logger.info("========进入身份验证");
				List<String> list = new ArrayList<String>(3) {
					private static final long serialVersionUID = 2621444383666420433L;
					
					public String toString() { // 重写toString方法,得到三个参数的拼接字符串
						return this.get(0) + this.get(1) + this.get(2);
					}
				};
				list.add(PropertiesUtil.getValue("wx.WEIXIN")); // 读取Token(令牌)
				list.add(timestamp);
				list.add(nonce);
				Collections.sort(list); // 排序
				String tmpStr = new MySecurity().encode(list.toString(), MySecurity.SHA_1); // SHA-1加密
				if (signature.equals(tmpStr)) {
					out.write(echostr); // 请求验证成功,返回随机码
				} else {
					out.write("");
				}
				out.flush();
				out.close();
			} else {/* 消息处理 */
				System.out.println("========进入消息处理");
				Map<String, String> requestMap = XMLUtil.parseXml(request);
				log.error("====="+JSON.toJSON(requestMap));
				//事件推送,是否是发送消息后的事件推送。
				if(requestMap!=null && requestMap.get("MsgType")!=null && "event".equalsIgnoreCase(requestMap.get("MsgType"))){
					String msgid  = requestMap.get("MsgID");
					if(StringUtils.isNotBlank(msgid)){
						TMemNotify notify = msgService.findNotify(msgid);
						if(notify!=null){
							notify.setUpdatetime(new Date());
							notify.setReturnmsg(requestMap.get("Status"));
							msgService.updateObj(notify);
						}
					}
				}
				response.reset();
				log.error(JSON.toJSON(requestMap));
			}
	}

 

   

 

公告

喧哗博客--繁华过后的沉寂--技术经验分享^-^
Copyright (c) 2009-2019, b3log.org & hacpai.com