前言

机遇巧合中在公司中遇到微信公众号开发,接触到了微信公众号接口的使用,所以写此文章来分享和记录自己所学的知识。


项目地址:https://gitee.com/sanyuetiandi/springboot


因为项目是基于springboot+maven搭建的,所以如果你想运行,需要 比较新版本的ide和1.7以上的jdk,也就是jdk1.8,如果不了解springboot,可以自行百度。不过,其实springboot和springmvc搭建的框架主要区别其实就在于配置文件,springboot舍弃了原来的xml方式采用了properties,yml文件和bean的方式。本质上来讲其实还是springmvc,除了配置上有所不同,其它方面其实还是大径相同。

简述

其实在我看来,微信公众号的很多接口和我们平时调用的接口没有什么大的区别,如果你认真的看微信公众号开发文档,很容易明白是怎么一回事儿。

正文

首先,需要打开微信公众号测试号,注册一个账号,因为真正的微信公众号分为,订阅号,服务号,企业号。服务号和企业号都是需要公司注册的,而订阅号虽然说是可以个人注册,但是接口权限只那么几个,对于开发者我们来说,是远远不够的。
其次,你需要打开微信公众号开发文档,如图:打开网页授权这一栏然后按照上面介绍的步骤一步一步来

Spring 微信公众号开发 网页授权接口响应慢 springboot微信公众号授权登录_java


1. 设置网页授权回调域名

打开你刚注册的:如图

Spring 微信公众号开发 网页授权接口响应慢 springboot微信公众号授权登录_微信公众号_02


然后下拉


Spring 微信公众号开发 网页授权接口响应慢 springboot微信公众号授权登录_java_03


在这个地方你会看到网页授权获取用户基本信息,点击后面的修改,贴上你的域名。当然,在这之前你需要一个内网穿透工具,来实现外网访问本地。并且,需要注意的是,微信公众号开发文档已经明确指出,此处是一个字符串而不是url,所以不要在域名前加上http,如图


Spring 微信公众号开发 网页授权接口响应慢 springboot微信公众号授权登录_spring_04


**2. 代码

在这之前建议把这些开发说明看完。

Spring 微信公众号开发 网页授权接口响应慢 springboot微信公众号授权登录_微信公众号开发_05


接下来就是正文了,我们一步一步l来,根据文档介绍,需要访问这个地址并且添加上面所需要的参数,需要注意的是红色的字体,使用urlEncode对链接进行处理

1.获取code
/**
 * 微信demo控制层
 * 
 * @author 晴 2017年9月12日 下午2:42:26
 */
@Controller
@RequestMapping("/weChat")
public class WeChatController {
    @Autowired
    private WechatTokenTicketService WechatTokenTicketService;

    /**
     * 微信网页授权 重定向到微信获取CODE,CODE可以获取access_token和openid
     * @param request
     * @param Url  授权之后将要跳转的页面
     */
    @RequestMapping("/oauth2")
    public String oauth2Code(HttpServletRequest request, @RequestParam String Url) {
        String backUrl = "";// 要返回的url
        // 查看将要跳转的页面是否以http或者https开头
        if (Url.startsWith("http://") && Url.startsWith("https://")) {
            backUrl = Url;
        } else {
            // 获取域名
            String requestUrl = "http://" + request.getServerName() + "/";
            if (request.getContextPath() != null && !request.getContextPath().equals("")) {
                // 如果有项目名,拼接项目名
                requestUrl += request.getContextPath() + "/";
            }
            // 最后拼接,URLEncoder微信接口指定需用此方法格式化url
            try {
                backUrl = URLEncoder.encode(requestUrl + "/weChat/oauth2AccessToken?targatUrl=" + requestUrl + Url,
                        "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        // 格式化最后需要请求的路径
        String redirectUrl = String.format(WeChatUtil.snsapi_url, WeChatUtil.appid, backUrl, WeChatUtil.snsapi_userinfo,
                WeChatUtil.getNonceStr());
        return "redirect:" + redirectUrl;
    }
2.微信工具类(常量储存)

package com.weChat.demo.util;

import java.util.UUID;

/**
 * 微信工具类
 * @author 晴
 * 2017年9月12日 上午10:36:49
 */
public class WeChatUtil {

    /**
     * AppID
     * 微信号唯一的标识
     */
     public final static String appid = "wx7a22791a9af43756";
    /**
     * AppID
     * 微信号唯一的标识
     */
    public final static String appsecrect = "0b91a452e0b89c3297e60eccb40241a4";

    /**
     * 拉去用户信息
     * 参数 access_token
     *    openid
     *    zh_CN 中文
     */
    public static String userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=%1$s&openid=%2$s&lang=zh_CN";


    /**
    * 应用授权作用域,snsapi_base 不弹出授权页面,直接跳转,只能获取用户openid,snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
    */
    public final static String snsapi_userinfo = "snsapi_userinfo";


    /**
     * 通过code获取网页授权的access_token和openid
     * 需要参数四个appid,appsecret,code,grant_type
     */

    public static String access_token_oauth2_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code";
    /**
     * 获取code的url
     * %1$s appId
     * %2$s 要重定向的url
     * %3$s 应用授权作用域,snsapi_base 不弹出授权页面,直接跳转,只能获取用户openid,snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
     * %4$s 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
     */
    public final static String snsapi_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%1$s&redirect_uri=%2$s&response_type=code&scope=%3$s&state=%4$s#wechat_redirect";

    /**
     * 获取10位随机数
     * @return
     */
    public static String getNonceStr(){
        return UUID.randomUUID().toString().replace("-","").substring(0, 10);
    }
}
3.根据code获取 access_token和openid 并且根据这两项拉取用户信息

    /**
     * 根据code获取 access_token和openid 并且根据这两项拉取用户信息
     * @param request
     * @param session 可以储存获取到的openid当作用户登录的标识
     * @param code  微信端返回的code
     * @param targatUrl
     * @return
     */
    @RequestMapping("/oauth2AccessToken")
    public String oauth2OpenId(HttpServletRequest request, HttpSession session, String code,
            @RequestParam String targatUrl) {
        if (code == "" || code == null) {
            return "redirect:/mWechat/fls/oauth2.?Url=" + targatUrl;
        }
        // 根据上一步获取的code获取网页授权用户的access_token和openid
        JSONObject json = WechatTokenTicketService.getAccessTokenOauth2(code);
        // 根据上一步的access_token和openid获取用户信息
        JSONObject userifo = HttpUtil.doGet(
                String.format(WeChatUtil.userinfo_url, json.getString("access_token"), json.getString("access_token")), null);
        // 已获取的用户信息
        System.out.println(userifo);
        System.out.println(json.getString("access_token"));
        return "redirect:" + targatUrl;
    }
package com.weChat.demo.service.Impl;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.weChat.demo.service.WechatTokenTicketService;
import com.weChat.demo.util.HttpUtil;
import com.weChat.demo.util.WeChatUtil;
@Service
public class WechatTokenTicketServiceImpl implements WechatTokenTicketService{
    @Override
    public JSONObject getAccessTokenOauth2(String code) {
        //拼接获取access_token的接口链接
        String access_token_url= String.format(WeChatUtil.access_token_oauth2_url,WeChatUtil.appid,WeChatUtil.appsecrect,code);
        JSONObject jsonObject = HttpUtil.doGet(access_token_url,null);
        return jsonObject;
    }
}
4.跳转地址
    @RequestMapping("/index")
    public String index(String access_token, String openid) {
        return "/index";
    }

总结

是不是很简单呢,如果不是很理解你可以在码云上面下载项目运行,并且看着文档一步一步看,上面注释很详细。