WeixinHelper.java 5.6 KB
Newer Older
苗卫卫 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
package com.boco.nbd.wios.wx.weixin;

import com.boco.nbd.cams.core.constant.CamsConstant;
import com.ihidea.component.cache.redis.RedisClient;
import com.ihidea.core.support.exception.ServiceException;
import com.ihidea.core.util.HttpClientUtils;
import com.ihidea.core.util.JSONUtilsEx;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.Map;

/**
 * 微信公众号帮助类
 *
 * @author Kevin
 */
@Component
public class WeixinHelper {

    private static Log logger = LogFactory.getLog(WeixinHelper.class);

    /**
     * 通过code换取网页授权access_token
     */
    private static final String SNS_API_URL_GET_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";

    // 获取调用接口基础access_token
    protected static final String GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";

    // 获取票据
    protected static final String WX_JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";

    protected static final String WX_MEDIA_GET = "https://api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}";

    private static String weixinAppId;

    @Value("${weixin.appId}")
    public void setWeixinAppId(String appId) {
        WeixinHelper.weixinAppId = appId;
    }

    private static String weixinAppSecret;

    @Value("${weixin.appSecret}")
    public void setWeixinAppSecret(String appSecret) {
        WeixinHelper.weixinAppSecret = appSecret;
    }

    /**
     * 通过code换取网页授权access_token
     *
     * @param appid  公众号的唯一标识
     * @param secret 公众号的appsecret
     * @param code   获取的code参数
     * @return AccessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
     * @Title: getAccessTokenByCode
     * @Description: 通过code换取网页授权access_token, 此access_token与基础支持的access_token不同
     * @see AccessToken
     */
    public static AccessToken getAccessTokenByCode(String appid, String secret, String code) {
        String url = MessageFormat.format(SNS_API_URL_GET_ACCESS_TOKEN, appid, secret, code);
        String result = HttpClientUtils.get(url, null, CamsConstant.UTF_8, CamsConstant.UTF_8);
        logger.debug("获取微信openId返回:" + result);
        AccessToken token = JSONUtilsEx.deserialize(result, AccessToken.class);
        return token;
    }

    public static String getOpenIdByCode(String code) {
        AccessToken accessToken = getAccessTokenByCode(weixinAppId, weixinAppSecret, code);
        return accessToken != null ? accessToken.getOpenid() : null;
    }

    public static String getAccessToken(String appid, String secret) {
        // String accessToken="";
        String accessToken = RedisClient.get("wxAccessTokenCache_" + appid, String.class);

        if (StringUtils.isEmpty(accessToken)) {
            String url = MessageFormat.format(GET_ACCESS_TOKEN, appid, secret);
            String tokenJson = HttpClientUtils.get(url, null, CamsConstant.UTF_8, CamsConstant.UTF_8);
            logger.debug("请求accessToken返回:" + tokenJson);
            AccessToken token = JSONUtilsEx.deserialize(tokenJson, AccessToken.class);
            if (token != null && StringUtils.isNotEmpty(token.getAccess_token())) {
                RedisClient.put("wxAccessTokenCache_" + appid, token.getAccess_token(), 5400);
                accessToken = token.getAccess_token();
            } else {
                throw new ServiceException("获取微信access_token发生异常");
            }
        }

        return accessToken;
    }

    public static String getJsapiTicket(String appid, String secret) {
        String accessToken = getAccessToken(appid, secret);
        String jsapiTicket = RedisClient.get("wxJsapiTicketCache_" + appid, String.class);

        if (StringUtils.isEmpty(jsapiTicket)) {
            String url = MessageFormat.format(WX_JSAPI_TICKET, accessToken);
            JsapiTicket ticket = JSONUtilsEx.deserialize(HttpClientUtils.get(url, null, CamsConstant.UTF_8, CamsConstant.UTF_8), JsapiTicket.class);
            if (ticket != null && StringUtils.isNotEmpty(ticket.getTicket())) {
                RedisClient.put("wxJsapiTicketCache_" + appid, ticket.getTicket(), 5400);
                jsapiTicket = ticket.getTicket();
            } else {
                if (ticket.getErrcode() != null && ticket.getErrcode() == 42001) {
                    RedisClient.remove("wxAccessTokenCache_" + appid);
                    return getJsapiTicket(appid, secret);
                }
                throw new ServiceException("获取微信jsapiTicket发生异常");
            }
        }

        return jsapiTicket;
    }

    public static byte[] getMediaContent(String mediaId) {
        String accessToken = getAccessToken(weixinAppId, weixinAppSecret);

        String url = MessageFormat.format(WX_MEDIA_GET, accessToken, mediaId);
        byte[] result = HttpClientUtils.getContent(url, null, CamsConstant.UTF_8);
        String resultStr = new String(result);
        if (StringUtils.contains(resultStr, "errcode")) {
            Map<String, String> resultMap = JSONUtilsEx.deserialize(resultStr, Map.class);
            throw new ServiceException(resultMap.get("errmsg"));
        }
        return result;
    }
}