Java微信公众号开发之接入

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fighting_sxw/article/details/79253180

微信官方接入指南

一、环境准备

1、申请一个公众号,公众号接口权限说明如下:
这里写图片描述
这里写图片描述
根据不同的需求申请不同的公众号。

个人只能申请订阅号,而且不能进行微信认证,但是可以申请公众平台测试账号,拥有全部的权限,(首页—>开发者工具—>公众平台测试账号)

2、准备一台外网服务器(腾讯云、阿里云、百度云)

二、接入微信公众平台开发
第一步:填写服务器配置
登录微信公众平台官网后,在公众平台官网的开发-基本设置页面,勾选协议成为开发者,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey。

URL是开发者用来接收微信消息和事件的接口URL。
Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。
EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。
这里写图片描述

如果是测试账号:
这里写图片描述

第二步:验证消息的确来自微信服务器
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上。
在外网服务器上用Java写后台,所以我们用到了Servlet来接受GET和POST请求,上一步中的URL地址就是Servlet的访问地址

GET请求携带参数如下表所示:

参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

验证步骤:
1、在外网服务器上建好Servlet,并填写好配置信息后,点击提交,外网服务器上会收到Get请求,并收到以下参数:

signature=63603f83cb6f12d376a5460779c8a3f59d150990&echostr=12631531042608380285&timestamp=1517668717&nonce=3442480512

2、将token(之前服务器配置中所填写)、timestamp、nonce三个参数进行字典序排序

3、将三个参数字符串拼接成一个字符串进行 sha1加密

public static String CheckSignature(String str){
        String[] content=str.split("&");
        String signature=content[0].split("=")[1];
        String timestamp=content[2].split("=")[1];
        String nonce=content[3].split("=")[1];
        //第一步中填写的token一致
        String token="wxsxw";

        ArrayList<String> list=new ArrayList<String>();
        list.add(nonce);
        list.add(timestamp);
        list.add(token);

        //字典序排序
        Collections.sort(list);
        //SHA1加密
        String checksignature=SHA1Util.encode(list.get(0)+list.get(1)+list.get(2));
        System.out.println(signature);
        System.out.println(checksignature);

        if(checksignature.equals(signature)){
            return content[1].split("=")[1];
        }
        return null;    
    }

4、开发者获得加密后的字符串可与signature对比,如果两者一致,确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Get请求携带参数
        String content=request.getQueryString();
        System.out.println(content);
        if(content.startsWith("signature")){
            //检查消息是否来自微信服务器
            String echostr=WechatUtil.CheckSignature(content);

            //返回echostr给微信服务器
            OutputStream os=response.getOutputStream();
            os.write(URLEncoder.encode(echostr,"UTF-8").getBytes());
            os.flush();
            os.close();
        }

    }

交互过程:
这里写图片描述

三、获取access_token
官方文档

3.1、access_token简介

1、access_token是公众号接口调用的全局唯一票据,每次主动调用接口时必须携带的参数。
2、目前Access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值
3、公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。

3.2、接口调用请求说明

https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数说明:

参数 是否必须 说明
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

返回说明:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

参数说明:

参数 说明
access_token 获取到的凭证
expires_in 凭证有效时间,单位:秒



Java代码:

    public static String getToken(){
        HttpURLConnection conn=null;
        if(access_token==null||access_token.equals("")
                ||(new Date().getTime()-access_token_date.getTime())>((accessTokenInvalidTime-200L)*1000L)){
            try{
                String Strurl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+AppID+"&secret="+AppSecret;
                URL url = new URL(Strurl);
                conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(5000);
                conn.setRequestMethod("GET");
                if (HttpURLConnection.HTTP_OK == conn.getResponseCode()){
                    access_token_date=new Date();
                    InputStream in=conn.getInputStream();
                    String backcontent= IOUtil.readString(in);
                    backcontent= URLDecoder.decode(backcontent,"UTF-8");

                    JSONObject json = JSONObject.fromObject(backcontent);
                    access_token=json.getString("access_token");
                    if(access_token!=null){
                        System.out.println("获取token成功:"+access_token);
                    }  
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally {
                conn.disconnect();
            }
        }else{
            System.out.println("token获取失败或尚未失效:"+access_token);
        }
        return access_token;
    }
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页