微信公众号开发笔记(二)——获取accessToken

来源:互联网 发布:网易彩票源码 编辑:程序博客网 时间:2024/06/05 12:02

这一篇要开始写微信的开发啦~~

关于微信开发这一块的笔记都围绕着我现在做的这个项目为例。

(注:因为公司的平台架构不同,所以代码实现的方式有些不一样,但是,但是,但是,道理还是一样的大笑


在开发前新建一个WxConstant类,来存放微信配置的常量。

 public static final String DOMAIN_URL = "http://域名";    public static final String CONTENT_URL = "/上下文";    public static final String WEB="/ns";//站点    public static final String TOKEN = "wechat";    public static final String APPID = "appid";    public static final String APPSECRET = "appsecret";    public static final String ORIGINID = "gh_xxx";

AppID(应用ID):该参数可用于唯一标识一个公众号。

AppSecret(应用密钥):该参数可重置,重置后系统原先的接口调用将失效。

originid:微信公众号的微信号


1.https请求接口

编写一个接口用来发送微信接口的请求。

(这里直接借用老前辈写的工具类的代码)

/**  * 发起https请求并获取结果  * @param requestUrl 请求地址  * @param requestMethod 请求方式(GET、POST)  * @param outputStr 提交的数据  * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)  */public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {JSONObject jsonObject = null;StringBuffer buffer = new StringBuffer();try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化  TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象  SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();httpUrlConn.setSSLSocketFactory(ssf);httpUrlConn.setDoOutput(true);httpUrlConn.setDoInput(true);httpUrlConn.setUseCaches(false);// 设置请求方式(GET/POST)  httpUrlConn.setRequestMethod(requestMethod);if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect();// 当有数据需要提交时  if (StringUtils.isNotEmpty(outputStr)) {OutputStream outputStream = httpUrlConn.getOutputStream();// 注意编码格式,防止中文乱码  outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 将返回的输入流转换成字符串  InputStream inputStream = httpUrlConn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}bufferedReader.close();inputStreamReader.close();// 释放资源  inputStream.close();inputStream = null;httpUrlConn.disconnect();jsonObject = JSONObject.fromObject(buffer.toString());} catch (ConnectException e) {} catch (Exception e) {    e.printStackTrace();}return jsonObject;

http请求

/**发起http请求post方式*/public static String sendHttpRequest(String requestUrl,String params){try {URL realUrl = new URL(requestUrl);            // 打开和URL之间的连接        URLConnection connection = realUrl.openConnection();        // 设置通用的请求属性        connection.setRequestProperty("accept", "*/*");        connection.setRequestProperty("connection", "Keep-Alive");        connection.setRequestProperty("user-agent",                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");        // 建立实际的连接        connection.connect();        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));                    String line = null;            StringBuilder sb = new StringBuilder();            while((line = br.readLine())!=null){                sb.append(line);            }            br.close();            return sb.toString();}catch (Exception e) {LogApp("发起HTTP请求失败:"+e);return null;}}

完成了以上接口开发后就可以发起微信接口的请求了。

接下来编写获取accesstoken的接口请求。

2.获取access_token

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。因为access_token的有效时间是7200秒(也就是2个小时)且获取的次数一天内是有限的(具体看微信公众平台开发文档),所以获取access_token后需要将其妥善保存,可以放在缓存中,也可以存在数据库中。

private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; 

 /** 获取access_token  * @param appid 公众号唯一凭证  * @param appsecret 公众号唯一凭证密钥  * @return accessToken 接口调用凭证 */public static WxToken getAccessToken(String appid, String appsecret) {WxToken accessToken = null;String requestUrl = ACCESS_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", appsecret);JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);// 如果请求成功  if (null != jsonObject) {try {accessToken = new WxToken();accessToken.setAppId(appid);accessToken.setToken(jsonObject.getString("access_token"));accessToken.setExpiresIn(jsonObject.getInt("expires_in"));String now = NowString_Mi().substring(0, 19);accessToken.setCreateTime(now);} catch (JSONException e) {LogApp(e)}}return accessToken;}
上面是通过接口去获取access_token,在实际开发中我们需要先去缓存或数据库中查询accessToken是否过期,下面是以存放在数据库中为例:

public static String getAccessToken(String appId, String appSecret) {String accessToken = null;try{  //查询数据库,获取最近的凭证        EntityBean bean = searchToken(appId);        if (null != bean) {            accessToken = bean.getString(WxTokenTable.TOKEN);            //如果超过有效期,则重新获取            if (!isTokenValid(bean)) {                accessToken = doAccessToken(appId, appSecret);               LogDebug("凭证已失效,重新获取为:" + accessToken);            }        } else {            accessToken = doAccessToken(appId, appSecret);            LogDebug("第一次获取凭证:" + accessToken);        }}catch(Exception e){   LogDebug("获取accesstoken失败:" + e.getMessage());}return accessToken;}
/** * 调用接口获取access_token,并将结果存储数据库 * @return accessToken 接口调用凭证 */private static String doAccessToken(String appId, String appSecret) {String accessToken = null;//获取接口调用凭证对象WxToken at = WeixinUtil.getAccessToken(appId, appSecret);if (null != at) {addToken(at); //将结果存入数据库accessToken = at.getToken(); //接口条用凭证}return accessToken;}
/** * 保存接口调用凭证 * @param at 接口调用凭证 */public void addToken(DataSource ds, WxToken at) {Transaction tran = null;try {// 创建事务tran = ds.createTransaction();EntityBean bean = new EntityBean(WxTable.WXTOKEN);bean.set(WxTokenTable.ID, Global.getInstance().GetUUID());bean.set(WxTokenTable.APPID, at.getAppId());bean.set(WxTokenTable.TOKEN, at.getToken());bean.set(WxTokenTable.EXPIRESIN, at.getExpiresIn());bean.set(WxTokenTable.CREATETIME, at.getCreateTime());bean.insert(tran);// 提交事务tran.commit();} catch (Exception e) {tran.rollback();} finally {tran.close();}

最后我们就可以愉快的使用access_token去调用微信公众号平台的各种接口啦辣~~

这篇笔记就到这里了。

再见

备注上开发时常见的一些问题

1.    接口访问异常

l             解决方案:检查服务器网络是否正常,参数是否正确。检查微信公众号后台是否配置了ip白名单。

2.    jssdk接口使用异常

l             解决方案:检查地址栏的地址与生成签名的url是否一致,检查appid与appsecret是否正确,检查微信公众号后台是否配置了js安全域名。

3.    网页授权失败

l             解决方案:检查微信后台设置,是否设置了授权域名。检查appid与appsecret是否正确。

4.    消息重复发送

l             解决方案:因为微信公众号在5秒内没有接收到开发者的返回结果会重复发送请求,有时候存在网络延迟的情况下,导致一条信息被公众号重复回复两次,这种情况需要用到msgid排重。(当不需要处理的时候尽量返回success或者空字符串)


阅读全文
0 0
原创粉丝点击