@@ -1,21 +1,7 @@
package me.chanjar.weixin.mp.api.impl ;
import com.google.gson.JsonArray ;
import com.google.gson.JsonElement ;
import com.google.gson.JsonObject ;
import com.google.gson.JsonParser ;
import me.chanjar.weixin.common.bean.WxAccessToken ;
import me.chanjar.weixin.common.bean.WxJsapiSignature ;
import me.chanjar.weixin.common.bean.result.WxError ;
import me.chanjar.weixin.common.exception.WxErrorException ;
import me.chanjar.weixin.common.session.StandardSessionManager ;
import me.chanjar.weixin.common.session.WxSessionManager ;
import me.chanjar.weixin.common.util.RandomUtils ;
import me.chanjar.weixin.common.util.crypto.SHA1 ;
import me.chanjar.weixin.common.util.http.* ;
import me.chanjar.weixin.mp.api.* ;
import me.chanjar.weixin.mp.bean.* ;
import me.chanjar.weixin.mp.bean.result.* ;
import java.io.IOException ;
import org.apache.http.HttpHost ;
import org.apache.http.client.config.RequestConfig ;
import org.apache.http.client.methods.CloseableHttpResponse ;
@@ -27,7 +13,51 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import java.io.IOException ;
import com.google.gson.JsonArray ;
import com.google.gson.JsonElement ;
import com.google.gson.JsonObject ;
import com.google.gson.JsonParser ;
import me.chanjar.weixin.common.bean.WxAccessToken ;
import me.chanjar.weixin.common.bean.WxJsapiSignature ;
import me.chanjar.weixin.common.bean.result.WxError ;
import me.chanjar.weixin.common.exception.WxErrorException ;
import me.chanjar.weixin.common.session.StandardSessionManager ;
import me.chanjar.weixin.common.session.WxSessionManager ;
import me.chanjar.weixin.common.util.RandomUtils ;
import me.chanjar.weixin.common.util.crypto.SHA1 ;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder ;
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder ;
import me.chanjar.weixin.common.util.http.RequestExecutor ;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor ;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor ;
import me.chanjar.weixin.common.util.http.URIUtil ;
import me.chanjar.weixin.mp.api.WxMpCardService ;
import me.chanjar.weixin.mp.api.WxMpConfigStorage ;
import me.chanjar.weixin.mp.api.WxMpDataCubeService ;
import me.chanjar.weixin.mp.api.WxMpGroupService ;
import me.chanjar.weixin.mp.api.WxMpKefuService ;
import me.chanjar.weixin.mp.api.WxMpMaterialService ;
import me.chanjar.weixin.mp.api.WxMpMenuService ;
import me.chanjar.weixin.mp.api.WxMpPayService ;
import me.chanjar.weixin.mp.api.WxMpQrcodeService ;
import me.chanjar.weixin.mp.api.WxMpService ;
import me.chanjar.weixin.mp.api.WxMpUserService ;
import me.chanjar.weixin.mp.api.WxMpUserTagService ;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage ;
import me.chanjar.weixin.mp.bean.WxMpIndustry ;
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage ;
import me.chanjar.weixin.mp.bean.WxMpMassNews ;
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage ;
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage ;
import me.chanjar.weixin.mp.bean.WxMpMassVideo ;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery ;
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage ;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult ;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult ;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken ;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult ;
import me.chanjar.weixin.mp.bean.result.WxMpUser ;
public class WxMpServiceImpl implements WxMpService {
@@ -45,7 +75,7 @@ public class WxMpServiceImpl implements WxMpService {
*/
private final Object globalJsapiTicketRefreshLock = new Object ( ) ;
private WxMpConfigStorage wxMpC onfigStorage;
private WxMpConfigStorage c onfigStorage;
private WxMpKefuService kefuService = new WxMpKefuServiceImpl ( this ) ;
@@ -80,7 +110,8 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public boolean checkSignature ( String timestamp , String nonce , String signature ) {
try {
return SHA1 . gen ( this . wxMpC onfigStorage. getToken ( ) , timestamp , nonce ) . equals ( signature ) ;
return SHA1 . gen ( this . c onfigStorage. getToken ( ) , timestamp , nonce )
. equals ( signature ) ;
} catch ( Exception e ) {
return false ;
}
@@ -94,14 +125,14 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public String getAccessToken ( boolean forceRefresh ) throws WxErrorException {
if ( forceRefresh ) {
this . wxMpC onfigStorage. expireAccessToken ( ) ;
this . c onfigStorage. expireAccessToken ( ) ;
}
if ( this . wxMpC onfigStorage. isAccessTokenExpired ( ) ) {
if ( this . c onfigStorage. isAccessTokenExpired ( ) ) {
synchronized ( this . globalAccessTokenRefreshLock ) {
if ( this . wxMpC onfigStorage. isAccessTokenExpired ( ) ) {
if ( this . c onfigStorage. isAccessTokenExpired ( ) ) {
String url = " https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential " +
" &appid= " + this . wxMpC onfigStorage. getAppId ( ) +
" &secret= " + this . wxMpC onfigStorage. getSecret ( ) ;
" &appid= " + this . c onfigStorage. getAppId ( ) + " &secret= "
+ this . c onfigStorage. getSecret ( ) ;
try {
HttpGet httpGet = new HttpGet ( url ) ;
if ( this . httpProxy ! = null ) {
@@ -115,7 +146,8 @@ public class WxMpServiceImpl implements WxMpService {
throw new WxErrorException ( error ) ;
}
WxAccessToken accessToken = WxAccessToken . fromJson ( resultContent ) ;
this . wxMpC onfigStorage. updateAccessToken ( accessToken . getAccessToken ( ) , accessToken . getExpiresIn ( ) ) ;
this . c onfigStorage. updateAccessToken ( accessToken . getAccessToken ( ) ,
accessToken . getExpiresIn ( ) ) ;
} finally {
httpGet . releaseConnection ( ) ;
}
@@ -125,7 +157,7 @@ public class WxMpServiceImpl implements WxMpService {
}
}
}
return this . wxMpC onfigStorage. getAccessToken ( ) ;
return this . c onfigStorage. getAccessToken ( ) ;
}
@Override
@@ -136,23 +168,23 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public String getJsapiTicket ( boolean forceRefresh ) throws WxErrorException {
if ( forceRefresh ) {
this . wxMpC onfigStorage. expireJsapiTicket ( ) ;
this . c onfigStorage. expireJsapiTicket ( ) ;
}
if ( this . wxMpC onfigStorage. isJsapiTicketExpired ( ) ) {
if ( this . c onfigStorage. isJsapiTicketExpired ( ) ) {
synchronized ( this . globalJsapiTicketRefreshLock ) {
if ( this . wxMpC onfigStorage. isJsapiTicketExpired ( ) ) {
if ( this . c onfigStorage. 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 . wxMpC onfigStorage. updateJsapiTicket ( jsapiTicket , expiresInSeconds ) ;
this . c onfigStorage. updateJsapiTicket ( jsapiTicket , expiresInSeconds ) ;
}
}
}
return this . wxMpC onfigStorage. getJsapiTicket ( ) ;
return this . c onfigStorage. getJsapiTicket ( ) ;
}
@Override
@@ -163,7 +195,7 @@ public class WxMpServiceImpl implements WxMpService {
String signature = SHA1 . genWithAmple ( " jsapi_ticket= " + jsapiTicket ,
" noncestr= " + noncestr , " timestamp= " + timestamp , " url= " + url ) ;
WxJsapiSignature jsapiSignature = new WxJsapiSignature ( ) ;
jsapiSignature . setAppid ( this . wxMpC onfigStorage. getAppId ( ) ) ;
jsapiSignature . setAppid ( this . c onfigStorage. getAppId ( ) ) ;
jsapiSignature . setTimestamp ( timestamp ) ;
jsapiSignature . setNoncestr ( noncestr ) ;
jsapiSignature . setUrl ( url ) ;
@@ -264,7 +296,7 @@ public class WxMpServiceImpl implements WxMpService {
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 . wxMpC onfigStorage. getAppId ( ) ) ;
url . append ( " appid= " ) . append ( this . c onfigStorage. getAppId ( ) ) ;
url . append ( " &redirect_uri= " ) . append ( URIUtil . encodeURIComponent ( redirectURI ) ) ;
url . append ( " &response_type=code " ) ;
url . append ( " &scope= " ) . append ( scope ) ;
@@ -280,7 +312,7 @@ public class WxMpServiceImpl implements WxMpService {
String state ) {
StringBuilder url = new StringBuilder ( ) ;
url . append ( " https://open.weixin.qq.com/connect/qrconnect? " ) ;
url . append ( " appid= " ) . append ( this . wxMpC onfigStorage. getAppId ( ) ) ;
url . append ( " appid= " ) . append ( this . c onfigStorage. getAppId ( ) ) ;
url . append ( " &redirect_uri= " ) . append ( URIUtil . encodeURIComponent ( redirectURI ) ) ;
url . append ( " &response_type=code " ) ;
url . append ( " &scope= " ) . append ( scope ) ;
@@ -306,8 +338,8 @@ public class WxMpServiceImpl implements WxMpService {
public WxMpOAuth2AccessToken oauth2getAccessToken ( String code ) throws WxErrorException {
StringBuilder url = new StringBuilder ( ) ;
url . append ( " https://api.weixin.qq.com/sns/oauth2/access_token? " ) ;
url . append ( " appid= " ) . append ( this . wxMpC onfigStorage. getAppId ( ) ) ;
url . append ( " &secret= " ) . append ( this . wxMpC onfigStorage. getSecret ( ) ) ;
url . append ( " appid= " ) . append ( this . c onfigStorage. getAppId ( ) ) ;
url . append ( " &secret= " ) . append ( this . c onfigStorage. getSecret ( ) ) ;
url . append ( " &code= " ) . append ( code ) ;
url . append ( " &grant_type=authorization_code " ) ;
@@ -318,7 +350,7 @@ public class WxMpServiceImpl implements WxMpService {
public WxMpOAuth2AccessToken oauth2refreshAccessToken ( String refreshToken ) throws WxErrorException {
StringBuilder url = new StringBuilder ( ) ;
url . append ( " https://api.weixin.qq.com/sns/oauth2/refresh_token? " ) ;
url . append ( " appid= " ) . append ( this . wxMpC onfigStorage. getAppId ( ) ) ;
url . append ( " appid= " ) . append ( this . c onfigStorage. getAppId ( ) ) ;
url . append ( " &grant_type=refresh_token " ) ;
url . append ( " &refresh_token= " ) . append ( refreshToken ) ;
@@ -438,7 +470,7 @@ public class WxMpServiceImpl implements WxMpService {
*/
if ( error . getErrorCode ( ) = = 42001 | | error . getErrorCode ( ) = = 40001 ) {
// 强制设置wxMpConfigStorage它的access token过期了, 这样在下一次请求里就会刷新access token
this . wxMpC onfigStorage. expireAccessToken ( ) ;
this . c onfigStorage. expireAccessToken ( ) ;
return execute ( executor , uri , data ) ;
}
if ( error . getErrorCode ( ) ! = 0 ) {
@@ -460,33 +492,37 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public void setWxMpConfigStorage ( WxMpConfigStorage wxConfigProvider ) {
this . wxMpC onfigStorage = wxConfigProvider ;
this . c onfigStorage = wxConfigProvider ;
this . initHttpClient ( ) ;
}
private void initHttpClient ( ) {
ApacheHttpClientBuilder apacheHttpClientBuilder = this . wxMpC onfigStorage. getApacheHttpClientBuilder ( ) ;
ApacheHttpClientBuilder apacheHttpClientBuilder = this . c onfigStorage
. getApacheHttpClientBuilder ( ) ;
if ( null = = apacheHttpClientBuilder ) {
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder . get ( ) ;
}
apacheHttpClientBuilder . httpProxyHost ( this . wxMpC onfigStorage. getHttpProxyHost ( ) )
. httpProxyPort ( this . wxMpC onfigStorage. getHttpProxyPort ( ) )
. httpProxyUsername ( this . wxMpC onfigStorage. getHttpProxyUsername ( ) )
. httpProxyPassword ( this . wxMpC onfigStorage. getHttpProxyPassword ( ) ) ;
apacheHttpClientBuilder . httpProxyHost ( this . c onfigStorage. getHttpProxyHost ( ) )
. httpProxyPort ( this . c onfigStorage. getHttpProxyPort ( ) )
. httpProxyUsername ( this . c onfigStorage. getHttpProxyUsername ( ) )
. httpProxyPassword ( this . c onfigStorage. getHttpProxyPassword ( ) ) ;
if ( this . wxMpC onfigStorage. getSSLContext ( ) ! = null ) {
if ( this . c onfigStorage. getSSLContext ( ) ! = null ) {
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory (
this . wxMpC onfigStorage. getSSLContext ( ) , new String [ ] { " TLSv1 " } , null , new DefaultHostnameVerifier ( ) ) ;
this . c onfigStorage. getSSLContext ( ) , new String [ ] { " TLSv1 " } , null ,
new DefaultHostnameVerifier ( ) ) ;
apacheHttpClientBuilder . sslConnectionSocketFactory ( sslsf ) ;
}
this . httpProxy = new HttpHost ( this . configStorage . getHttpProxyHost ( ) ,
this . configStorage . getHttpProxyPort ( ) ) ;
this . httpClient = apacheHttpClientBuilder . build ( ) ;
}
@Override
public WxMpConfigStorage getWxMpConfigStorage ( ) {
return this . wxMpC onfigStorage;
return this . c onfigStorage;
}
@Override