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

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

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

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


在开发前新建一个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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值