weixin

您所在的位置:网站首页 扫码关注公众号平台 weixin

weixin

2024-06-30 17:36:21| 来源: 网络整理| 查看: 265

(java)微信公众号开发 之 扫码关注 获取OPPENID 对该OPPENID发送相关的信息

因为公司项目需要对接微信公众号平台,所以把自己的笔记整理在此,先写下大概的项目需求,具体操作往下看。

博客地址:https://blog.csdn.net/weixin_44254243/article/details/112346782

项目需求:

顾客在我们项目平台提交一个申请,这个填写的申请单中有一个手机号必填。 提交完我们会生成一个二维码,该二维码是携带参数(手机号)请求微信公众平台所返回的二维码(要点:1.获取access_token,2.获取Ticket来换取二维码) 顾客扫描二维码之后,微信平台会推送消息到我们自己项目.(要点:对微信推送的消息进行解析,并响应微信服务器)此时也就获取到了oppenID 我们获取到了oppenid,根据oppenid来给该oppenID用户发送任意的消息。 1.微信公众平台接口的配置

首先我们要对接微信公众平台,需要在该平台微信公众平台地址 开发->开发者工具->公众平台测试账号中进行配置 见下图 开发-开发者工具- 公众平台测试账号 具体配置

在配置下图的URL的时候需要先在程序中写你要写的URL接口,我这里是http://******/sys/wx 废话不多说了 直接上代码了。

@Controller @RequestMapping("/sys") public class WxController { private static final Logger log = LoggerFactory.getLogger(WxController.class); /** * 微信服务器 对 微信公众号管理平台的 服务器地址(URL) 进行校验 * @param signature * @param timestamp * @param nonce * @param echostr * @return */ @GetMapping("/wx") @ResponseBody public String firstWxVerify(@RequestParam(value="signature",required=false) String signature, @RequestParam(value="timestamp",required=false) String timestamp, @RequestParam(value="nonce",required=false) String nonce, @RequestParam(value="echostr",required=false) String echostr){ System.out.println(" 微信服务端返回的数据 用于校验 微信配置中心的网址是否正确: >>>" + signature + "\t" + timestamp + "\t" + nonce + "\t" + echostr); log.info("开始签名验证:"+" PARAM VAL: >>>" + signature + "\t" + timestamp + "\t" + nonce + "\t" + echostr); if (StringUtils.isNotEmpty(signature) && StringUtils.isNotEmpty(timestamp) &&StringUtils.isNotEmpty(nonce) && StringUtils.isNotEmpty(echostr)) { String sTempStr = ""; if (StringUtils.isNotEmpty(signature) ) { log.info("验证成功:-----------:"+sTempStr); return echostr; } else { log.info("验证失败:-----------:00000"); return "-1"; } } else { log.info("验证失败:-----------:11111"); return "-1"; } } }

在此没有对signature签名进行再次加密 对比 需要的大佬可以自行对比 这个步骤完成就可以进行下面的URL配置啦。

配置 ==消息模板配置== 这个在给对应的oppenID发送消息的时候需要用到 消息模板 上面的配置完以后,就需要进行程序开发了

2. 获取access_token

直接上代码了

编写token实体类:

public class Token { //接口访问凭证 private String accessToken; //凭证有效期 秒 private int expiresIn; private Long timestamp=System.currentTimeMillis(); public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } }

获取token(在此appid,secret,这两个参数 自行去修改成自己的)

public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /** * 直接获取token ---->> 微信服务器 * token 失效时间 7100 * @return */ private static Token getTokenByAppidAndAppsecret() { Token token = null; String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", secret); // 发起GET请求获取凭证 String result = HttpClientUtil.doGet(requestUrl); JSONObject jsonObject = JSONObject.parseObject(result); log.info("获取Token返回结果----->;WxHelper-getTokenByAppidAndAppsecret:"+jsonObject); if (null != jsonObject) { token = new Token(); String access_token = jsonObject.getString("access_token"); if(null != access_token && !"".equals(access_token)){ token.setAccessToken(access_token); token.setExpiresIn(jsonObject.getIntValue("expires_in")); }else { token = null; // 获取token失败 log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getIntValue("errcode"), jsonObject.getString("errmsg")); } } return token; } 3.获取Ticket来换取二维码

直接上代码 实体类

public class QRcodeDto { //成功返回值 //获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。 private String ticket; //二维码图片解析后的地址,开发者可根据该地址自行生成需要的二维码图片 private String url; //该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 private long expire_seconds; //二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值 private String action_name; //二维码详细信息 private Map action_info; /* //场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000) private String scene_id; //场景值ID(字符串形式的ID),字符串类型,长度限制为1到64 private String scene_str; */ getter setter 省略 }

获取二维码

public final static String ticket_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; //请求二维码 public final static String QRcode_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET"; /** * 获取Ticket来换取二维码 * @param tokenBySession * @param params * @return */ private static QRcodeDto getTicket(String tokenBySession, String params) { QRcodeDto qRcode = null; String requestUrl = ticket_url.replace("ACCESS_TOKEN", tokenBySession); String doPostResult = HttpClientUtil.doPostSSL(requestUrl,params); //String doPostResult = HttpClientUtil.doPost(requestUrl, params); log.info("************获取Ticket来换取二维码***********,{}",doPostResult); JSONObject jsonObject = JSONObject.parseObject(doPostResult); if (null != jsonObject) { try { return JSON.parseObject(doPostResult,QRcodeDto.class); } catch (JSONException e) { qRcode = null; // 获取Ticket失败 log.error("获取Ticket失败 errcode:{} errmsg:{}", jsonObject.getIntValue("errcode"), jsonObject.getString("errmsg")); } } return qRcode; } /** * 生成二维码(关注公众号) * @return */ public static String makeQRcodeByPhone(String phone){ String tokenBySession = getTokenByAppidAndAppsecret(); if(null != tokenBySession && !"".equals(tokenBySession)){ //phone 需要跟 微信关联 //封装二维码信息 QRcodeDto qRcode = new QRcodeDto(); qRcode.setExpire_seconds(7200l); //二维码类型 qRcode.setAction_name("QR_STR_SCENE"); Map mapMap = new HashMap(); Map map = new HashMap(); map.put("scene_str", phone); mapMap.put("scene", map); qRcode.setAction_info(mapMap); //Map params = JSON.parseObject(JSON.toJSONString(qRcode), Map.class); //去获二维码地址 QRcodeDto qRcodeDto = getTicket(tokenBySession, JSON.toJSONString(qRcode)); //根据二维码地址去保存到本地 并返回本地二维码地址 String qRcode2 = getQRcode(qRcodeDto.getTicket()); return qRcode2; }else { return "token为空!请检查对接微信平台的方法!"; } } /** * 获取下载二维码地址 * @param ticket * @return */ private static String getQRcode(String ticket) { String requestUrl = QRcode_url.replace("TICKET", ticket); String download = downloadByNet(requestUrl, ticket); return download; } /** * 下载二维码 * @param requestUrl * @param ticket * @return */ private static String downloadByNet(String requestUrl, String ticket) { // 构造URL URL url = null; try { url = new URL(requestUrl); // 打开连接 URLConnection con = url.openConnection(); // 输入流 InputStream is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[4056]; // 读取到的数据长度 int len; long l = System.currentTimeMillis(); // 输出的文件流 String filename = "/qr/"+l+".jpg"; //下载路径及下载图片名称 File files = new File("/qr"); if (!files.exists()) { files.mkdirs();// 创建文件根目录 } File file = new File(filename); FileOutputStream os = new FileOutputStream(file, true); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // 完毕,关闭所有链接 os.close(); is.close(); return "/profile/qr/"+l+".jpg"; } catch (Exception e) { return null; } } 3.获取oppenID,顾客扫描二维码之后,微信平台会推送消息到我们自己项目.

实体类 wxPushMessage

/** * 微信推送过来的数据 * 微信API :https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html#%E5%85%B3%E6%B3%A8/%E5%8F%96%E6%B6%88%E5%85%B3%E6%B3%A8%E4%BA%8B%E4%BB%B6 */ @Root(name = "xml", strict = false) public class WxPushMessage { //开发者微信号 @Element(name = "ToUserName") private String ToUserName; //发送方帐号(一个OpenID) @Element(name = "FromUserName") private String FromUserName; //消息创建时间 (整型) @Element(name = "CreateTime", required = false) private Long CreateTime; //消息类型,event @Element(name = "Event", required = false) private String Event; //事件类型,subscribe @Element(name = "MsgType", required = false) private String MsgType; @Element(name = "CardId", required = false) private String CardId; @Element(name = "UserCardCode", required = false) private String UserCardCode; @Element(name = "ModifyBonus", required = false) private Integer ModifyBonus; // 事件KEY值,qrscene_为前缀,后面为二维码的参数值 @Element(name = "EventKey", required = false) private String EventKey=""; public void setEventKey(String eventKey) { if (eventKey.startsWith("qrscene_")){ EventKey=eventKey.replace("qrscene_",""); }else { EventKey = eventKey; } } }

获取oppenID

@Controller @RequestMapping("/sys") public class WxController { private static final Logger log = LoggerFactory.getLogger(WxController.class); /** * //微信方回调 * @param body 微信回调传送的参数 * @return String 返回一个空串告诉微信服务器 接受到了响应 */ @PostMapping("/wx") @ResponseBody public String wxCallBack(@RequestBody String body){ //接受到微信的数据后解析为javabean WxPushMessage wxPushMessage = (WxPushMessage) XmlUtil.fromXML(body,WxPushMessage.class); System.out.println("=========wxPushMessage==========="+wxPushMessage); if(null != wxPushMessage){ //开发者微信号 String toUserName = wxPushMessage.getToUserName(); //FromUserName String fromUserName = wxPushMessage.getFromUserName(); //消息创建时间 (整型) Long createTime = wxPushMessage.getCreateTime(); //消息类型,event String msgType = wxPushMessage.getMsgType(); // 事件类型,subscribe->订阅 unsubscribe取消 String event = wxPushMessage.getEvent(); // 事件KEY值,qrscene_为前缀,后面为二维码的参数值 String eventKey = wxPushMessage.getEventKey(); //表示消息推送类型是订阅 SCAN消息推送类型是 之前关注过 if(null != event && ("subscribe".equals(event) || "SCAN".equals(event))){ // eventKey 之前传递的值 phone //TODO 关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。 // 更新数据库 将openid 和 phone绑定 return ""; }else if(null != event && "unsubscribe".equals(event)){//消息推送类型是 取消订阅 // 更新数据库 将openid 和 phone解除绑定 return ""; }else { return ""; } }else { return ""; } } } 4. 我们获取到了oppenid,根据oppenid来给该oppenID用户发送任意的消息。

实体类

/** * @author YangJY * @date 2020-01-07 * 发送模板消息 * 接口调用请求说明 * http请求方式: POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN */ public class SendData { private String value; private String color="#173177"; }

发送消息

@Controller @RequestMapping("/sys") public class WxController { //发送消息 public final static String news_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN"; private static final Logger log = LoggerFactory.getLogger(WxController.class); @GetMapping("/send") @ResponseBody public Map send(HttpSession session){ Map hashMap = new HashMap(); hashMap.put("touser","oBxBQ6Jd5pJL3LoqGGteYoDSDoTE"); hashMap.put("template_id","05DNtwB1aVSvCKvftU00XnzVX8daAbGwBWSLqbN_4-w"); //hashMap.put("url",""); //非必填 //hashMap.put("miniprogram",null); //非必填 //现在封装data-> SendData //创建data的对象map Map data = new HashMap(); SendData firstData = new SendData(); firstData.setValue("隔壁老王"); data.put("first",firstData); SendData keyword1 = new SendData(); keyword1.setValue("艹"); data.put("keyword1",keyword1); hashMap.put("data",data); String o = JSONObject.toJSONString(hashMap); log.info("hashMap:==================== ,{}",hashMap); log.info("String:====================,{}",o); send(hashMap,session); return hashMap; } } /** * 发送消息 * @param data * @return */ public static boolean send( Map data,HttpSession session) { String token = getTokenByAppidAndAppsecret(session); if(null != token && !"".equals(token)){ String requestUrl = news_url.replace("ACCESS_TOKEN", token); String toJSONString = JSON.toJSONString(data); log.info("***************发消息的参数******************{}",toJSONString); String doPostSSLResult = HttpClientUtil.doPostSSL(requestUrl, toJSONString); log.info("***************发送消息******************{}",doPostSSLResult); JSONObject jsonObject = JSONObject.parseObject(doPostSSLResult); if (null != jsonObject) { return true; } return false; }else { log.error("WxHelper.send() 中 token 为空"); return false; } }

==效果== 效果

博客地址:https://blog.csdn.net/weixin_44254243/article/details/112346782



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭