| @@ -5,7 +5,7 @@ | |||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| <groupId>me.chanjar</groupId> | <groupId>me.chanjar</groupId> | ||||
| <artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
| <version>1.0.3</version> | |||||
| <version>1.0.4</version> | |||||
| <packaging>pom</packaging> | <packaging>pom</packaging> | ||||
| <name>WeiXin Java Tools - Parent</name> | <name>WeiXin Java Tools - Parent</name> | ||||
| <description>微信公众号、企业号上级POM</description> | <description>微信公众号、企业号上级POM</description> | ||||
| @@ -6,7 +6,7 @@ | |||||
| <parent> | <parent> | ||||
| <groupId>me.chanjar</groupId> | <groupId>me.chanjar</groupId> | ||||
| <artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
| <version>1.0.3</version> | |||||
| <version>1.0.4</version> | |||||
| </parent> | </parent> | ||||
| <artifactId>weixin-java-common</artifactId> | <artifactId>weixin-java-common</artifactId> | ||||
| @@ -88,6 +88,7 @@ public class WxConsts { | |||||
| public static final String EVT_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; | public static final String EVT_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; | ||||
| public static final String EVT_PIC_WEIXIN = "pic_weixin"; | public static final String EVT_PIC_WEIXIN = "pic_weixin"; | ||||
| public static final String EVT_LOCATION_SELECT = "location_select"; | public static final String EVT_LOCATION_SELECT = "location_select"; | ||||
| public static final String EVT_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH"; | |||||
| /////////////////////// | /////////////////////// | ||||
| // 上传多媒体文件的类型 | // 上传多媒体文件的类型 | ||||
| @@ -8,10 +8,13 @@ import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; | import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.http.Header; | import org.apache.http.Header; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.entity.ContentType; | import org.apache.http.entity.ContentType; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| @@ -27,7 +30,7 @@ import java.util.regex.Pattern; | |||||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { | public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { | ||||
| @Override | @Override | ||||
| public File execute(String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { | |||||
| public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { | |||||
| if (queryParam != null) { | if (queryParam != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -36,6 +39,11 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| } | } | ||||
| HttpGet httpGet = new HttpGet(uri); | HttpGet httpGet = new HttpGet(uri); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet); | CloseableHttpResponse response = httpclient.execute(httpGet); | ||||
| Header[] contentTypeHeader = response.getHeaders("Content-Type"); | Header[] contentTypeHeader = response.getHeaders("Content-Type"); | ||||
| @@ -5,7 +5,9 @@ import java.io.IOException; | |||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import org.apache.http.HttpEntity; | import org.apache.http.HttpEntity; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpPost; | import org.apache.http.client.methods.HttpPost; | ||||
| import org.apache.http.entity.ContentType; | import org.apache.http.entity.ContentType; | ||||
| @@ -13,6 +15,7 @@ import org.apache.http.entity.mime.MultipartEntityBuilder; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| /** | /** | ||||
| * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | ||||
| @@ -22,8 +25,12 @@ import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> { | public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> { | ||||
| @Override | @Override | ||||
| public WxMediaUploadResult execute(String uri, File file) throws WxErrorException, ClientProtocolException, IOException { | |||||
| public WxMediaUploadResult execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, ClientProtocolException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | HttpPost httpPost = new HttpPost(uri); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpPost.setConfig(config); | |||||
| } | |||||
| if (file != null) { | if (file != null) { | ||||
| HttpEntity entity = MultipartEntityBuilder | HttpEntity entity = MultipartEntityBuilder | ||||
| .create() | .create() | ||||
| @@ -2,6 +2,7 @@ package me.chanjar.weixin.common.util.http; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.apache.http.impl.client.HttpClients; | import org.apache.http.impl.client.HttpClients; | ||||
| @@ -10,15 +11,23 @@ import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| /** | /** | ||||
| * http请求执行器 | * http请求执行器 | ||||
| * @author Daniel Qian | |||||
| * | * | ||||
| * @param <T> 返回值类型 | * @param <T> 返回值类型 | ||||
| * @param <E> 请求参数类型 | * @param <E> 请求参数类型 | ||||
| */ | */ | ||||
| public interface RequestExecutor<T, E> { | public interface RequestExecutor<T, E> { | ||||
| public static final CloseableHttpClient httpclient = HttpClients.createDefault(); | |||||
| /** | |||||
| * | |||||
| * @param httpclient 传入的httpClient | |||||
| * @param httpProxy http代理对象,如果没有配置代理则为空 | |||||
| * @param uri uri | |||||
| * @param data 数据 | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws ClientProtocolException | |||||
| * @throws IOException | |||||
| */ | |||||
| public T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, ClientProtocolException, IOException; | |||||
| public T execute(String uri, E data) throws WxErrorException, ClientProtocolException, IOException; | |||||
| } | } | ||||
| @@ -2,12 +2,15 @@ package me.chanjar.weixin.common.util.http; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
| import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| /** | /** | ||||
| * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | ||||
| @@ -17,7 +20,7 @@ import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, String> { | public class SimpleGetRequestExecutor implements RequestExecutor<String, String> { | ||||
| @Override | @Override | ||||
| public String execute(String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { | |||||
| public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { | |||||
| if (queryParam != null) { | if (queryParam != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -25,6 +28,11 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String> | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | ||||
| } | } | ||||
| HttpGet httpGet = new HttpGet(uri); | HttpGet httpGet = new HttpGet(uri); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet); | CloseableHttpResponse response = httpclient.execute(httpGet); | ||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | ||||
| WxError error = WxError.fromJson(responseContent); | WxError error = WxError.fromJson(responseContent); | ||||
| @@ -5,10 +5,20 @@ import java.io.IOException; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import org.apache.http.Consts; | import org.apache.http.Consts; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.auth.AuthScope; | |||||
| import org.apache.http.auth.UsernamePasswordCredentials; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.CredentialsProvider; | |||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | |||||
| import org.apache.http.client.methods.HttpPost; | import org.apache.http.client.methods.HttpPost; | ||||
| import org.apache.http.entity.StringEntity; | import org.apache.http.entity.StringEntity; | ||||
| import org.apache.http.impl.client.BasicCredentialsProvider; | |||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import org.apache.http.impl.client.HttpClients; | |||||
| import org.apache.http.util.EntityUtils; | |||||
| /** | /** | ||||
| * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | ||||
| @@ -18,12 +28,18 @@ import org.apache.http.entity.StringEntity; | |||||
| public class SimplePostRequestExecutor implements RequestExecutor<String, String> { | public class SimplePostRequestExecutor implements RequestExecutor<String, String> { | ||||
| @Override | @Override | ||||
| public String execute(String uri, String postEntity) throws WxErrorException, ClientProtocolException, IOException { | |||||
| public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, ClientProtocolException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | HttpPost httpPost = new HttpPost(uri); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpPost.setConfig(config); | |||||
| } | |||||
| if (postEntity != null) { | if (postEntity != null) { | ||||
| StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); | StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); | ||||
| httpPost.setEntity(entity); | httpPost.setEntity(entity); | ||||
| } | } | ||||
| CloseableHttpResponse response = httpclient.execute(httpPost); | CloseableHttpResponse response = httpclient.execute(httpPost); | ||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | ||||
| WxError error = WxError.fromJson(responseContent); | WxError error = WxError.fromJson(responseContent); | ||||
| @@ -6,7 +6,7 @@ | |||||
| <parent> | <parent> | ||||
| <groupId>me.chanjar</groupId> | <groupId>me.chanjar</groupId> | ||||
| <artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
| <version>1.0.3</version> | |||||
| <version>1.0.4</version> | |||||
| </parent> | </parent> | ||||
| <artifactId>weixin-java-cp</artifactId> | <artifactId>weixin-java-cp</artifactId> | ||||
| @@ -27,4 +27,12 @@ public interface WxCpConfigStorage { | |||||
| public int getExpiresIn(); | public int getExpiresIn(); | ||||
| public String getHttp_proxy_host(); | |||||
| public int getHttp_proxy_port(); | |||||
| public String getHttp_proxy_username(); | |||||
| public String getHttp_proxy_password(); | |||||
| } | } | ||||
| @@ -18,6 +18,11 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||||
| protected String agentId; | protected String agentId; | ||||
| protected int expiresIn; | protected int expiresIn; | ||||
| protected String http_proxy_host; | |||||
| protected int http_proxy_port; | |||||
| protected String http_proxy_username; | |||||
| protected String http_proxy_password; | |||||
| public void updateAccessToken(WxAccessToken accessToken) { | public void updateAccessToken(WxAccessToken accessToken) { | ||||
| updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | ||||
| } | } | ||||
| @@ -83,16 +88,53 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||||
| this.agentId = agentId; | this.agentId = agentId; | ||||
| } | } | ||||
| public String getHttp_proxy_host() { | |||||
| return http_proxy_host; | |||||
| } | |||||
| public void setHttp_proxy_host(String http_proxy_host) { | |||||
| this.http_proxy_host = http_proxy_host; | |||||
| } | |||||
| public int getHttp_proxy_port() { | |||||
| return http_proxy_port; | |||||
| } | |||||
| public void setHttp_proxy_port(int http_proxy_port) { | |||||
| this.http_proxy_port = http_proxy_port; | |||||
| } | |||||
| public String getHttp_proxy_username() { | |||||
| return http_proxy_username; | |||||
| } | |||||
| public void setHttp_proxy_username(String http_proxy_username) { | |||||
| this.http_proxy_username = http_proxy_username; | |||||
| } | |||||
| public String getHttp_proxy_password() { | |||||
| return http_proxy_password; | |||||
| } | |||||
| public void setHttp_proxy_password(String http_proxy_password) { | |||||
| this.http_proxy_password = http_proxy_password; | |||||
| } | |||||
| @Override | @Override | ||||
| public String toString() { | public String toString() { | ||||
| return "WxInMemoryCpConfigStorage{" + | |||||
| "appidOrCorpid='" + corpId + '\'' + | |||||
| return "WxCpInMemoryConfigStorage{" + | |||||
| "corpId='" + corpId + '\'' + | |||||
| ", corpSecret='" + corpSecret + '\'' + | ", corpSecret='" + corpSecret + '\'' + | ||||
| ", token='" + token + '\'' + | ", token='" + token + '\'' + | ||||
| ", accessToken='" + accessToken + '\'' + | ", accessToken='" + accessToken + '\'' + | ||||
| ", aesKey='" + aesKey + '\'' + | ", aesKey='" + aesKey + '\'' + | ||||
| ", agentId='" + agentId + '\'' + | ", agentId='" + agentId + '\'' + | ||||
| ", expiresIn=" + expiresIn + | ", expiresIn=" + expiresIn + | ||||
| ", http_proxy_host='" + http_proxy_host + '\'' + | |||||
| ", http_proxy_port=" + http_proxy_port + | |||||
| ", http_proxy_username='" + http_proxy_username + '\'' + | |||||
| ", http_proxy_password='" + http_proxy_password + '\'' + | |||||
| '}'; | '}'; | ||||
| } | } | ||||
| } | } | ||||
| @@ -7,6 +7,7 @@ import java.util.List; | |||||
| import me.chanjar.weixin.common.bean.WxMenu; | import me.chanjar.weixin.common.bean.WxMenu; | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import me.chanjar.weixin.cp.bean.*; | import me.chanjar.weixin.cp.bean.*; | ||||
| import me.chanjar.weixin.cp.bean.WxCpDepart; | import me.chanjar.weixin.cp.bean.WxCpDepart; | ||||
| import me.chanjar.weixin.cp.bean.WxCpUser; | import me.chanjar.weixin.cp.bean.WxCpUser; | ||||
| @@ -65,8 +66,8 @@ public interface WxCpService { | |||||
| * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件 | * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件 | ||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param mediaType 媒体类型, 请看{@link WxConsts} | |||||
| * @param fileType 文件类型,请看{@link WxConsts} | |||||
| * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} | |||||
| * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} | |||||
| * @param inputStream 输入流 | * @param inputStream 输入流 | ||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| */ | */ | ||||
| @@ -281,6 +282,40 @@ public interface WxCpService { | |||||
| */ | */ | ||||
| public void tagRemoveUsers(String tagId, List<String> userIds) throws WxErrorException; | public void tagRemoveUsers(String tagId, List<String> userIds) throws WxErrorException; | ||||
| /** | |||||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 | |||||
| * @param url | |||||
| * @param queryParam | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| String get(String url, String queryParam) throws WxErrorException; | |||||
| /** | |||||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 | |||||
| * @param url | |||||
| * @param postData | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| String post(String url, String postData) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * Service没有实现某个API的时候,可以用这个, | |||||
| * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。 | |||||
| * 可以参考,{@link me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor}的实现方法 | |||||
| * </pre> | |||||
| * @param executor | |||||
| * @param uri | |||||
| * @param data | |||||
| * @param <T> | |||||
| * @param <E> | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException; | |||||
| /** | /** | ||||
| * 注入 {@link WxCpConfigStorage} 的实现 | * 注入 {@link WxCpConfigStorage} 的实现 | ||||
| * | * | ||||
| @@ -20,9 +20,15 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||||
| import me.chanjar.weixin.common.util.crypto.SHA1; | import me.chanjar.weixin.common.util.crypto.SHA1; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.auth.AuthScope; | |||||
| import org.apache.http.auth.UsernamePasswordCredentials; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.CredentialsProvider; | |||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.impl.client.BasicCredentialsProvider; | |||||
| import org.apache.http.impl.client.BasicResponseHandler; | import org.apache.http.impl.client.BasicResponseHandler; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.apache.http.impl.client.HttpClients; | import org.apache.http.impl.client.HttpClients; | ||||
| @@ -51,12 +57,14 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| */ | */ | ||||
| protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false); | protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false); | ||||
| protected static final CloseableHttpClient httpclient = HttpClients.createDefault(); | |||||
| protected WxCpConfigStorage wxCpConfigStorage; | protected WxCpConfigStorage wxCpConfigStorage; | ||||
| protected final ThreadLocal<Integer> retryTimes = new ThreadLocal<Integer>(); | protected final ThreadLocal<Integer> retryTimes = new ThreadLocal<Integer>(); | ||||
| protected CloseableHttpClient httpClient; | |||||
| protected HttpHost httpProxy; | |||||
| public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { | ||||
| try { | try { | ||||
| return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature); | return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature); | ||||
| @@ -78,6 +86,11 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| + "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); | + "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); | ||||
| try { | try { | ||||
| HttpGet httpGet = new HttpGet(url); | HttpGet httpGet = new HttpGet(url); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| CloseableHttpClient httpclient = getHttpclient(); | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet); | CloseableHttpResponse response = httpclient.execute(httpGet); | ||||
| String resultContent = new BasicResponseHandler().handleResponse(response); | String resultContent = new BasicResponseHandler().handleResponse(response); | ||||
| WxError error = WxError.fromJson(resultContent); | WxError error = WxError.fromJson(resultContent); | ||||
| @@ -308,6 +321,14 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| execute(new SimplePostRequestExecutor(), url, jsonObject.toString()); | execute(new SimplePostRequestExecutor(), url, jsonObject.toString()); | ||||
| } | } | ||||
| public String get(String url, String queryParam) throws WxErrorException { | |||||
| return execute(new SimpleGetRequestExecutor(), url, queryParam); | |||||
| } | |||||
| public String post(String url, String postData) throws WxErrorException { | |||||
| return execute(new SimplePostRequestExecutor(), url, postData); | |||||
| } | |||||
| /** | /** | ||||
| * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | ||||
| * | * | ||||
| @@ -327,7 +348,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | ||||
| try { | try { | ||||
| return executor.execute(uriWithAccessToken, data); | |||||
| return executor.execute(getHttpclient(), httpProxy, uriWithAccessToken, data); | |||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| /* | /* | ||||
| @@ -371,8 +392,38 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| } | } | ||||
| } | } | ||||
| protected CloseableHttpClient getHttpclient() { | |||||
| return httpClient; | |||||
| } | |||||
| public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { | public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { | ||||
| this.wxCpConfigStorage = wxConfigProvider; | this.wxCpConfigStorage = wxConfigProvider; | ||||
| String http_proxy_host = wxCpConfigStorage.getHttp_proxy_host(); | |||||
| int http_proxy_port = wxCpConfigStorage.getHttp_proxy_port(); | |||||
| String http_proxy_username = wxCpConfigStorage.getHttp_proxy_username(); | |||||
| String http_proxy_password = wxCpConfigStorage.getHttp_proxy_password(); | |||||
| if(StringUtils.isNotBlank(http_proxy_host)) { | |||||
| // 使用代理服务器 | |||||
| if(StringUtils.isNotBlank(http_proxy_username)) { | |||||
| // 需要用户认证的代理服务器 | |||||
| CredentialsProvider credsProvider = new BasicCredentialsProvider(); | |||||
| credsProvider.setCredentials( | |||||
| new AuthScope(http_proxy_host, http_proxy_port), | |||||
| new UsernamePasswordCredentials(http_proxy_username, http_proxy_password)); | |||||
| httpClient = HttpClients | |||||
| .custom() | |||||
| .setDefaultCredentialsProvider(credsProvider) | |||||
| .build(); | |||||
| } else { | |||||
| // 无需用户认证的代理服务器 | |||||
| httpClient = HttpClients.createDefault(); | |||||
| } | |||||
| httpProxy = new HttpHost(http_proxy_host, http_proxy_port); | |||||
| } else { | |||||
| httpClient = HttpClients.createDefault(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -5,6 +5,7 @@ import java.io.InputStream; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.List; | import java.util.List; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | |||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import org.testng.Assert; | import org.testng.Assert; | ||||
| import org.testng.annotations.DataProvider; | import org.testng.annotations.DataProvider; | ||||
| @@ -1,5 +1,6 @@ | |||||
| package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | |||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
| import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
| @@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.api; | |||||
| import java.util.Map; | import java.util.Map; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | |||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import org.testng.Assert; | import org.testng.Assert; | ||||
| @@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.api; | |||||
| import javax.xml.bind.JAXBException; | import javax.xml.bind.JAXBException; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | |||||
| import me.chanjar.weixin.common.bean.WxMenu; | import me.chanjar.weixin.common.bean.WxMenu; | ||||
| import org.testng.Assert; | import org.testng.Assert; | ||||
| import org.testng.annotations.DataProvider; | import org.testng.annotations.DataProvider; | ||||
| @@ -6,7 +6,7 @@ | |||||
| <parent> | <parent> | ||||
| <groupId>me.chanjar</groupId> | <groupId>me.chanjar</groupId> | ||||
| <artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
| <version>1.0.3</version> | |||||
| <version>1.0.4</version> | |||||
| </parent> | </parent> | ||||
| <artifactId>weixin-java-mp</artifactId> | <artifactId>weixin-java-mp</artifactId> | ||||
| <name>WeiXin Java Tools - MP</name> | <name>WeiXin Java Tools - MP</name> | ||||
| @@ -25,4 +25,12 @@ public interface WxMpConfigStorage { | |||||
| public int getExpiresIn(); | public int getExpiresIn(); | ||||
| public String getHttp_proxy_host(); | |||||
| public int getHttp_proxy_port(); | |||||
| public String getHttp_proxy_username(); | |||||
| public String getHttp_proxy_password(); | |||||
| } | } | ||||
| @@ -16,6 +16,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| protected String aesKey; | protected String aesKey; | ||||
| protected int expiresIn; | protected int expiresIn; | ||||
| protected String http_proxy_host; | |||||
| protected int http_proxy_port; | |||||
| protected String http_proxy_username; | |||||
| protected String http_proxy_password; | |||||
| public void updateAccessToken(WxAccessToken accessToken) { | public void updateAccessToken(WxAccessToken accessToken) { | ||||
| updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | ||||
| } | } | ||||
| @@ -73,5 +78,52 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
| this.expiresIn = expiresIn; | this.expiresIn = expiresIn; | ||||
| } | } | ||||
| public String getHttp_proxy_host() { | |||||
| return http_proxy_host; | |||||
| } | |||||
| public void setHttp_proxy_host(String http_proxy_host) { | |||||
| this.http_proxy_host = http_proxy_host; | |||||
| } | |||||
| public int getHttp_proxy_port() { | |||||
| return http_proxy_port; | |||||
| } | |||||
| public void setHttp_proxy_port(int http_proxy_port) { | |||||
| this.http_proxy_port = http_proxy_port; | |||||
| } | |||||
| public String getHttp_proxy_username() { | |||||
| return http_proxy_username; | |||||
| } | |||||
| public void setHttp_proxy_username(String http_proxy_username) { | |||||
| this.http_proxy_username = http_proxy_username; | |||||
| } | |||||
| public String getHttp_proxy_password() { | |||||
| return http_proxy_password; | |||||
| } | |||||
| public void setHttp_proxy_password(String http_proxy_password) { | |||||
| this.http_proxy_password = http_proxy_password; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return "WxMpInMemoryConfigStorage{" + | |||||
| "appId='" + appId + '\'' + | |||||
| ", secret='" + secret + '\'' + | |||||
| ", token='" + token + '\'' + | |||||
| ", accessToken='" + accessToken + '\'' + | |||||
| ", aesKey='" + aesKey + '\'' + | |||||
| ", expiresIn=" + expiresIn + | |||||
| ", http_proxy_host='" + http_proxy_host + '\'' + | |||||
| ", http_proxy_port=" + http_proxy_port + | |||||
| ", http_proxy_username='" + http_proxy_username + '\'' + | |||||
| ", http_proxy_password='" + http_proxy_password + '\'' + | |||||
| '}'; | |||||
| } | |||||
| } | } | ||||
| @@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.api; | |||||
| import me.chanjar.weixin.common.bean.WxMenu; | import me.chanjar.weixin.common.bean.WxMenu; | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import me.chanjar.weixin.mp.bean.*; | import me.chanjar.weixin.mp.bean.*; | ||||
| import me.chanjar.weixin.mp.bean.result.*; | import me.chanjar.weixin.mp.bean.result.*; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| @@ -306,10 +307,65 @@ public interface WxMpService { | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| */ | */ | ||||
| public String shortUrl(String long_url) throws WxErrorException; | public String shortUrl(String long_url) throws WxErrorException; | ||||
| /** | |||||
| * <pre> | |||||
| * 发送模板消息 | |||||
| * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=模板消息接口 | |||||
| * </pre> | |||||
| * @param templateMessage | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| public void templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 语义查询接口 | |||||
| * 详情请见:http://mp.weixin.qq.com/wiki/index.php?title=语义理解 | |||||
| * </pre> | |||||
| * @param semanticQuery | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; | |||||
| /** | /** | ||||
| * 注入 {@link WxMpConfigStorage} 的实现 | |||||
| * @param wxConfigProvider | |||||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 | |||||
| * @param url | |||||
| * @param queryParam | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| String get(String url, String queryParam) throws WxErrorException; | |||||
| /** | |||||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 | |||||
| * @param url | |||||
| * @param postData | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | */ | ||||
| String post(String url, String postData) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * Service没有实现某个API的时候,可以用这个, | |||||
| * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。 | |||||
| * 可以参考,{@link me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor}的实现方法 | |||||
| * </pre> | |||||
| * @param executor | |||||
| * @param uri | |||||
| * @param data | |||||
| * @param <T> | |||||
| * @param <E> | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException; | |||||
| /** | |||||
| * 注入 {@link WxMpConfigStorage} 的实现 | |||||
| * @param wxConfigProvider | |||||
| */ | |||||
| public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); | public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); | ||||
| } | } | ||||
| @@ -19,9 +19,16 @@ import me.chanjar.weixin.mp.bean.result.*; | |||||
| import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; | import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; | ||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.auth.AuthScope; | |||||
| import org.apache.http.auth.UsernamePasswordCredentials; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.CredentialsProvider; | |||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.client.methods.HttpPost; | |||||
| import org.apache.http.impl.client.BasicCredentialsProvider; | |||||
| import org.apache.http.impl.client.BasicResponseHandler; | import org.apache.http.impl.client.BasicResponseHandler; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.apache.http.impl.client.HttpClients; | import org.apache.http.impl.client.HttpClients; | ||||
| @@ -31,6 +38,7 @@ import java.io.IOException; | |||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.io.StringReader; | import java.io.StringReader; | ||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | |||||
| import java.util.UUID; | import java.util.UUID; | ||||
| import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||
| @@ -43,12 +51,14 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| */ | */ | ||||
| protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false); | protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false); | ||||
| protected static final CloseableHttpClient httpclient = HttpClients.createDefault(); | |||||
| protected WxMpConfigStorage wxMpConfigStorage; | protected WxMpConfigStorage wxMpConfigStorage; | ||||
| protected final ThreadLocal<Integer> retryTimes = new ThreadLocal<Integer>(); | protected final ThreadLocal<Integer> retryTimes = new ThreadLocal<Integer>(); | ||||
| protected CloseableHttpClient httpClient; | |||||
| protected HttpHost httpProxy; | |||||
| public boolean checkSignature(String timestamp, String nonce, String signature) { | public boolean checkSignature(String timestamp, String nonce, String signature) { | ||||
| try { | try { | ||||
| return SHA1.gen(wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature); | return SHA1.gen(wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature); | ||||
| @@ -66,6 +76,11 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| ; | ; | ||||
| try { | try { | ||||
| HttpGet httpGet = new HttpGet(url); | HttpGet httpGet = new HttpGet(url); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| CloseableHttpClient httpclient = getHttpclient(); | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet); | CloseableHttpResponse response = httpclient.execute(httpGet); | ||||
| String resultContent = new BasicResponseHandler().handleResponse(response); | String resultContent = new BasicResponseHandler().handleResponse(response); | ||||
| WxError error = WxError.fromJson(resultContent); | WxError error = WxError.fromJson(resultContent); | ||||
| @@ -272,8 +287,27 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | ||||
| return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); | return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); | ||||
| } | } | ||||
| /** | |||||
| public void templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException { | |||||
| String url = "https://api.weixin.qq.com/cgi-bin/message/template/send"; | |||||
| execute(new SimplePostRequestExecutor(), url, templateMessage.toJson()); | |||||
| } | |||||
| public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { | |||||
| String url = "https://api.weixin.qq.com/semantic/semproxy/search"; | |||||
| String responseContent = execute(new SimplePostRequestExecutor(), url, semanticQuery.toJson()); | |||||
| return WxMpSemanticQueryResult.fromJson(responseContent); | |||||
| } | |||||
| public String get(String url, String queryParam) throws WxErrorException { | |||||
| return execute(new SimpleGetRequestExecutor(), url, queryParam); | |||||
| } | |||||
| public String post(String url, String postData) throws WxErrorException { | |||||
| return execute(new SimplePostRequestExecutor(), url, postData); | |||||
| } | |||||
| /** | |||||
| * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | ||||
| * @param executor | * @param executor | ||||
| * @param uri | * @param uri | ||||
| @@ -291,7 +325,7 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | ||||
| try { | try { | ||||
| return executor.execute(uriWithAccessToken, data); | |||||
| return executor.execute(getHttpclient(), httpProxy, uriWithAccessToken, data); | |||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| /* | /* | ||||
| @@ -334,9 +368,39 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
| } | } | ||||
| } | } | ||||
| protected CloseableHttpClient getHttpclient() { | |||||
| return httpClient; | |||||
| } | |||||
| public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { | public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { | ||||
| this.wxMpConfigStorage = wxConfigProvider; | this.wxMpConfigStorage = wxConfigProvider; | ||||
| String http_proxy_host = wxMpConfigStorage.getHttp_proxy_host(); | |||||
| int http_proxy_port = wxMpConfigStorage.getHttp_proxy_port(); | |||||
| String http_proxy_username = wxMpConfigStorage.getHttp_proxy_username(); | |||||
| String http_proxy_password = wxMpConfigStorage.getHttp_proxy_password(); | |||||
| if(StringUtils.isNotBlank(http_proxy_host)) { | |||||
| // 使用代理服务器 | |||||
| if(StringUtils.isNotBlank(http_proxy_username)) { | |||||
| // 需要用户认证的代理服务器 | |||||
| CredentialsProvider credsProvider = new BasicCredentialsProvider(); | |||||
| credsProvider.setCredentials( | |||||
| new AuthScope(http_proxy_host, http_proxy_port), | |||||
| new UsernamePasswordCredentials(http_proxy_username, http_proxy_password)); | |||||
| httpClient = HttpClients | |||||
| .custom() | |||||
| .setDefaultCredentialsProvider(credsProvider) | |||||
| .build(); | |||||
| } else { | |||||
| // 无需用户认证的代理服务器 | |||||
| httpClient = HttpClients.createDefault(); | |||||
| } | |||||
| httpProxy = new HttpHost(http_proxy_host, http_proxy_port); | |||||
| } else { | |||||
| httpClient = HttpClients.createDefault(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,91 @@ | |||||
| package me.chanjar.weixin.mp.bean; | |||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
| /** | |||||
| * 语义理解查询用对象 | |||||
| * | |||||
| * http://mp.weixin.qq.com/wiki/index.php?title=语义理解 | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class WxMpSemanticQuery { | |||||
| private String query; | |||||
| private String category; | |||||
| private Float latitude; | |||||
| private Float longitude; | |||||
| private String city; | |||||
| private String region; | |||||
| private String appid; | |||||
| private String uid; | |||||
| public String getQuery() { | |||||
| return query; | |||||
| } | |||||
| public void setQuery(String query) { | |||||
| this.query = query; | |||||
| } | |||||
| public String getCategory() { | |||||
| return category; | |||||
| } | |||||
| public void setCategory(String category) { | |||||
| this.category = category; | |||||
| } | |||||
| public Float getLatitude() { | |||||
| return latitude; | |||||
| } | |||||
| public void setLatitude(Float latitude) { | |||||
| this.latitude = latitude; | |||||
| } | |||||
| public Float getLongitude() { | |||||
| return longitude; | |||||
| } | |||||
| public void setLongitude(Float longitude) { | |||||
| this.longitude = longitude; | |||||
| } | |||||
| public String getCity() { | |||||
| return city; | |||||
| } | |||||
| public void setCity(String city) { | |||||
| this.city = city; | |||||
| } | |||||
| public String getRegion() { | |||||
| return region; | |||||
| } | |||||
| public void setRegion(String region) { | |||||
| this.region = region; | |||||
| } | |||||
| public String getAppid() { | |||||
| return appid; | |||||
| } | |||||
| public void setAppid(String appid) { | |||||
| this.appid = appid; | |||||
| } | |||||
| public String getUid() { | |||||
| return uid; | |||||
| } | |||||
| public void setUid(String uid) { | |||||
| this.uid = uid; | |||||
| } | |||||
| public String toJson() { | |||||
| return WxMpGsonBuilder.create().toJson(this); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,49 @@ | |||||
| package me.chanjar.weixin.mp.bean; | |||||
| /** | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class WxMpTemplateData { | |||||
| private String name; | |||||
| private String value; | |||||
| private String color; | |||||
| public WxMpTemplateData() { | |||||
| } | |||||
| public WxMpTemplateData(String name, String value) { | |||||
| this.name = name; | |||||
| this.value = value; | |||||
| } | |||||
| public WxMpTemplateData(String name, String value, String color) { | |||||
| this.name = name; | |||||
| this.value = value; | |||||
| this.color = color; | |||||
| } | |||||
| public String getName() { | |||||
| return name; | |||||
| } | |||||
| public void setName(String name) { | |||||
| this.name = name; | |||||
| } | |||||
| public String getValue() { | |||||
| return value; | |||||
| } | |||||
| public void setValue(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| public String getColor() { | |||||
| return color; | |||||
| } | |||||
| public void setColor(String color) { | |||||
| this.color = color; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,62 @@ | |||||
| package me.chanjar.weixin.mp.bean; | |||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| /** | |||||
| * Created by qianjia on 14/11/1. | |||||
| */ | |||||
| public class WxMpTemplateMessage { | |||||
| private String toUser; | |||||
| private String templateId; | |||||
| private String url; | |||||
| private String topColor; | |||||
| private List<WxMpTemplateData> datas = new ArrayList<WxMpTemplateData>(); | |||||
| public String getToUser() { | |||||
| return toUser; | |||||
| } | |||||
| public void setToUser(String toUser) { | |||||
| this.toUser = toUser; | |||||
| } | |||||
| public String getTemplateId() { | |||||
| return templateId; | |||||
| } | |||||
| public void setTemplateId(String templateId) { | |||||
| this.templateId = templateId; | |||||
| } | |||||
| public String getUrl() { | |||||
| return url; | |||||
| } | |||||
| public void setUrl(String url) { | |||||
| this.url = url; | |||||
| } | |||||
| public String getTopColor() { | |||||
| return topColor; | |||||
| } | |||||
| public void setTopColor(String topColor) { | |||||
| this.topColor = topColor; | |||||
| } | |||||
| public List<WxMpTemplateData> getDatas() { | |||||
| return datas; | |||||
| } | |||||
| public void setDatas(List<WxMpTemplateData> datas) { | |||||
| this.datas = datas; | |||||
| } | |||||
| public String toJson() { | |||||
| return WxMpGsonBuilder.INSTANCE.create().toJson(this); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,73 @@ | |||||
| package me.chanjar.weixin.mp.bean.result; | |||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
| /** | |||||
| * 语义理解查询结果对象 | |||||
| * | |||||
| * http://mp.weixin.qq.com/wiki/index.php?title=语义理解 | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class WxMpSemanticQueryResult { | |||||
| private String query; | |||||
| private String type; | |||||
| private String semantic; | |||||
| private String result; | |||||
| private String answer; | |||||
| private String text; | |||||
| public String getQuery() { | |||||
| return query; | |||||
| } | |||||
| public void setQuery(String query) { | |||||
| this.query = query; | |||||
| } | |||||
| public String getType() { | |||||
| return type; | |||||
| } | |||||
| public void setType(String type) { | |||||
| this.type = type; | |||||
| } | |||||
| public String getSemantic() { | |||||
| return semantic; | |||||
| } | |||||
| public void setSemantic(String semantic) { | |||||
| this.semantic = semantic; | |||||
| } | |||||
| public String getResult() { | |||||
| return result; | |||||
| } | |||||
| public void setResult(String result) { | |||||
| this.result = result; | |||||
| } | |||||
| public String getAnswer() { | |||||
| return answer; | |||||
| } | |||||
| public void setAnswer(String answer) { | |||||
| this.answer = answer; | |||||
| } | |||||
| public String getText() { | |||||
| return text; | |||||
| } | |||||
| public void setText(String text) { | |||||
| this.text = text; | |||||
| } | |||||
| public static WxMpSemanticQueryResult fromJson(String json) { | |||||
| return WxMpGsonBuilder.create().fromJson(json, WxMpSemanticQueryResult.class); | |||||
| } | |||||
| } | |||||
| @@ -8,10 +8,13 @@ import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; | |||||
| import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; | import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import org.apache.http.Header; | import org.apache.http.Header; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.client.ClientProtocolException; | import org.apache.http.client.ClientProtocolException; | ||||
| import org.apache.http.client.config.RequestConfig; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.entity.ContentType; | import org.apache.http.entity.ContentType; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| @@ -27,7 +30,7 @@ import java.util.UUID; | |||||
| public class QrCodeRequestExecutor implements RequestExecutor<File, WxMpQrCodeTicket> { | public class QrCodeRequestExecutor implements RequestExecutor<File, WxMpQrCodeTicket> { | ||||
| @Override | @Override | ||||
| public File execute(String uri, WxMpQrCodeTicket ticket) throws WxErrorException, ClientProtocolException, IOException { | |||||
| public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, WxMpQrCodeTicket ticket) throws WxErrorException, ClientProtocolException, IOException { | |||||
| if (ticket != null) { | if (ticket != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -39,6 +42,11 @@ public class QrCodeRequestExecutor implements RequestExecutor<File, WxMpQrCodeTi | |||||
| } | } | ||||
| HttpGet httpGet = new HttpGet(uri); | HttpGet httpGet = new HttpGet(uri); | ||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet); | CloseableHttpResponse response = httpclient.execute(httpGet); | ||||
| Header[] contentTypeHeader = response.getHeaders("Content-Type"); | Header[] contentTypeHeader = response.getHeaders("Content-Type"); | ||||
| @@ -22,6 +22,8 @@ public class WxMpGsonBuilder { | |||||
| INSTANCE.registerTypeAdapter(WxMpMassSendResult.class, new WxMpMassSendResultAdapter()); | INSTANCE.registerTypeAdapter(WxMpMassSendResult.class, new WxMpMassSendResultAdapter()); | ||||
| INSTANCE.registerTypeAdapter(WxMpMassUploadResult.class, new WxMpMassUploadResultAdapter()); | INSTANCE.registerTypeAdapter(WxMpMassUploadResult.class, new WxMpMassUploadResultAdapter()); | ||||
| INSTANCE.registerTypeAdapter(WxMpQrCodeTicket.class, new WxQrCodeTicketAdapter()); | INSTANCE.registerTypeAdapter(WxMpQrCodeTicket.class, new WxQrCodeTicketAdapter()); | ||||
| INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter()); | |||||
| INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter()); | |||||
| } | } | ||||
| public static Gson create() { | public static Gson create() { | ||||
| @@ -0,0 +1,51 @@ | |||||
| /* | |||||
| * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. | |||||
| * | |||||
| * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended | |||||
| * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction | |||||
| * arose from modification of the original source, or other redistribution of this source | |||||
| * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. | |||||
| */ | |||||
| package me.chanjar.weixin.mp.util.json; | |||||
| import com.google.gson.*; | |||||
| import me.chanjar.weixin.common.util.json.GsonHelper; | |||||
| import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | |||||
| import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; | |||||
| import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | |||||
| import java.lang.reflect.Type; | |||||
| /** | |||||
| * | |||||
| * @author Daniel Qian | |||||
| * | |||||
| */ | |||||
| public class WxMpSemanticQueryResultAdapter implements JsonDeserializer<WxMpSemanticQueryResult> { | |||||
| public WxMpSemanticQueryResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||||
| WxMpSemanticQueryResult result = new WxMpSemanticQueryResult(); | |||||
| JsonObject resultJsonObject = json.getAsJsonObject(); | |||||
| if (GsonHelper.getString(resultJsonObject, "query") != null) { | |||||
| result.setQuery(GsonHelper.getString(resultJsonObject, "query")); | |||||
| } | |||||
| if (GsonHelper.getString(resultJsonObject, "type") != null) { | |||||
| result.setType(GsonHelper.getString(resultJsonObject, "type")); | |||||
| } | |||||
| if (resultJsonObject.get("semantic") != null) { | |||||
| result.setSemantic(resultJsonObject.get("semantic").toString()); | |||||
| } | |||||
| if (resultJsonObject.get("result") != null) { | |||||
| result.setResult(resultJsonObject.get("result").toString()); | |||||
| } | |||||
| if (GsonHelper.getString(resultJsonObject, "answer") != null) { | |||||
| result.setAnswer(GsonHelper.getString(resultJsonObject, "answer")); | |||||
| } | |||||
| if (GsonHelper.getString(resultJsonObject, "text") != null) { | |||||
| result.setText(GsonHelper.getString(resultJsonObject, "text")); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,50 @@ | |||||
| /* | |||||
| * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. | |||||
| * | |||||
| * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended | |||||
| * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction | |||||
| * arose from modification of the original source, or other redistribution of this source | |||||
| * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. | |||||
| */ | |||||
| package me.chanjar.weixin.mp.util.json; | |||||
| import com.google.gson.*; | |||||
| import me.chanjar.weixin.common.api.WxConsts; | |||||
| import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||||
| import me.chanjar.weixin.mp.bean.WxMpTemplateData; | |||||
| import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | |||||
| import java.lang.reflect.Type; | |||||
| /** | |||||
| * @author qianjia | |||||
| */ | |||||
| public class WxMpTemplateMessageGsonAdapter implements JsonSerializer<WxMpTemplateMessage> { | |||||
| public JsonElement serialize(WxMpTemplateMessage message, Type typeOfSrc, JsonSerializationContext context) { | |||||
| JsonObject messageJson = new JsonObject(); | |||||
| messageJson.addProperty("touser", message.getToUser()); | |||||
| messageJson.addProperty("template_id", message.getTemplateId()); | |||||
| if (message.getUrl() != null) { | |||||
| messageJson.addProperty("url", message.getUrl()); | |||||
| } | |||||
| if (message.getTopColor() != null) { | |||||
| messageJson.addProperty("topcolor", message.getTopColor()); | |||||
| } | |||||
| JsonObject datas = new JsonObject(); | |||||
| messageJson.add("data", datas); | |||||
| for (WxMpTemplateData data : message.getDatas()) { | |||||
| JsonObject dataJson = new JsonObject(); | |||||
| dataJson.addProperty("value", data.getValue()); | |||||
| if (data.getColor() != null) { | |||||
| dataJson.addProperty("color", data.getColor()); | |||||
| } | |||||
| datas.add(data.getName(), dataJson); | |||||
| } | |||||
| return messageJson; | |||||
| } | |||||
| } | |||||