2017-02-10 15:01:42 iteye_10899 阅读数 182
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27821 人正在学习 去看看 秦子恒

本章讲解内容主要如下:

1.用户扫描公众号二维码进行关注时,微信服务器会发送subscribe请求给开发者服务器,开发者服务器会根据数据库中是否存在此openid的用户信息来进行操作,如果数据库中存在此openid的用户信息,则将用户信息的状态修改为可用的,如果数据库中不存在此openid的用户信息,则根据openid从微信服务器中获取用户信息,并将其存储到我们自己的数据库中,并将状态设置为可用的。

2.用户不再关注微信公众号时,微信服务器会发送unsubscribe请求给开发者服务器,开发者服务器会从数据库中获取此openid的用户信息,如果用户信息存在,则把用户信息的状态修改为不可用的。

2016-01-14 13:55:49 HinstenyHisoka 阅读数 5926
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27821 人正在学习 去看看 秦子恒

当我们进行微信平台相关内容开发时,如果想做一些针对微信用户进行一些信息获取及消息推送,那我们第一步先要拿到微信用户的OPENID(用户唯一标识,建立在一个公众号与一个微信用户之间,即针对一个公众号,所有的微信用户都享有一个独立不变的标识);


1 . 如果微信用户已经关注自己的公众号, 那可以通过微信接口里面的用户管理模板直接获取到对应公众号的所有已关注用户OPENID的列表;
1). 在调用所有的微信接口之前,我们先要请求授权,拿到access_token

    @Getter
    @Config("wechat.appid")
    private static String WECHATAPPID;

    @Getter
    @Config("wechat.appsecret")
    private static String WECHATAPPSECRET;

    public static final String ACCESS_TOKEN = "access_token";
    public final static String WECHATACCESSTOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=";
        /**
     * <p>
     * 成功: {"access_token":"ACCESS_TOKEN","expires_in":7200}
     * </p>
     * <p>
     * 失败: {"errcode":40013,"errmsg":"invalid appid"}
     * </p>
     * @return 如果没有获取到有效的凭据,就返回 null
     */
    private static Map getWechatAPPAccessTokenFromWeChat() {
        StringBuilder accessTokenUrl = new StringBuilder().append(WECHATACCESSTOKEN).append(WECHATAPPID)
                        .append("&secret=").append(WECHATAPPSECRET);
        Map result = HttpClientUtil.readHttpContent(accessTokenUrl.toString());
        if (result != null && result.get(ACCESS_TOKEN) != null)
            return result;
        return null;
    }

    //HttpClientUtil.class static method
    /**
     * get json content and transform to Map from the urlStr
     * If occuer one error just return null.
     * @param urlStr
     * @return
     */
    public static Map<String,Object> readHttpContent(String urlStr){
        Map<String, Object> result = null;
        HttpEntity httpEntity = null;
        try {
            HttpResponse response = Request.Get(urlStr).execute().returnResponse();
            httpEntity = response.getEntity();
        }catch (IOException e) {
            logger.error("Get resouse from {} had occurred an error: {}", urlStr, e.toString());
            return result;
        }
        try (
            InputStream in = httpEntity.getContent();
        ){
            ObjectMapper mapper = new ObjectMapper();
            result = mapper.readValue(in, HashMap.class);
        }catch (IOException e) {
            logger.error("Get json content from {} had occurred an error: {}", urlStr, e.toString());
            return result;
        }
        return result;
    }

2). 使用前面得到的access_token获取公众号的微信关注用户列表

    public static final String ERRMSG = "errmsg";
    public final static String WECHATUSERLISTURL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=";
    /**
     *<p>
     * 获取成功:{
     *  "total":23000,
     *  "count":10000,
     *  "data":{"
     *    openid":[
     *      "OPENID1",
     *      "OPENID2",
     *      ...,
     *      "OPENID10000"
     *    ]
     *  },
     *  "next_openid":"OPENID10000"
     *  }
     *</p>
     *
     *<p>
     * 获取失败:{"errcode":40013,"errmsg":"invalid appid"}
     *</p>
     *
     *
     * 获取微信公众帐号的关注者列表(wechat user openID),每次最多10000个
     *
     * @param accessToken
     * @param next_openid: 没有此参数,则默认从关注列表的第一个开始获取
     * @return
     */
    public static Map getWechatUserOpenIDList(String accessToken, String next_openid) {
        StringBuilder urlB = new StringBuilder().append(WECHATUSERLISTURL).append(accessToken);
        if (!Strings.isBlank(next_openid))
            urlB.append("&next_openid=").append(next_openid);
        Map result = HttpClientUtil.readHttpContent(urlB.toString());
        if (result != null && result.get(ERRMSG) == null)
            return result;
        return null;
    }
采用方法一,到此便得到了用户openID列表,可以进行后面获取微信用户信息及向用户推送模板消息等;

2 . 无论微信用户是否关注自己的公众号, 当微信用户访问我们的web站点时(通过微信内置浏览器),我们可以通过页面授权的方式拿到微信用户的OpendID(页面授权需要跳转到微信服务器拿到oauth_code然后再换取access_token及OpendID);
1). 为我们的web站点服务添加一个filter,拦截来自微信浏览器的请求,进行302跳转到微信站点,拿到授权码再回调回来;

public class WechatFilter implements Filter {

    private static final Logger logger             = LoggerFactory.getLogger(WechatFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        if (response.isCommitted()) {
            chain.doFilter(request, response);
            return;
        }
        //判断请求是否来自微信浏览器
        if (!WebUtil.isWechatRequest(httpRequest)) {
            chain.doFilter(request, response);
            return;
        }
        String requestURL = WebUtil.getRequsetUrl(httpRequest, true, true);
        logger.debug("Request from wechat client:{}", requestURL);
        HttpSession session = httpRequest.getSession();
        String weChatOpenId = (String) session.getAttribute(WeChatManager.WECHATOPENID);
        if (weChatOpenId == null) {
            if (httpRequest.getParameter(WeChatManager.CODE) == null) {
                StringBuilder url = new StringBuilder("http://").append(WebUtil.getRequsetUrl(httpRequest, true, true));
                response.reset();
                ((HttpServletResponse) response).sendRedirect(url.toString());
                return;
            } else {
                String oauthCode = httpRequest.getParameter(WeChatManager.CODE);
                if (!Strings.isBlank(oauthCode)) {
                    Map<String, Object> oauth_data = WeChatPageInterface.getWechatPageAccessToken(oauthCode);
                    weChatOpenId = oauthCode != null && oauth_data.get(WeChatManager.OPENID) != null ? (String) oauth_data.get(WeChatManager.OPENID) : null;
                    session.setAttribute(WeChatManager.WECHATOPENID, weChatOpenId);
                } else {
                    logger.warn("The oauth_code is empty!");
                }
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

}
    //WeChatPageInterface.class static method
    /**
     * <p>
     * 微信获取授权成功:{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN",
     * "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }
     * </p>
     * <p>
     * 微信获取授权失败:{"errcode":40029,"errmsg":"invalid code"}
     * </p>
     *
     * 请求微信公众号的网页授权,得到用户OpenID和access_token
     * 微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证( 网页授权access_token),
     * 通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
     *
     * @return 如果没有获取到有效的凭据,就返回 null
     */
    public static Map<String, Object> getWechatPageAccessToken(String oauthCode) {
        StringBuilder accessTokenUrl = new StringBuilder().append(WeChatManager.weChatAuthAccessTokenPage).append(WeChatManager.getWECHATAPPID())
                        .append("&secret=").append(WeChatManager.getWECHATAPPSECRET()).append("&code=")
                        .append(oauthCode).append("&grant_type=").append("authorization_code");
        Map<String, Object> accessToken = HttpClientUtil.readHttpContent(accessTokenUrl.toString());
        if (accessToken != null && accessToken.get(WeChatManager.ACCESS_TOKEN) != null) {
            return accessToken;
        }
        return null;
    }

至此,我们通过两种方式都可以获取微信用户的OpenID了,至于采用哪一种可以根据实际业务环境;

PS: OpenID是介于微信用户与公众账号之间恒定不变的,所以可以进行三方持久化存储;

2018-07-16 14:27:05 xinpz 阅读数 2228
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27821 人正在学习 去看看 秦子恒

一、问题场景

  开发模式的微信服务号开通用户身份绑定功能,将微信用户openId与输入的身份证号码进行校验绑定。微信用户关注服务号成功后响应图文消息,点击身份绑定跳转到身份绑定页面,输入身份证号码点击查询信息并绑定。

  这个场景中身份绑定信息后台无法获取该微信用户的OpenId。想要获取微信用户信息,就需要微信平台回调模式。微信提供了回调模式,这种回调模式的可以将用户发送给微信的信息,转发到用户提供的一个回调接口上,该接口解析用户发送过来的信息,解析后进行相应处理。而且回调模式中,可以调用的东西不少,扫码,图片,视频,地理位置信息等。

二、开启回调模式注意点

1.      必须使用外网能够访问得到的URL(不能是本地服务器)

2.      JDK版本必须要1.7以上

3.      jec加解密包必须与JDKversion一致

4.      微信企业号开启回调模式默认只支持80或443端口

三、案例代码

1.微信服务号菜单链接__身份绑定请求路径

http://服务器域名/educloud/response/getCode

2. 请求Mapping的Controller

package com.zichen.xhkq.controller.mine;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.zichen.xhkq.pojo.OpenidStatus;
import com.zichen.xhkq.service.mine.BindStatusService;
import com.zichen.xhkq.service.mine.WechatService;
import com.zichen.xhkq.util.Constants;
import com.zichen.xhkq.util.HttpUtil;
import com.zichen.xhkq.util.PropertiesHelper;

@Controller
@RequestMapping("/response")
public class ResponseController {
	@Resource
	private BindStatusService bindStatusService;
	@Resource
	private WechatService wechatService;
	private static Logger  log = LogManager.getLogger(ResponseController.class);
	//绑定身份
	@RequestMapping("/getCode")
	public String getCode(int schoolId){
		System.out.println("测试getCode"+schoolId);
		String backUri = Constants.REDIRECT_BINDURL.replace("relayDomanName", PropertiesHelper.getRelayDomanName());
		String appid = wechatService.selectWechat(schoolId).getAppid();	
		String url = Constants.NET_AUTHORIZE;
		try {
			url = url.replace("APPID", appid).replace("REDIRECT_URI", URLEncoder.encode(backUri, "utf-8")).replace("SCOPE", Constants.WXPAY_SCOPE).replace("STATE", Constants.WXPAY_STATE);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		log.info("跳转的页面"+url);
		return "redirect:"+url;
	}
	
	@RequestMapping("/getOpenid")
	public String getOpenid(String code,HttpServletRequest request, HttpServletResponse response,int schoolId){
		log.info("网页授权获取/getOpenid");
		String appid = wechatService.selectWechat(schoolId).getAppid();	
		String appsecret = wechatService.selectWechat(schoolId).getAppsecret();	
		//先网页授权,通过网页授权后获取code参数,通过code参数获取access-token。
        String openId = "";
        String result = "";
        String URL = Constants.NET_ACCESSTOKEN;
        URL = URL.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);
        log.info("网页授权获取access-token的的链接为"+URL);
        
        JSONObject jsonObject = HttpUtil.httpsRequest(URL, "GET", null);
        if (null != jsonObject) {
       	    log.info("调用网页授权接口链接返回的值为"+jsonObject.toString());
       	    HttpSession session = request.getSession();
            openId = jsonObject.getString("openid");
            session.setAttribute("openId", openId);
            List<OpenidStatus> status = bindStatusService.findStatus(openId);
            if(status!=null && status.size()>0){
            	for (int i = 0; i < status.size(); i++) {
					if (status.get(i)!=null) {
						session.setAttribute("status", status.get(i));
						result="hasbind-user";
					}
				}
            }else {
            	result="bind-user";
			}
        }
        return result;
	}
	
}

3.准备回调路劲Constants.REDIRECT_BINDURL

该路径为调用微信公众平台授权后的回调项目路径

/**绑定身份时的授权回调方法*/
	public static final String REDIRECT_BINDURL = "http://relayDomanName/educloud/response/getOpenid";

4. 微信公共平台网页授权请求Constants.NET_AUTHORIZE

/** 网页授权请求(APPID、SCOPE需要替换REDIRECT_URI需要转码后替换) */
	public static final String NET_AUTHORIZE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";

5. 替换URL中的参数

url = url.replace("APPID", appid).replace("REDIRECT_URI", URLEncoder.encode(backUri, "utf-8")).replace("SCOPE", Constants.WXPAY_SCOPE).replace("STATE", Constants.WXPAY_STATE);

其中:

(1)APPID 为服务号appid

(2)REDIRECT_URI 为授权后的回调路径,3中已准备好

(3)SCOPE 授权作用域 Constants.WXPAY_SCOPE

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

(4)STATE  state参数  Constants.WXPAY_STATE

 /**重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节*/
    public static final String WXPAY_STATE               = "ejs";

(5) 重定向URL,向微信平台发送授权请求

return "redirect:"+url;


四、案例解析主要步骤

1.网页授权请求

/** 网页授权请求(APPID、SCOPE需要替换REDIRECT_URI需要转码后替换) */

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect;

2.获取网页内授权凭证

/** 获取网页内授权凭证(APPID、SECRET、CODE需要替换) */

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code;

 

3. 发送https请求Get方法







2019-03-26 17:00:35 guobinhui 阅读数 4405
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27821 人正在学习 去看看 秦子恒

10万+IT都在关注,史上最全面的微信公众号开发系列教程:基于Springboot开发公众号关注/取消关注事件

前言:

关于监听公众号用户关注和取消关注的消息事件,微信官方文档给出的参考内容寥寥无几,具体如何配置url,官方文档也没有具体的说明,确实很坑,让人很难懂,而且网上关于配置微信消息事件接口的讲解资料很少,大多数只讲到验证token的url的配置,很少有讲到消息接口的url配置注意事项,很多开发者朋友也经常会卡到这里,通过加笔者微信请教笔者,本篇内容是笔者经过深入钻研实现的。能读到本篇干货的读者都是幸运的,经过精心整理,笔者今天把实现过程和完整案例无私分享给广大开发者朋友。

之前文章笔者已经实现了在测试公众号接入URL进行token验证,从本节起,开始利用微信官方提供的公众号开发文档来实现不同的交互案例。(注意:如果开发者还没有接入url进行token验证操作,请参考笔者之前的开发教程【springmvc开发微信公众号接口 微信公众号测试账号配置接口Token验证】。本案例演示效果如下:用户关注后公众号测试账号自动回复定制化的各种消息响应用户,并且可以根据用户发的消息进行智能回复。

实现思路

1.打开公众账号测试网址http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login,扫码登陆测试公众号 

2.我们打开微信公众号开发文档https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432,选择左侧"消息管理"模块中的"接收普通消息",阅读微信官方开发文档。

文档中已经告诉我们,当普通微信用户向公众账号发送消息时,微信服务器会把该消息封装成XML数据包通过POST的方式发送到开发者填写的URL上。我们设置的URL仅仅只有一个,之前笔者分享的文章(【springmvc开发微信公众号接口 微信公众号测试账号配置接口Token验证】)中接入的url是用来做token验证的,就是微信服务器向开发者服务器发送GET请求过来,而现在是要用来做消息处理的,此时微信服务器向开发者服务器配置的url发送的是POST请求,因此我们只需要根据请求方式区分即可,配置的url和验证token配置的url保持一致即可,唯一不同的是,这次的请求接口路径上要用注解表明POST请求。详细见下面代码:

package com.chenyun.cloud.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.DocumentException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.chenyun.cloud.utils.CheckoutUtil;
import com.chenyun.cloud.utils.MessageUtil;
import com.chenyun.cloud.utils.WeiXinUtil;
import com.chenyun.cloud.utils.XmlUtil;

/**
 * 创建时间:2019年3月18日 下午3:35:33
 * 项目名称:weixindev
 * 类说明:微信开发之token验证以及各种消息处理
 * @author guobinhui
 * @since JDK 1.8.0_51
 */
@Controller
public class WeixinMsgController {

    public static String URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    /**
     * 微信消息接收和token验证
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value="/msg/checkToken",method=RequestMethod.GET)
    public void weChat(HttpServletRequest request, HttpServletResponse response) throws IOException {
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        if (isGet) {
            // 微信加密签名
            String signature = request.getParameter("signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            String echostr = request.getParameter("echostr");
            // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
            if (signature != null && CheckoutUtil.checkSignature(signature, timestamp, nonce)) {
                try {
                    boolean flag = CheckoutUtil.checkSignature(signature, timestamp, nonce);
                    System.out.println(flag);
                    PrintWriter print = response.getWriter();
                    print.write(echostr);
                    System.out.println(echostr);
                    print.flush();
                    print.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @RequestMapping(value="/msg/checkToken",method=RequestMethod.POST)
    @ResponseBody
    public String  responseEvent(HttpServletRequest req, HttpServletResponse resp)throws IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        String message = "success";
        try {
            //把微信返回的xml信息转义成map
            Map<String, String> map = XmlUtil.xmlToMap(req);
            System.out.println("微信接收到的消息为:"+map.toString());
            String fromUserName = map.get("FromUserName");//消息来源用户标识
            String toUserName = map.get("ToUserName");//消息目的用户标识
            String msgType = map.get("MsgType");//消息类型(event或者text)
            System.out.println("消息来源于:"+fromUserName);
            System.out.println("openId:"+toUserName);
            System.out.println("消息类型为:"+msgType);
            String eventType = map.get("Event");//事件类型
            String nickName = getUserNickName(fromUserName);
            if(MessageUtil.MSGTYPE_EVENT.equals(msgType)){//如果为事件类型
                if(MessageUtil.SUBSCIBE_EVENT.equals(eventType)){//处理订阅事件
                    String content = "欢迎关注,这是一个公众号测试账号,您可以回复任意消息测试,开发者郭先生,18629374628";
                    String msg = "@"+ nickName + "," +content;
                    System.out.println("事件类型为:"+","+eventType);
                    message = MessageUtil.subscribeForText(toUserName, fromUserName,msg);
                }else if(MessageUtil.UNSUBSCIBE_EVENT.equals(eventType)){//处理取消订阅事件
                    System.out.println("事件类型为:"+eventType);
                    message = MessageUtil.unsubscribe(toUserName, fromUserName);
                }
            }else {
                //微信消息分为事件推送消息和普通消息,非事件即为普通消息类型
                switch (msgType) {
                    case "text":{//文本消息
                        String content = map.get("Content");//用户发的消息内容
                        content = "您发的消息内容是:"+content+",如需帮助,请联系郭先生,18629374628";
                        message = MessageUtil.replyMsg(toUserName, fromUserName,content,"text");
                        break;
                    }
                    case "image":{//图片消息
                        String content = "您发的消息内容是图片,如需帮助,请联系郭先生,18629374628";
	                    message = MessageUtil.replyMsg(toUserName, fromUserName,content,"text");
                        break;
                    }	
                    default:{//其他类型的普通消息
                        break;
                    }
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        System.out.println("关注微信公众号自动回复的消息内容为:"+message);
        return message;
    }
    
    public static String getUserNickName(String openId) {
    	String nickName  = null;
    	try {
            Map map = WeiXinUtil.cacheTokenAndTicket();
            String token = (String)map.get("access_token");
            String url = URL.replace("OPENID", openId).replace("ACCESS_TOKEN", token);
            JSONObject obj = WeiXinUtil.HttpGet(url);
            nickName = (String)obj.get("nickname");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return nickName;
    }
}

次处access_token缓存7200秒是用笔者写的一个工具类实现的,这个工具类也一并分享给大家,主要思路就是通过IO流把生成的access_token写到项目所在的文件中每隔7200秒重新生成access_token覆盖原有的access_token,当然也可以用ehcache等缓存插件实现,那么所有的需要用到access_token的请求,取到的access_token都是实时的最新的。直接看代码:

public static  Map <String,Object> cacheTokenAndTicket() throws IOException {
	  Gson gson = new Gson();
      Map <String,Object> map = new HashMap <String,Object> ();
      String token = null;
      String ticket = null;
      JSONObject tokenObj = null; //需要获取的access_token对象;
      JSONObject ticketObj = null;//需要获取的jsapi_ticket对象;
      String filePath = System.getProperty("user.dir")+"/src/main/resources/token.txt";
      File file = new File(filePath);//Access_token保存的位置
      if (!file.exists())
        file.createNewFile();
      // 如果文件大小等于0,说明第一次使用,存入Access_token
      if (file.length() == 0) {
    	tokenObj = WeiXinUtil.getToken();
        token = (String)tokenObj.get("access_token");
        FileOutputStream fos = new FileOutputStream(filePath, false);// 不允许追加
        tokenObj.put("expires_in",System.currentTimeMillis()/1000+"");
        String json = gson.toJson(tokenObj);
        fos.write(json.getBytes());
        fos.close();
      }else {
    	//读取文件内容
        @SuppressWarnings("resource")
		FileInputStream fis = new FileInputStream(file);
        byte[] b = new byte[2048];
        int len = fis.read(b);
        String jsonAccess_token = new String(b, 0, len);// 读取到的文件内容
        JSONObject access_token = gson.fromJson(jsonAccess_token,JSONObject.class);
        if (access_token.get("expires_in") != null) {
          String lastSaveTime = (String)access_token.get("expires_in");
          long nowTime = System.currentTimeMillis()/1000;
          long remianTime = nowTime - Long.valueOf(lastSaveTime);
          if (remianTime < WeixinConstant.EXPIRESIN_TIME) {
        	  JSONObject access = gson.fromJson(jsonAccess_token,JSONObject.class);
        	  token = (String)access.get("access_token");
          } else {
        	  tokenObj = WeiXinUtil.getToken();
              FileOutputStream fos = new FileOutputStream(file, false);// 不允许追加
              tokenObj.put("expires_in",System.currentTimeMillis()/1000+"");
              String json = gson.toJson(tokenObj);
              fos.write((json).getBytes());
              fos.close();
          }
      }
      }
      map.put("access_token",token);
      map.put("jsapi_ticket",ticket);
      return map;
	}

点击这里免费获取源码 :https://download.csdn.net/download/guobinhui/11270776

更多JavaEE资料请关注下面公众号,欢迎广大开发者朋友一起交流。笔者电话(微信):18629374628

具体功能体验可以扫左边的公众号二维码体验 

2017-06-16 10:41:07 sss80657 阅读数 919
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27821 人正在学习 去看看 秦子恒

开贴记录下这一两天关于被微信公众号-新浪云折磨的日子

首先我是按照方倍工作室的微信开发公众号的步子来进行开发的,没想到这里面居然埋了一个大坑,

折磨得我不要不要的

这个坑就是:token验证老是不通过。试了许多网上的方法,有关于utf-8无bom格式的,有关于网络不好多试几次的

还有诸如加一个ob_clean();在echo $echoStr;之前之类的一些方法,但是并没有解决问题

苦思冥想的对着

新浪云的日记发呆,然而就在我郁闷不已的时候随手百度居然看到了 新浪云要实名验证才可以正常使用创建的应用

就在刚刚,笔者实名验证通过后,果不其然,token验证通过了。

我勒个擦,方倍真是太坏了,这里居然不明说,亏我还买了他的书。

这里重申一次,当你试过了网上的所有方法的时候还不能token验证成功

一定得去看看新浪云是否实名验证了!

这篇文章上面都是废话,就只有一句话,总结就是:

新浪云做微信开发时,要实名验证!

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