WxOpenMpServiceImpl.java 8.7 KB
package org.theyeasy.weixin.service.impl;

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

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.theyeasy.weixin.service.WxOpenMpService;
import org.theyeasy.weixin.util.WxTokenServiceConstant;

import redis.clients.jedis.Jedis;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.w1hd.zzhnc.util.PropertiesFileUtil;
import com.w1hd.zzhnc.util.RedisUtil;

import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;

/**
 * 微信公众号服务类
 * @author Administrator
 *
 */
public class WxOpenMpServiceImpl extends WxMpServiceImpl {

	private static final JsonParser JSON_PARSER = new JsonParser();
	private String componentAppId;
	private String appId;
	
	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	/**
	 * 这是获取的第三方平台的AccessToken,不是公众号的Token(mark by lcc 171028)
	 */
	public String getComponentAccessToken() {
		String open_token_key=WxTokenServiceConstant.WX_OPEN_TOKEN_SERVICE.concat("_").concat(this.getComponentAppId());

		return RedisUtil.get3rdToken(open_token_key);
	}
	
	
	public WxOpenMpServiceImpl(String component_appId, String appId) {
		// TODO Auto-generated constructor stub
		this.componentAppId = component_appId;
		this.appId = appId;
		final WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
		// final WxMpInRedisConfigStorage config=new WxMpInRedisConfigStorage();
		config.setAppId(appId);// 设置微信公众号的appid
		this.setWxMpConfigStorage(config);
	}

	/**
	 * 这是获取公众号的Token,不是获取第三方平台的OpenToken(mark by lcc 171028)
	 */
	@Override
	public String getAccessToken(boolean forceRefresh) throws WxErrorException {

		String open_mp_token_key = WxTokenServiceConstant.WX_OPEN_AUTHOR_TOKEN_SERVICE.concat("_").concat(getComponentAppId()).concat("_").concat(this.getAppId());

		String open_mp_token = RedisUtil.get3rdToken(open_mp_token_key);

		System.out.println(open_mp_token);

		return open_mp_token;
	}

	public String getComponentAppId() {
		return componentAppId;
	}

	@Override
	public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {

		if (forceRefresh) {
			this.getWxMpConfigStorage().expireJsapiTicket();
		}

		if (this.getWxMpConfigStorage().isJsapiTicketExpired()) {
			String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
			String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
			JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
			JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
			String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
			int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
			this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds);
		}
		return this.getWxMpConfigStorage().getJsapiTicket();
	}

	public void setComponentAppId(String componentAppId) {
		this.componentAppId = componentAppId;
	}

	public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
		try {
			T result = executeInternal(executor, uri, data);
			this.log.debug("\n[URL]:  {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, result);
			return result;
		} catch (WxErrorException e) {
			log.error(e.getMessage(), e);
			return null;
		}
	}

	protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
		if (uri.indexOf("access_token=") != -1) {
			throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
		}
		String accessToken = getAccessToken(false);

		String uriWithAccessToken = uri;
		uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;

		try {
			return executor.execute(getHttpclient(), this.getHttpProxy(), uriWithAccessToken, data);
		} catch (WxErrorException e) {
			WxError error = e.getError();

			if (error.getErrorCode() != 0) {
				this.log.error("\n[URL]:  {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, error);
				throw new WxErrorException(error);
			}
			return null;
		} catch (IOException e) {
			this.log.error("\n[URL]:  {}\n[PARAMS]: {}\n[EXCEPTION]: {}", uri, data, e.getMessage());
			throw new RuntimeException(e);
		}
	}

	@Override
	public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) {
		StringBuilder url = new StringBuilder();
		url.append("https://open.weixin.qq.com/connect/oauth2/authorize?");
		url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
		url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI));
		url.append("&response_type=code");
		url.append("&scope=").append(scope);
		if (state != null) {
			url.append("&state=").append(state);
		}
		url.append("&component_appid=").append(getComponentAppId());
		url.append("#wechat_redirect");
		return url.toString();
		
				
	}

	private WxMpOAuth2AccessToken getOAuth2AccessToken(StringBuilder url) throws WxErrorException {
		try {
			RequestExecutor<String, String> executor = new SimpleGetRequestExecutor();
			String responseText = executor.execute(this.getHttpclient(), this.getHttpProxy(), url.toString(), null);
			return WxMpOAuth2AccessToken.fromJson(responseText);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException {
		StringBuilder url = new StringBuilder();
		url.append("https://api.weixin.qq.com/sns/oauth2/component/access_token?");
		url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
		url.append("&code=").append(code);
		url.append("&&grant_type=").append("authorization_code");
		url.append("&component_appid=").append(this.getComponentAppId());
		url.append("&component_access_token=").append(this.getComponentAccessToken());

		return this.getOAuth2AccessToken(url);
	}

	@Override
	public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException {
		StringBuilder url = new StringBuilder();
		url.append("https://api.weixin.qq.com/sns/oauth2/component/refresh_token?");
		url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
		url.append("&grant_type=refresh_token");
		url.append("&refresh_token=").append(refreshToken);
		url.append("&component_appid=").append(this.getComponentAppId());
		url.append("&component_access_token=").append(this.getComponentAccessToken());

		return this.getOAuth2AccessToken(url);
	}

	@Override
	public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException {
		StringBuilder url = new StringBuilder();
		url.append("https://api.weixin.qq.com/sns/userinfo?");
		url.append("access_token=").append(oAuth2AccessToken.getAccessToken());
		url.append("&openid=").append(oAuth2AccessToken.getOpenId());
		if (lang == null) {
			url.append("&lang=zh_CN");
		} else {
			url.append("&lang=").append(lang);
		}

		try {
			RequestExecutor<String, String> executor = new SimpleGetRequestExecutor();
			String responseText = executor.execute(getHttpclient(), this.getHttpProxy(), url.toString(), null);
			return WxMpUser.fromJson(responseText);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) {
		StringBuilder url = new StringBuilder();
		url.append("https://api.weixin.qq.com/sns/auth?");
		url.append("access_token=").append(oAuth2AccessToken.getAccessToken());
		url.append("&openid=").append(oAuth2AccessToken.getOpenId());

		try {
			RequestExecutor<String, String> executor = new SimpleGetRequestExecutor();
			executor.execute(getHttpclient(), this.getHttpProxy(), url.toString(), null);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (WxErrorException e) {
			return false;
		}
		return true;
	}

	
	
	 
}