java对接微信公众号

我对接公众号,主要使用的地方在H5。实现效果就是不需要关注公众号就会弹出来一个授权页,然后进行其他的一些操作。
效果图:
在这里插入图片描述

其实代码很简单,主要是这个流程。我先讲流程,再结合代码,请仔细看完,绝对可以完成。

  1. 请求微信授权接口(分为静默模式和非静默模式)
  2. 在第一步的基础上会有一个回调地址redirect_uri,这里就是写我们自己的登录逻辑和获取用户信息

其实就完了。。。。

一、请求微信授权接口

https://open.weixin.qq.com/connect/oauth2/authorize?appid={APPID}&redirect_uri=https://c380h47694.vicp.fun//wechat/login&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect

主要几个参数:

  • appid 微信公众号)appid
  • redirect_uri 回调地址)就是你的接口
  • response_type 固定写死的
  • scope 类型这个参数就很重要了
    • snsapi_userinfo:非静默模式,就是像上图一样会弹出授权页
    • snsapi_base:静默模式

文档地址

二、编写回调接口

在这里插入图片描述
主要就是获取网页授权token和用户信息接口,需要注意有几个获取用户信息的url,不要用错了 网页授权是用这个获取

/** 获取网页授权access_token的URL,和基础服务access_token不同 **/
    private final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
/** 用户信息URL**/
    private final static String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

 /**
     * 网页授权AccessToken
     * @param code 微信传递的code
     * @return json
     */
    private static JSONObject geOauth2AccessToken(String code) {
        String requestUrl = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", SECRET).replace("CODE",code);
        // 发起GET请求获取凭证
        String result = HttpUtil.get(requestUrl);
        log.info(result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (Objects.nonNull(jsonObject.getInt(ERR_CODE))) {
            throw new CustomException("网页授权AccessToken失败:"+jsonObject);
        }
        return jsonObject;
    }
/**
     * 获取用户信息
     *   // 用户的标识
     *   System.out.println(jsonObject.getStr("openid"));
     *   // 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
     *   System.out.println(jsonObject.getInt("subscribe"));
     *   // 用户关注时间
     *   System.out.println(jsonObject.getStr("subscribe_time"));
     *   // 昵称
     *   System.out.println(jsonObject.getStr("nickname"));
     *   // 用户的性别(1是男性,2是女性,0是未知)
     *   System.out.println(jsonObject.getInt("sex"));
     *   // 用户所在国家
     *   System.out.println(jsonObject.getStr("country"));
     *   // 用户所在省份
     *   System.out.println(jsonObject.getStr("province"));
     *   // 用户所在城市
     *   System.out.println(jsonObject.getStr("city"));
     *   // 用户的语言,简体中文为zh_CN
     *   System.out.println(jsonObject.getStr("language"));
     *   // 用户头像
     *   System.out.println(jsonObject.getStr("headimgurl"));
     * @param accessToken 接口访问凭证 全局访问token
     * @param openId 用户标识
     * @return WeixinUserInfo
     */
    public static JSONObject getUserInfo(String accessToken, String openId) {
        // 拼接请求地址
        String requestUrl = USER_INFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        // 获取用户信息
        String result = HttpUtil.get(requestUrl);
        log.info("获取用户信息结果:"+result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        return jsonObject;
    }

三、公众号配置

在这里插入图片描述
完事!!!

编写获取微信签名

用的是hutool工具类生成的随机数
应该复制过去能直接用,不过有些不重要的代码没有贴,随便改改写死就行

@ApiOperation(value = "获取微信签名")
    @GetMapping("/getWXSign")
    public Result<String> getWXSign(@ApiParam("当前地址") String url) {
        long timeStampSec = System.currentTimeMillis() /1000;
        String timestamp = String.format("%010d", timeStampSec);

        String nonceStr = RandomUtil.randomString(8);

        String[] urls = url.split("#");
        String newUrl = urls[0];
        JSONObject respJson =new JSONObject();

        String wxJsapiTicket = WechatUtil.getWXJsapiTicket();
        System.out.println("ticket:"+wxJsapiTicket);
        String[] paramArr =new String[]{"url=" + newUrl,"jsapi_ticket=" + wxJsapiTicket,"noncestr=" + nonceStr,"timestamp=" + timestamp};
        Arrays.sort(paramArr);

        // 将排序后的结果拼接成一个字符串
        String content = paramArr[0].concat("&").concat(paramArr[1]).concat("&").concat(paramArr[2]).concat("&").concat(paramArr[3]);
        String signature = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            // 对接后的字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            signature = WechatUtil.byteToStr(digest).toLowerCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        respJson.put("appId", WechatUtil.APPID);
        respJson.put("timestamp", timestamp);
        respJson.put("nonceStr", nonceStr);
        respJson.put("signature", signature);
        return Result.newSuccess(respJson.toJSONString());
    }


  /**
     * 获取基础服务接口访问凭证
     * @return token 基础token
     */
    public static String getAccessToken() {
        String accessToken;

        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
        Object accessTokenCache = redisUtil.get(CommonConstant.ACCESS_TOKEN);
        if (Objects.nonNull(accessTokenCache)) {
            accessToken = accessTokenCache.toString();
            return accessToken;
        }

        String requestUrl = TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", SECRET);
        // 发起GET请求获取凭证
        String result = HttpUtil.get(requestUrl);
        log.info("全局获取token接口返回参数:"+result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (Objects.nonNull(jsonObject.getInt(ERR_CODE))) {
            throw new CustomException("获取用户信息失败,请重试");
        }

        accessToken = jsonObject.getStr("access_token");
        redisUtil.set(CommonConstant.ACCESS_TOKEN,accessToken);
        return accessToken;
    }

/**
     *  入参为token,返回ticket
     * @return
     */
    public static String getWXJsapiTicket() {
        String accessToken = getAccessToken();
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";
        String result = HttpUtil.get(tokenUrl);
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(result);
        return jsonObject.getString("ticket");
    }

    /**
     * 编码sign
     * @param byteArray sign
     * @return 字符串
     */
    public static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }
    private static String byteToHexStr(byte mByte) {
        char[] digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }


遇到的坑

  1. 切换测试公众号和真实公众号的时遇到的缓存或者没切换
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值