httpClient实现微信公众号消息群发

1、实现功能 

  向关注了微信公众号的微信用户群发消息。(可以是所有的用户,也可以是提供了微信openid的微信用户集合)

2、基本步骤

前提:

  已经有认证的公众号或者测试公众账号

发送消息步骤:

  1. 发送一个请求微信去获取access_token
  2. 发送一个请求去请求微信发送消息

相关微信接口的信息可以查看:http://www.cnblogs.com/0201zcr/p/5866296.html 有测试账号的申请 + 获取access_token和发送微信消息的url和相关的参数需求。各个参数的意义等。

3、实践

  这里通过HttpClient发送请求去微信相关的接口。

1)maven依赖

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.3.1</version>
</dependency>

2)httpClient使用方法

使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。

  1. 创建HttpClient对象。
  2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
  3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
  4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
  5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
  6. 释放连接。无论执行方法是否成功,都必须释放连接——这里使用了连接池,可以交给连接池去处理

 3)实例

1、发送请求的类

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.seewo.core.util.json.JsonUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** Created by zhengcanrui on 16/9/20.*/
public class WechatAPIHander {/*** 获取token接口*/private String getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";/*** 拉微信用户信息接口*/private String getUserInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}";/*** 主动推送信息接口(群发)*/private String sendMsgUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}";private HttpClient webClient;private Log log = LogFactory.getLog(getClass());public void initWebClient(String proxyHost, int proxyPort){this.initWebClient();if(webClient != null && !StringUtils.isEmpty(proxyHost)){HttpHost proxy = new HttpHost(proxyHost, proxyPort);webClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);}}/*** @desc 初始化创建 WebClient*/public void initWebClient() {log.info("initWebClient start....");try {PoolingClientConnectionManager tcm = new PoolingClientConnectionManager();tcm.setMaxTotal(10);SSLContext ctx = SSLContext.getInstance("TLS");X509TrustManager tm = new X509TrustManager() {@Overridepublic void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {}@Overridepublic void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {}@Overridepublic java.security.cert.X509Certificate[] getAcceptedIssuers() {return new java.security.cert.X509Certificate[0];}};ctx.init(null, new X509TrustManager[] { tm }, null);SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);Scheme sch = new Scheme("https", 443, ssf);tcm.getSchemeRegistry().register(sch);webClient = new DefaultHttpClient(tcm);} catch (Exception ex) {log.error("initWebClient exception", ex);} finally {log.info("initWebClient end....");}}/*** @desc 获取授权token* @param appid* @param secret* @return*/public String getAccessToken(String appid, String secret) {String accessToken = null;try {log.info("getAccessToken start.{appid=" + appid + ",secret:" + secret + "}");String url = MessageFormat.format(this.getTokenUrl, appid, secret);String response = executeHttpGet(url);Map map = JsonUtils.jsonToMap(response);accessToken = (String) map.get("access_token");/* Object Object = JSONUtils.parse(response);accessToken = jsonObject.getString("access_token");*/
//                accessToken = JsonUtils.read(response, "access_token");} catch (Exception e) {log.error("get access toekn exception", e);}return accessToken;}/*** @desc 推送信息* @param token* @param msg* @return*/public String sendMessage(String token,String msg){try{log.info("\n\nsendMessage start.token:"+token+",msg:"+msg);String url = MessageFormat.format(this.sendMsgUrl, token);HttpPost post = new HttpPost(url);ResponseHandler<?> responseHandler = new BasicResponseHandler();//这里必须是一个合法的json格式数据,每个字段的意义可以查看上面连接的说明,content后面的test是要发送给用户的数据,这里是群发给所有人msg = "{\"filter\":{\"is_to_all\":true},\"text\":{\"content\":\"test\"},\"msgtype\":\"text\"}\"";//设置发送消息的参数StringEntity entity = new StringEntity(msg);//解决中文乱码的问题entity.setContentEncoding("UTF-8");entity.setContentType("application/json");post.setEntity(entity);//发送请求String response = (String) this.webClient.execute(post, responseHandler);log.info("return response=====start======");log.info(response);log.info("return response=====end======");return response;}catch (Exception e) {log.error("get user info exception", e);return null;}}/*** @desc 发起HTTP GET请求返回数据* @param url* @return* @throws IOException* @throws ClientProtocolException*/private String executeHttpGet(String url) throws IOException, ClientProtocolException {ResponseHandler<?> responseHandler = new BasicResponseHandler();String response = (String) this.webClient.execute(new HttpGet(url), responseHandler);log.info("return response=====start======");log.info(response);log.info("return response=====end======");return response;}}

 2、Controller和Service层调用

  @RequestMapping(value = "/testHttpClient", method = RequestMethod.GET)public DataMap test() {WechatAPIHander wechatAPIHander = new WechatAPIHander();//获取access_token
      //第一个参数是你appid,第二个参数是你的秘钥,需要根据你的具体情况换String accessToken = wechatAPIHander.getAccessToken("appid","scerpt"); //发送消息wechatAPIHander.sendMessage(accessToken, "测试数据");return new DataMap().addAttribute("DATA",accessToken);}

 3、结果

  假如你关注了微信公众号中看到你刚刚发送的test消息。

HttpClient学习文档:https://pan.baidu.com/s/1miO1eOg

 致谢:感谢您的阅读

转载于:https://www.cnblogs.com/0201zcr/p/5893600.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为静态博客生成器WDTP移植了一款美美哒主题

前言 关于这个主题的移植后公布&#xff0c;我已经联系了主题作者并取得同意&#xff0c;这个主题是一夜涕所写的Sgreen&#xff0c;预览图见下 关于WDTP 就是一个很方便很便携很快速的cpp编写的带gui跨平台的开源的静态博客生成器&#xff0c;软件作者更新记录在V站可以找到,软…

TCP/IP数据包结构分析

一般来说&#xff0c;网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作&#xff0c;但是一些特殊的情况下&#xff0c;就需要深入的理解 网络数据包的结构&#xff0c;以及协议分析。如&#xff1a;网络监控&#xff0c;故障排查等…… IP包是不安全的&am…

C#decimal数据类型

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 为适应高精度的财务和货币计算的需要&#xff0c;C#提供了十进制decimal类型。decimal类型数据特征如下表所示&#xff1a; 数据类型含义取值范围有效数字位数decimal128位高精度十进制…

世界杯快到了,看我用Python爬虫实现(伪)球迷速成!

还有4天就世界杯了&#xff0c;作为一个资深&#xff08;伪&#xff09;球迷&#xff0c;必须要实时关注世界杯相关新闻&#xff0c;了解各个球队动态&#xff0c;这样才能在一堆球迷中如&#xff08;大&#xff09;鱼&#xff08;吹&#xff09;得&#xff08;特&#xff09;水…

Bootstrap学习笔记(四)-----Bootstrap每天必学之表单

本文主要讲解的是表单&#xff0c;这个其实对于做过网站的人来说&#xff0c;并不陌生&#xff0c;而且可以说是最为常用的提交数据的Form表单。本文主要来讲解一下内容&#xff1a; 1.基本案例2.内联表单3.水平排列的表单4.被支持的控件5.静态控件6.控件状态7.控件尺寸8.帮助文…

LVS--NAT模型配置

环境准备 管理IP地址角色备注192.168.11.131调度器&#xff08;Director&#xff09;对外提供VIP服务的地址为192.168.1.114192.168.11.132RS1 网关为192.168.11.131192.168.11.129RS2 网关为192.168.11.131将Directory开启内核转发 Linux系统默认是禁止数据包转发的。所谓转发…

STL中list的使用(理论)

STL中的list就是一双向链表&#xff0c;可高效地进行插入删除元素。现总结一下它的操作。文中所用到两个list对象c1,c2分别有元素c1(10,20,30) c2(40,50,60)。还有一个list<int>::iterator citer用来指向c1或c2元素。list对象的声明构造()&#xff1a;A. list<in…

C#数据类型转换—使用Convert类转换

文章目录简介用例博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 简介 System.Covert类就是专门进行类型转换的类&#xff0c;Convert类提供的方法可以实现各种进本数据类型之间的转换。Convert类的常用方法如下表&#xff1a; 方法说明ToBo…

服务器租用单线、双线、bgp 相比有哪些区别优势?

2019独角兽企业重金招聘Python工程师标准>>> 在IDC行业中&#xff0c;服务器的稳定性、安全性是考核服务商的主要指标&#xff0c;影响这两个指标的因素有很多&#xff0c;其中比较重要的有三个&#xff0c;分别是服务器的配置、机房骨干网宽带和机房的线路。我们常…

SQL Server 数据库的维护(四)__游标(cursor)

--维护数据库-- --游标(cursor)-- --概述&#xff1a; 注&#xff1a;使用select语句查询结果的结果集是一个整体&#xff0c;如果想每次处理一行或一部分行数据&#xff0c;游标可以提供这种处理机制。可以将游标理解为指针。指针指向哪条记录&#xff0c;哪条记录即是被操作记…

关于在unity中动态获取字符串后在InputField上进行判断的BUG

今天想做一个简单的密码锁定控制功能&#xff0c;但是出现了问题。我是在游戏开始时读取streamingAsset中的text中的文本&#xff0c;其实就是密码如下图密码是123456789 然后我在程序中输入了该密码出现错误&#xff0c;居然错了。 然后我打印读取的文本信息是什么、没错啊。然…

转载 调用xvid 实现解码

2011-06-01 00:26:14) 转载view plaincopy to clipboardprint? /// intinit_decoder() { intret; xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_txvid_dec_create; memset(&xvid_gbl_init, 0,sizeof(xvid_gbl_init_t)); memset(…

C# 数值和字符串之间的相互转换

文章目录方法用例ToString&#xff08;&#xff09;方法Parse&#xff08;&#xff09;方法博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 方法 ToString&#xff08;&#xff09;方法&#xff1a;数值类型的 ToString&#xff08;&#xff…

LeetCode Reverse Words in a String III

原题链接在这里&#xff1a;https://leetcode.com/problems/reverse-words-in-a-string-iii/#/description 题目&#xff1a; Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial wo…

创业感悟:技术兄弟为什么一直没有起来(1)

相信很多做技术的朋友&#xff0c;看到“人脉”两个字&#xff0c;就显得有些敏感&#xff0c;有人甚至产生一种“抵触”的心理。 因为在很多人的心中&#xff0c;会自动的把“人脉”和“关系”关联起来&#xff0c;会把“人脉”与“走后门”&#xff0c;甚至会和“酒桌文化”&…

kali开启ssh

修改 vi /etc/ssh/sshd_config 1.将 permitrootlogin 前面的注释去掉,并且后面改为yes 如果没有则添加permitrootlogin yes 2.将#PasswordAuthentication no的注释去掉&#xff0c;并且将NO修改为YES //kali中默认是yes 3.按Esc , 同时按shift和冒号键 ,输入wq &#xff0c;回…

C# 引用类型与值类型转换-装箱和拆箱

文章目录简介用例装箱拆箱博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 简介 拆箱就是把 “引用” 类型转化为 “值” 类型&#xff1b; 装箱就是把 “值” 类型转化为 “引用” 类型&#xff1b; 装箱与拆箱是数据类型转换的一种特殊应用…

XVID基本参数解析

XVID&#xff0c;X264等是MPEG4、H264标准的开源编码器&#xff0c;其中X264只有编码部分&#xff0c;解码部分需要FFMPEG完成&#xff1b;XVID有编解码部分&#xff0c;其中解码亦可以利用FFMPEG中的MPEG4完成解码。视频压缩算法的计算复杂度&#xff0c;都是比较高的。其中具…

自己整理的openresty安装步骤

这几天一直在研究对webapi的限流和名单的问题&#xff0c;于是看了开涛博客的方案&#xff0c;于是就用到了openresty&#xff0c;一个把Nginx和lua集成的东西。 下面就是整理的安装方案&#xff08;简单使用基本可以这么安装&#xff09; 下载openresty&#xff08;centos上下…

京东入职一周感悟:4个匹配和4个观点

入职一周啦&#xff0c;随便写点。一、京东之缘1、我和京东之间的4点匹配Ⅰ技术2008年9月到2016年9月&#xff0c;一直坚持自学技术。京东&#xff0c;是一家商业化的互联网公司&#xff0c;有技术积淀&#xff0c;有发挥空间。作为技术人员&#xff0c;职业匹配。Ⅱ读书大学的…