文章目录

  • 读前必看
  • 测试号推送
  • 天气接口获取数据

谁说程序员不懂浪漫? 将你的关心 推送至微信公众号 给女朋友及时的关怀~(这位同学 你女朋友呢?)

读前必看

关于微信开发平台,小程序和公众号是不一样的,而公众号又会区分订阅号、服务号、测试号,服务号会比订阅号拥有更多权限,而订阅号又区分是否个人主体,很不幸博主一开始在捣鼓的是个人主体的订阅号,试了半天,然后看到了文档 发现这类公众号什么权限都没有:

干得漂亮 … 当然 如果不是个人主体的订阅号 或者是服务号的同学,是可以在这页面继续认证的

那既然这个什么都干不了,我们可以转战测试号,测试号有个很明显的弊端就是公众号名称很难看 还改不了。。。
当然 相信同学们的对象(new Object() ) 是不会嫌弃的

本文主要介绍测试号如何推送,当然 如果你的订阅号不是个人主体 也可以参考一下 基本是差不多的,但如果是个人主体,调用没权限的接口就会报48001。

测试号推送

  1. 首先我们在微信公众号平台 https://mp.weixin.qq.com/ 找到开发者工具
    选择公众平台测试账号

这里需要注意的是 URL需要公网,如果没有服务器域名,我们可以使用免费的内网穿透软件 博主这里使用的是natapp,natapp可以将本地ip端口映射到公网域名

如下图 http://xxxx.xxfree.cc 其实就是127.0.0.1:8080(项目地址)映射的

/wx 是我们项目中的路径 也就是@RequestMapping(“/wx”)

在提交前 我们需要服务端已经写好了接口 用于校验URL 代码如下:


import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
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 javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;@Controller
@RequestMapping("/wx")
public class WeChatUrlController {/*** 用于微信公众号平台URL校验* @param req* @param response* @throws Exception*/@GetMappingpublic void weChatConnect(HttpServletRequest req, HttpServletResponse response) throws Exception {Signature sg = new Signature(req.getParameter("signature"),req.getParameter("timestamp"),req.getParameter("nonce"),req.getParameter("echostr"));ServletInputStream inputStream = req.getInputStream();String s = IOUtils.toString(inputStream, "UTF-8");System.out.println(s);String method = req.getMethod();// 如果是微信发过来的GET请求if ("GET".equals(method)) {if (CheckUtil.checkSignature(sg)) {System.out.println("微信连接成功!");response.setCharacterEncoding("UTF-8");response.getWriter().write(sg.getEchostr());}}}}

public class Signature {private String signature;private String timestamp;private String nonce;private String echostr;public Signature() {super();// TODO Auto-generated constructor stub}public Signature(String signature, String timestamp, String nonce, String echostr) {super();this.signature = signature;this.timestamp = timestamp;this.nonce = nonce;this.echostr = echostr;}public String getSignature() {return signature;}public void setSignature(String signature) {this.signature = signature;}public String getTimestamp() {return timestamp;}public void setTimestamp(String timestamp) {this.timestamp = timestamp;}public String getNonce() {return nonce;}public void setNonce(String nonce) {this.nonce = nonce;}public String getEchostr() {return echostr;}public void setEchostr(String echostr) {this.echostr = echostr;}@Overridepublic String toString() {return "Signature [signature=" + signature + ", timestamp=" + timestamp + ", nonce=" + nonce + ", echostr="+ echostr + "]";}
}

import java.security.MessageDigest;
import java.util.Arrays;public class CheckUtil {// 换成你自己定义的tokenprivate static final String token = "xxxx";public static boolean checkSignature(Signature sg) {String[] arr = new String[] { token, sg.getTimestamp(), sg.getNonce() };// 排序Arrays.sort(arr);// 生成字符串StringBuffer content = new StringBuffer();for (int i = 0; i < arr.length; i++) {content.append(arr[i]);}// sha1加密String temp = getSha1(content.toString());// 比较return temp.equals(sg.getSignature());}// 加密算法public static String getSha1(String str) {if (str == null || str.length() == 0) {return null;}char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };try {MessageDigest mdTemp = MessageDigest.getInstance("SHA1");mdTemp.update(str.getBytes("UTF-8"));byte[] md = mdTemp.digest();int j = md.length;char buf[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];buf[k++] = hexDigits[byte0 >>> 4 & 0xf];buf[k++] = hexDigits[byte0 & 0xf];}return new String(buf);} catch (Exception e) {return null;}}
}
  1. 提交成功后 第二步就是获取用户的openId了

    我们可以引入一个starter 大幅度简化代码 不用再手动去调用url了

            <dependency><groupId>com.github.binarywang</groupId><artifactId>wx-java-mp-spring-boot-starter</artifactId><version>4.0.0</version></dependency>
    

    获取openId的方法 我们同样写在WeChatUrlController, 完整代码变为如下:


import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserService;
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
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 javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;@Controller
@RequestMapping("/wx")
public class WeChatUrlController {@Autowiredprivate WxMpService wxMpService;/*** 用于微信公众号平台URL校验* @param req* @param response* @throws Exception*/@GetMappingpublic void weChatConnect(HttpServletRequest req, HttpServletResponse response) throws Exception {Signature sg = new Signature(req.getParameter("signature"),req.getParameter("timestamp"),req.getParameter("nonce"),req.getParameter("echostr"));ServletInputStream inputStream = req.getInputStream();String s = IOUtils.toString(inputStream, "UTF-8");System.out.println(s);String method = req.getMethod();// 如果是微信发过来的GET请求if ("GET".equals(method)) {if (CheckUtil.checkSignature(sg)) {System.out.println("微信连接成功!");response.setCharacterEncoding("UTF-8");response.getWriter().write(sg.getEchostr());}}}/*** 获取用户的 openId* @param req* @param response* @throws Exception*/@PostMappingpublic void getUserInfo(HttpServletRequest req, HttpServletResponse response) throws Exception {// 方式一 获取所有关注该公众号的用户的openIdWxMpUserService userService = wxMpService.getUserService();WxMpUserList wxMpUserList = userService.userList("");List<String> openIds = wxMpUserList.getOpenids();System.out.println(openIds);// 方式二  让用户在微信公众号发消息 会进入此接口 (POST请求  和我们设置的URL /wx 对应)ServletInputStream inputStream = req.getInputStream();String s = IOUtils.toString(inputStream, "UTF-8");// 打印结果中的 FromUserName节点 <FromUserName><![CDATA[x-xxxx]]></FromUserName>// x-xxxx就是openId了 System.out.println(s);}}
  1. 设置消息模板 在设置URL的同个页面 往下翻 复制模板id
import com.alibaba.fastjson.JSONObject;
import com.qiuhuanhen.sendforyou.entity.WeChatTemplateMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;@Slf4j
@Component
public class Message {@PostConstruct@GetMapping("/sendMessage")public  String sendMessage() {// 模板参数Map<String, WeChatTemplateMsg> sendMag = new HashMap<String, WeChatTemplateMsg>();// 需要替换成你自己的三个参数// openId代表一个唯一微信用户,即微信消息的接收人String openId = "x-xxx";// 消息模板idString templateId = "xxxx";// 微信的基础accessTokenString accessToken ="x-xx-xxx";String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;/***  key和模板id相对应 这里取了两个key做测试 **/sendMag.put("temperatureDay", new WeChatTemplateMsg("111"));sendMag.put("weatherDay", new WeChatTemplateMsg("333"));RestTemplate restTemplate = new RestTemplate();//拼接base参数Map<String, Object> sendBody = new HashMap<>();sendBody.put("touser", openId);               // openIdsendBody.put("url", "www.baidu.com");         // 点击模板信息跳转地址sendBody.put("topcolor", "#FF0000");          // 顶色sendBody.put("data", sendMag);                   // 模板参数sendBody.put("template_id", templateId );      // 模板IdResponseEntity<String> forEntity = restTemplate.postForEntity(url, sendBody, String.class);log.info("结果是: {}",forEntity.getBody());JSONObject jsonObject = JSONObject.parseObject(forEntity.getBody());// 0String messageCode = jsonObject.getString("errcode");// 2431260672639467520String msgId = jsonObject.getString("msgid");System.out.println("messageCode : " + messageCode + ", msgId: " +msgId);return forEntity.getBody();}
}
import lombok.*;@Data
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
public class WeChatTemplateMsg {/** msg **/private String value;private String color;public WeChatTemplateMsg(String value) {this.value = value;}
}
/*** 获取接口访问凭证** @param appid 凭证* @param appsecret 密钥* @return*/public static AccessToken getToken(String appid, String appsecret) {AccessToken token = null;String requestUrl = tokenUrl.replace("APPID", appid).replace("APPSECRET", appsecret);// 发起GET请求获取凭证JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);if (null != jsonObject) {try {token = new AccessToken();token.setAccessToken(jsonObject.getString("access_token"));token.setExpiresIn(jsonObject.getInteger("expires_in"));} catch (JSONException e) {token = null;// 获取token失败log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));}}return token;}

简易效果图:

我们的推送内容 可以是天气预报等等,天气预报推荐用高德开放平台,步骤也比较简单。

天气接口获取数据

首先我们要去高德开放平台申请key

代码如下:

import lombok.Data;@Data
public class Cast {private String date;private String week;private String dayWeather;private String nightWeather;private String dayTemp;private String nightTemp;private String dayWind;private String nightWind;private String dayPower;private String nightPower;
}
import lombok.Data;import java.util.ArrayList;@Data
public class Forecast {private String city;private String adCode;private String province;private String reportTime;private ArrayList<Cast> casts;
}
import lombok.Data;import java.util.ArrayList;@Data
public class WeatherDTO {private String status;private String count;private String info;private String infoCode;private ArrayList<Forecast> forecasts;
}
@Component
public class WeatherJob {/*** 高德开放平台key 需要替换成你自己的*/String AMAP_KEY = "xxx";/*** city code (行政编码 身份证前6位)*/String CITY_CODE = "440100";@Scheduled(cron = "0 0 10 * * ?")public void getWeather() throws IOException {String weatherUrl = "https://restapi.amap.com/v3/weather/weatherInfo?city=" + CITY_CODE + "&key=" + AMAP_KEY + "&extensions=all";StringBuffer result = new StringBuffer();BufferedReader in = null;try {URL url = new URL(weatherUrl);URLConnection connection = url.openConnection();in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result.append(line);}in.close();} catch (IOException e) {e.printStackTrace();} finally {if (null != in)in.close();}WeatherDTO weatherDTO = JSON.parseObject(result.toString(), WeatherDTO.class);System.out.println(weatherDTO);Forecast forecast = weatherDTO.getForecasts().get(0);String city = forecast.getCity();String reportTime = forecast.getReportTime();ArrayList<Cast> casts = weatherDTO.getForecasts().get(0).getCasts();Cast today = casts.get(0);String todayDayWeather = today.getDayWeather();String todayNightWeather = today.getDayWeather();String todayDayTemp = today.getDayTemp();String todayNightTemp = today.getDayTemp();String todayDayPower = today.getDayPower();String todayNightPower = today.getDayPower();String currentReport = "【" + city + "】: 当前时间" + reportTime + "\n" + "[今日天气]:" +"\n白天  " + todayDayWeather + " " + todayDayTemp + "°C" + " 风力" + todayDayPower + "级;" +"\n晚上  " + todayNightWeather + " " + todayNightTemp + "°C" + " 风力" + todayNightPower + "级";}

【java】java天气消息推送至微信公众号详细教程相关推荐

  1. php app 推送原理,微信公众号开发的那点事第一篇——消息推送原理

    微信公众平台从诞生开始到现在已经积累了海量的公众号,这其中有大量的个人运营者.为了让公众号更好滴为粉丝们服务,微信官方提供了很多接口,使用这些接口来丰富公众号的功能对于有些个人运营者来说可能并不熟悉. ...

  2. python爬取微信公众号推送_微信公众号推送信息爬取---python爬虫

    问题描述 利用搜狗的微信搜索抓取指定公众号的最新一条推送,并保存相应的网页至本地. 注意点 搜狗微信获取的地址为临时链接,具有时效性. 公众号为动态网页(JavaScript渲染),使用request ...

  3. 【Java集成小米消息推送(海外版)】

    Java集成小米消息推送(海外版) 注册登录: 小米推送运营中心 提交需要的信息,一般为包名等信息(或直接让Android开发提交) 需要的配置信息 1.App Secret 2.Package na ...

  4. Java版WebSocket消息推送系统搭建

    Java版WebSocket消息推送系统搭建 最近在做消息推送,网上查了一些资料,开始想的是用MQ来做,后面发现用WebSocket来做的话感觉应该要简单点,话不多说,准备撸代码. 后端核心代码 /* ...

  5. python自动推送消息_Python自动接收微信群消息并推送相应的公众号文章

    原标题:Python自动接收微信群消息并推送相应的公众号文章 封面图片:<Python程序设计基础与应用>(ISBN:9787111606178),董付国,机械工业出版社 用书教师可以联系 ...

  6. 公众平台模板消息所在行业_微信公众号模板消息功能怎么快速推送?

    公众号平台上模板消息功能仅支持添加模板和更改所在行业,不支持模板消息推送,如果想要实现更多功能效果,可以使用微号帮平台的模板消息群发功能实现,也可以通过公众号平台的接口自己开发实现功能,均可以达到微信 ...

  7. 微信公众号开发java流程_微信公众号开发教程java 编程语言的特点及选择

    微信公众号开发教程java 编程语言的特点及选择 微信公众号为用户提供了相关的工具,来对微信公众号进行一个简单的开发.但是如果想实现一些复杂的功能,其实还是要借助于一些编程语言的使用.所以要了解,在微 ...

  8. ➢ 微信公众号运营教程(三)熟悉一些实用的工具 编写第一篇公众号推文

    ➢ 微信公众号运营教程(三) 熟悉一些实用的工具 & 编写第一篇公众号推文 实用的一些工具 ①浏览器:Google Chrome谷歌浏览器 ②图片素材 首先,我们编写文章的时候,需要一些配图, ...

  9. 微信公众号开发教程(一) 验证接入

    作者:陈惠,叩丁狼教育高级讲师.原创文章,转载请注明出处. 微信公众号开发教程(一)验证接入 本篇文章主要介绍了微信公众号开发接入详细流程,希望对刚接触公众号开发的同学有所帮助,有兴趣的同学可多多关注 ...

最新文章

  1. 活动报名 | 新国立尤洋:FastFold——将AlphaFold训练时间从11天减少到67小时
  2. 100教育:一场与信任赛跑的赌注
  3. 微信小程序开发第二弹
  4. python入门基础代码图-【01】Python基础入门 (全)
  5. bat php 监控网站,HTML_进程监控实现代码[vbs+bat],运行后会在%windir%\system32\目录 - phpStudy...
  6. (二)git常用基本概念
  7. 因为喜欢,所以选择它
  8. docker lnmp php
  9. java 获取服务器IP地址及MAC地址
  10. 读《程序员修炼之道——从小工到专家》
  11. 数据结构笔记(十八)-- 树的定义和基本术语
  12. Spring 源码分析(三) —— AOP(二)Spring AOP 整体架构
  13. ARToolkit介绍
  14. 扇贝有道180913每日一句
  15. 深入理解Nginx:模块开发与架构解析阅读--Nginx架构设计简介
  16. 基于java的在校大学生贷款管理系统
  17. 9款主流图表控件轻松实现数据可视化
  18. 小米笔记本pro lol测试软件,小米笔记本Pro 15增强版游戏性能测评
  19. 硕士论文查重原理是什么?
  20. WIN10合并磁盘扩展区是灰色的

热门文章

  1. 用于LaTeX Python代码展现的minted包的安装及运行该包时TeXworks编译命令的设置
  2. Dell戴尔笔记本电脑G5 15 5500原装出厂系统2004恢复原厂系统
  3. 2022-2028年中国痔疮药品行业运营现状及投资前景预测报告
  4. html夸女生的代码,抖音上夸女孩子漂亮的语句
  5. 估计下星期就能考科目二了
  6. 事务和事务的隔离级别及脏读、幻读
  7. Transformer(李宏毅老师Transforme PPT截图)
  8. .net开发下简单的增删改查
  9. 【Excel】求和的几种方式
  10. html css投影效果,CSS添加阴影效果