目录

从零接入微信公众号

一、微信测试号的申请与关注

1.申请

2.访问域名配置

3.关注

二、测试号快速生成底部导航栏

1.获取 access_token

2.自定义菜单

三、微信公众号网页授权

1.网页授权原理

2.代码实现

1)NetUtil.java

2)Oauth2Token.java

3)WxUserDO.java

4)WxController

3.测试

4.整合

四、公众号视频资源分享


从零接入微信公众号



提前准备:

1.一台云服务器(配置好web项目环境)

2.一个域名(https 或者 http)

关于服务器的,如果你是小白可以看我的其他博客:

CentOS 服务器配置 jdk +Tomcat + mysql

基于腾讯云的域名绑定和 tomcat 部署

腾讯云申请免费 ssl 证书+tomcat配置https

本文是直接上代码,有些需要修改和解释都会说明。


一、微信测试号的申请与关注

1.申请

刚刚开始做微信公众号的时候,我们建议选择微信测试号就好,等熟悉了之后,微信公众号的配置什么的,跟测试号是一样的。

接下来就交大家怎么来申请测试号。

首先进入微信公众号的开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

2.访问域名配置

找到  JS 接口安全域名修改 填写上自己的域名。然后考虑我们会在测好中里面进行网页的跳转操作,所以我们需要在网页账号功能这边填上授权的域名,如下图。

3.关注

登录微信测试号页面,找到测试号二维码,然后用自己的微信号扫码,使自己的微信账号位于用户列表中。

二、测试号快速生成底部导航栏

https://mp.weixin.qq.com/debug/cgi-bin/apiinfo?t=index

1.获取 access_token

打开上面的链接,按下图选择,然后填上 appid 和 secret ,点击检查问题,就能获取到 access_token 了。

2.自定义菜单

按下图的提示选,然后 access_token 已经在上面查询到了,复制下来就好,body 则是填入对应的 json 串,下面已经提供了 demo ,直接复制就好。

{"button": [{"name": "我的","sub_button": [{"type": "scancode_waitmsg","name": "扫码藏书","key": "rselfmenu_0_0","sub_button": []},{"type": "view","name": "我的书房","url": "http://127.0.0.1/index.php"}]},{"name": "关于","sub_button": [{"type": "view","name": "关于我们","url": "http://127.0.0.1/index.php"}]}]
}

点击 检查问题,往下拉查看返回结果。下图为成功的返回。

然后进入刚刚关注的微信测试号,就可以看到底部已经出现了对应的导航按钮了。

三、微信公众号网页授权

如果用户在微信客户端上访问第三方的网页,公众号可以通过微信网页授权机制,来获取用户信息,进而实现业务逻辑。

1.网页授权原理

1)引导用户进入授权页面同意授权,获取 code

2)通过 code 换取网页授权 access_token

3)如果需要,开发者可以刷新网页授权 access_token ,避免过期

4)通过网页授权 access_token 和 openid 获取用户基本信息

2.代码实现

NetUtil.java:实现 http 发送服务

Oauth2Token:存放 access_token 等信息的实体类

WxUserDO:存放用户信息的实体类

WxController:具体实现的控制层

下面的源码中都附带了导入的包名。

1)NetUtil.java

package com.controller.wechat;import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class NetUtil {public static final Logger log = LoggerFactory.getLogger(NetUtil.class);public static CloseableHttpClient httpClient = HttpClientBuilder.create().build();/*** get 请求获取String类型数据* @param url* @return*/public static String get(String url) {log.info("get 请求开始 ...");StringBuffer sb = new StringBuffer();HttpGet httpGet = new HttpGet(url);    try {HttpResponse response =  httpClient.execute(httpGet);HttpEntity entity = response.getEntity();InputStreamReader reader = new InputStreamReader(entity.getContent(), "utf-8");char [] charbuffer;while(0 < reader.read(charbuffer=new char[10])) {sb.append(charbuffer);}}catch(IOException e) {e.printStackTrace();}finally {httpGet.releaseConnection();}log.info(sb.toString());log.info("get 请求开始 ...");return sb.toString();}/*** post 请求获取数据* @param url* @param data* @return*/@SuppressWarnings("unchecked")public static String post(String url, Map<String,String> data) {log.info("post 请求开始 ...");StringBuffer sb = new StringBuffer();HttpPost httpPost = new HttpPost(url);ArrayList<NameValuePair> valuePairs = new ArrayList<NameValuePair>();if(null != data) {for(String key : data.keySet()) {valuePairs.addAll((Collection<? extends NameValuePair>) new BasicNameValuePair(key, data.get(key)));}}try {HttpResponse response = httpClient.execute(httpPost);HttpEntity httpEntity = response.getEntity();BufferedInputStream bis = new BufferedInputStream(httpEntity.getContent());byte [] buffer;while(0 < bis.read(buffer=new byte[128])) {sb.append(new String(buffer,"utf-8"));}}catch(UnsupportedEncodingException e) {//数据格式有误e.printStackTrace();}catch (IOException e) {//请求出错e.printStackTrace();}finally {httpPost.releaseConnection();}log.info(sb.toString());log.info("post 请求开始 ...");return sb.toString();}
}

2)Oauth2Token.java

package com.controller.wechat;public class Oauth2Token {private String accessToken; //网页授权接口调用凭证private int expiresIn; //凭证有效时长private String refreshToken; //用于刷新凭证private String openId; //用户标识private String scope; //用户授权作用域// get 和 set 方法  @Overridepublic String toString() {return "Oauth2Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn + ", refreshToken=" + refreshToken+ ", openId=" + openId + ", scope=" + scope + "]";}
}

3)WxUserDO.java

package com.controller.wechat;import java.io.Serializable;
import java.util.List;public class WxUserDO implements Serializable{private static final long serialVersionUID = 1L;private Integer id; //主键 id private String openId; //用户主键private String nickname; //用户昵称private Integer sex; //性别(1:男,2:女,0:未知)private String country; //国家private String province; //省份private String city; //城市private String headimgurl; //用户头像链接private String unionid; //unionidprivate List<String> privilegeList; //用户特权信息//get 和 set 方法@Overridepublic String toString() {return "WxUserDO [id=" + id + ", openId=" + openId + ", nickname=" + nickname + ", sex=" + sex + ", country="+ country + ", province=" + province + ", city=" + city + ", headimgurl=" + headimgurl + ", unionid="+ unionid + ", privilegeList=" + privilegeList + "]";}}

4)WxController

package com.controller.wechat;import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.alibaba.fastjson.JSON;@RestController
@RequestMapping("/wechat")
public class WxController {private static Logger log = LoggerFactory.getLogger(WxController.class);private static final String APP_ID = "自己的appid";private static final String APP_SECRET = "自己的secret";//回调地址,要跟下面的地址能调通(/wxLogin)private static final String BACK_URL = "https://自己的域名/wechat/wechat/wxLogin";//登录成功回调地址(返回你指定的地址)private static final String URL_LOGIN = "https://自己的域名/wechat/hello";/*** 向指定 URL 发送 GET 方法的请求* URL 所代表远程资源的响应结果* @param request* @param response* * 用户同意授权,获取 code* @throws IOException */@RequestMapping("/wxLoginInit")public void loginInt(HttpServletRequest request, HttpServletResponse response) throws IOException {log.info("微信授权登录...");String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APP_ID + "&redirect_uri=" + URLEncoder.encode(BACK_URL, "UTF-8") + "&response_type=code" + "&scope=snsapi_userinfo" + "&state=STATE#wechat_redirect" ;//重定向到重定向地址response.sendRedirect(url);}@RequestMapping("/wxLogin")public void wxLogin(HttpServletRequest request, HttpServletResponse response) {log.info("用户同意授权,重定向到重定向地址,获取 code");String code = request.getParameter("code");log.info("code:" + code);String appId = APP_ID;String appSecret = APP_SECRET;try {// 获取网页授权 access_token openid 等Oauth2Token oauth2Token = getOauth2Token(appId, appSecret, code);// 网页授权接口访问凭证String accessToken = oauth2Token.getAccessToken();// 用户标识String openId = oauth2Token.getOpenId();// 获取用户信息WxUserDO wxUserInfo = getWxUserInfo(accessToken, openId);// 具体业务 start// 具体有什么业务需求自己实现,我这里只把 Oauth2Token 和 WxUserDO 的信息输出// ...log.info(oauth2Token.toString());log.info(wxUserInfo.toString());//  ...// 具体业务 end// 授权登录成功后,跳转到指定的链接response.sendRedirect(URL_LOGIN);}catch(IOException e) {e.printStackTrace();log.error("网络异常");}}/*** 通过网页授权获取用户信息* * @param accessToken 网页授权接口调用凭证* @param openId 用户标识* @return */private WxUserDO getWxUserInfo(String accessToken, String openId) {log.info("获取用户信息 开始...");log.info("网页授权接口访问凭证AccessToken:" + accessToken);log.info("用户标识openId:" + openId);WxUserDO wxUserInfo = null;// 拼接请求地址String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken);requestUrl = requestUrl.replace("OPENID", openId);log.info("拼接请求地址:" + requestUrl);// 通过网页授权获取用户信息com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(NetUtil.get(requestUrl));if (null != jsonObject) {try {wxUserInfo = new WxUserDO();wxUserInfo.setOpenId(jsonObject.getString("openid"));wxUserInfo.setNickname(jsonObject.getString("nickname"));wxUserInfo.setSex(jsonObject.getInteger("sex"));wxUserInfo.setCountry(jsonObject.getString("country"));wxUserInfo.setProvince(jsonObject.getString("province"));wxUserInfo.setCity(jsonObject.getString("city"));wxUserInfo.setHeadimgurl(jsonObject.getString("headimgurl"));//用户授权信息List<String> list = JSON.parseArray(jsonObject.getString("privilege"), String.class);wxUserInfo.setPrivilegeList(list);//与开放平台公用的唯一标识,只有在用户讲公众号绑定到微信开放平台账号后,才会出现该字段wxUserInfo.setUnionid(jsonObject.getString("unionid"));}catch (Exception e) {wxUserInfo = null;int errorCode = jsonObject.getInteger("errcode");String errorMsg = jsonObject.getString("errmsg");log.error("获取用户信息失败  errcode:{} errmsg:{}",errorCode,errorMsg);}}log.info("获取用户信息 结束...");return wxUserInfo;}/*** 获取网页授权凭证* @param appId 公众账号的唯一标识* @param appSecret 公众账号的密钥* @param code* @return*/private Oauth2Token getOauth2Token(String appId, String appSecret, String code) {log.info("获取网页授权凭证 开始...");Oauth2Token auth = null;//拼接请求地址String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";requestUrl = requestUrl.replace("APPID", appId);requestUrl = requestUrl.replace("SECRET", appSecret);requestUrl = requestUrl.replace("CODE", code);log.info("拼接后的请求地址为:" + requestUrl);//获取网页授权凭证com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject (NetUtil.get(requestUrl));if(null != jsonObject) {try {auth = new Oauth2Token();auth.setAccessToken(jsonObject.getString("access_token"));auth.setExpiresIn(jsonObject.getInteger("expires_in"));auth.setRefreshToken("refresh_token");auth.setOpenId("openid");auth.setScope("scope");}catch(Exception e) {auth = null;int errorCode = jsonObject.getInteger("errcode");String errorMsg = jsonObject.getString("errmsg");log.error("获取网页授权凭证失败 errcode:{} errmsg:{}",errorCode,errorMsg);}}log.info("获取网页授权凭证 结束...");return auth;}
}

3.测试

该功能的测试只能在微信上。例如:https://自己的域名/wechat/wxLoginInit。

把访问的链接发送到微信上。

在微信客户端上点击当前链接,跳转网页,就能出现如下提示是否收取登录的接口,点击同意即可。

注意:网页微信授权一般只需要授权一次,后面都会直接登入的。

4.整合

到这里我们就学会了,在微信上实现网页授权登录。然后如何在公众号上实现呢???很简单,就是结合前面的 2.2 自定义菜单 把授权链接设置进去就可以了。

重要的事情说三遍 ↓↓↓

重要的事情说三遍 ↓↓↓

重要的事情说三遍 ↓↓↓

这只是一个简单的 demo ,具体要在那里实现授权登录,授权后要跳转到哪里或者要实现什么业务,请根据自己的实际情况编写!!!

四、公众号视频资源分享

需要以上公众号视频的,请关注博主的订阅号,在后台回复“ 公众号 ”即可获取百度元分享链接。

从零接入微信公众号(Java实现 附源码)相关推荐

  1. Java微信公众号开发(附源码!!!)

    笔者最近在为一个艺考服务团队开发手机端的服务,由于开发app需要的时间较长,所以选择开发微信公众号.本人比较擅长Java开发,所以本文是基于Java语言的公众号开发.话不多说,直接进入正题. 准备工作 ...

  2. 2021最新外卖霸王餐小程序、H5、微信公众号版外系统源码|霸王餐美团/饿了么系统 粉丝裂变玩源码下载

    2021年了,你还在用淘宝客吗?赶紧跟上互联网的大势吧,外卖cps就是cps人群趋势! 个人.个体.企业均可使用 外卖霸王餐小程序.H5.微信公众号版外系统源码|霸王餐美团/饿了么系统 粉丝裂变玩 2 ...

  3. 城乡投票源码php_PHP微信公众号投票活动系统源码 独立版

    PHP微信公众号投票活动系统源码 独立版,男神女神商家评选,微信独立后台,内附安装使用说明 1.支持关注公众号后报名参加. 2.支持用户自拍上传照片报名,照片可传1-5张. 3.IP限制,可以限制单I ...

  4. 微信分销 微信公众号开店 多用户版源码

    微信分销版程序可以给微商用户实现在移动端开店的功能,开通的供销店还可以再开分销店,每个分销店都是独立的,运作模式类似于天猫供销,可接入微信公众账号.易信.微博等第三方开放平台 总管理端功能包含: 1. ...

  5. Spring Boot+微信公众号开发Demo(源码见文章最低端)

    目录 微信公众号开发 1.微信公众号简单介绍 2.微信公众号申请 3.开发模式启用以及接口配置 4.消息以及消息处理的工具 5.各种消息的接收与响应 6.图文消息 7.自定义菜单的创建以及菜单的相应 ...

  6. 白狐微信公众号编辑器CMS系统源码

    白狐微信助手管理系统是一套集合微信公众号文章管理和素材商城于一身的专业网站系统,是一套可做商业应用的工具型网站,是微信营销人员所必备的工具网站.前台功能强大,后台管理灵活,代码清晰简洁, 通俗易懂,是 ...

  7. 微信公众号短链生成服务器,微信公众号短链接生成源码

    .版本 2 .支持库 spec .程序集 窗口程序集_启动窗口 .子程序 __启动窗口_创建完毕 .局部变量 access_token, 文本型 .局部变量 返回, 文本型 .局部变量 i, 整数型 ...

  8. 最新微信公众号砍价系统程序源码+仿砍价啦独立系统

    正文: 下方是程序完整标题: 这程序价_值386,最新版的砍价系统,独立系统,非插件带商品详情. 环境配置:微信砍价功能是基于php+MySQL开发的,所以你的服务器需要支持php+MySQL,php ...

  9. 2023 新版 微信公众号无限回调系统源码

     修复了很多BUG,目前支持对接易支付,支持用户自助充值,自助购买授权,支持自助更换授权,支持自助续费授权

最新文章

  1. PHP 取302跳转后真实 URL 的两种方法
  2. 计算机网络知识点总结(一)-物理层
  3. HTTP 200 OK和HTTP 304 Not modified的由来
  4. SonarQube系列二、分析dotnet core/C#代码
  5. CF720C Homework(构造)(暴力)
  6. 跟从内心,无问东西------观影《无问东西》
  7. javaWeb项目中web.xml的xsd( XML Schemas Definition)文件
  8. Java发送https请求,综合post请求,get请求,获取网络返回的信息
  9. Spring 3.x jar 包详解 与 依赖关系
  10. Python引力波火了 你该了解的开源框架
  11. 安装Ubuntu前三件重要的事情
  12. 前端开发中使用build.js完成区分环境的打包配置
  13. WeQuant交易策略—EMV
  14. 【scala】获取当前时间的上一个自然周以及自然周集合;获取当前时间的上一个自然月以及自然月的第一天与最后一天
  15. Java的Scanner对象
  16. UnityShader实现较为完整的光照模型(Lambert+Phong+三色环境光+阴影+环境遮蔽(AO))
  17. 【 Python 中 int 用法详解】(转载)
  18. 计算机应用基础教师授课视频,微课在计算机应用基础教学的应用
  19. 1、 输入长方形的长和宽,编程求该长方形的周长和面积
  20. 第48讲 Android Camera2 API FD人脸检测

热门文章

  1. 封装chrome镜像
  2. centOS7.2.1511 bit64位 浏览器不能上网
  3. cookie实现单点登录
  4. Android 分享功能之 微信 图片分享
  5. Java实训报告----计算图形的周长和面积(保姆级,完整版)
  6. 服务拆分理论和原理及方法
  7. 盘点 35 个 Apache 顶级项目,我拜服了…
  8. python下载西瓜视频2020最新思路
  9. 判断苹果手机系统版本 判断手机浏览器信息
  10. Win11如何隐藏输入法悬浮窗?