Skip to content

Commit a5779a7

Browse files
authored
Merge pull request binarywang#3 from wechat-group/develop
合并代码
2 parents b98661b + cb9380c commit a5779a7

File tree

58 files changed

+3273
-941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3273
-941
lines changed

README.md

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,57 @@
11
# Weixin Java Tools 微信公众号/企业号开发Java SDK
2-
## [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badge/) ![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg) [![Build Status](https://travis-ci.org/binarywang/weixin-java-tools.svg?branch=develop)](https://travis-ci.org/binarywang/weixin-java-tools)
2+
## [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badge/) ![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg) [![Build Status](https://travis-ci.org/wechat-group/weixin-java-tools.svg?branch=develop)](https://travis-ci.org/wechat-group/weixin-java-tools)
33

44

5-
### 声明:本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。
5+
### 注意:
6+
1. ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。***
7+
1. ***自2.0.0版本以来,主要是公众号的接口调整比较大,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。***
8+
1. 最新更新:2016-08-31 发布2.1.0正式版!
69

7-
### 最新更新:2.1.0版发布!!! on 2016-08-31
10+
===========
811

9-
#### ***自2.0.0版本以来,接口调整比较大,主要是公众号的调整,企业号无过多调整,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。所以如果习惯于1.X.X版本的同学不想做过多更改的话,请慎重考虑升级到2.X.X版本.***
10-
---
12+
## 开发交流方式:
13+
1. ***入群须知:为保证入群成员质量,请申请入群前,先Star本项目,然后在申请入群时,输入您的Github帐号ID,以便管理员核对,ID即你的github主页地址https://github.com/XXXX 中最后的部分XXXX的内容,或者在github网页右上角点击头像后查看Signed in as后方内容。***
14+
1. QQ群:343954419 [![Join QQ Group](http://pub.idqqimg.com/wpa/images/group.png)](http://shang.qq.com/wpa/qunwpa?idkey=078f7a153d243853e24cf2b542e7a6ccbf2a592bc138080f84d11297f736ec46)
15+
1. 微信群: 因二维码有时间限制,如有想加入微信群的,请入QQ群后咨询获取最新入群二维码;
16+
1. 有功能需求或由于微信官方接口调整导致的代码问题,可以直接提出issue,便于讨论追踪问题;
17+
1. 详细开发文档请看 [Wiki](https://github.com/wechat-group/weixin-java-tools/wiki)
1118

12-
### 详细开发文档请看 [wiki](https://github.com/chanjarster/weixin-java-tools/wiki)
13-
===========
14-
## 开发交流工具:
15-
* 微信群: 因二维码有时间限制,如有想加入微信群的,请入QQ群后咨询获取最新入群二维码。
16-
* QQ群:343954419 [![Join QQ Group](http://pub.idqqimg.com/wpa/images/group.png)](http://shang.qq.com/wpa/qunwpa?idkey=078f7a153d243853e24cf2b542e7a6ccbf2a592bc138080f84d11297f736ec46)
17-
* ***注意:为保证入群成员质量,请申请入群前,先Star本项目,然后在申请入群时,输入您的Github帐号ID,以便管理员核对,ID即你的github主页地址https://github.com/XXXX 中最后的部分XXXX的内容,或者在github网页右上角点击头像查看,如下图Signed in as下方黄色标识内容即是:***
18-
* ![github_id](https://raw.githubusercontent.com/wechat-group/weixin-java-tools/develop/res/github_id.png)
19-
2019
===========
2120

2221
## 版本说明
23-
* 本项目定为每月发布一次正式版,版本号格式为X.X.0(如2.0.0,2.1.0等),月初或月底发布新版本,遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request。
24-
* BUG修复和新特性一般会先发布成小版本作为临时版本(如2.0.1,2.0.2等,即尾号不为0,以区别于正式版)。
25-
* 目前最新版本号为 ![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg) ,也可以通过访问如下地址查看所有最新的版本:
26-
- [【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22)
27-
- [【企业号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22)
28-
22+
* 本项目定为每月发布一次正式版,版本号格式为X.X.0(如2.0.0,2.1.0等),月初或月底发布新版本,遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request;
23+
* BUG修复和新特性一般会先发布成小版本作为临时版本(如2.0.1,2.0.2等,即尾号不为0,以区别于正式版);
24+
* 目前最新版本号为 ![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg) ,也可以通过访问链接[【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22)[【企业号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22)
25+
分别查看所有最新的版本。
2926

3027
## Maven & Gradle
3128

3229
* 公众号(订阅号、服务号):
30+
31+
maven:
3332
```xml
3433
<dependency>
3534
<groupId>com.github.binarywang</groupId>
3635
<artifactId>weixin-java-mp</artifactId>
3736
<version>2.1.0</version>
3837
</dependency>
3938
```
40-
39+
gradle:
4140
```groovy
4241
compile 'com.github.binarywang:weixin-java-mp:2.1.0'
4342
```
4443

4544
* 企业号:
45+
46+
maven:
4647
```xml
4748
<dependency>
4849
<groupId>com.github.binarywang</groupId>
4950
<artifactId>weixin-java-cp</artifactId>
5051
<version>2.1.0</version>
5152
</dependency>
5253
```
53-
54+
gradle:
5455
```groovy
5556
compile 'com.github.binarywang:weixin-java-cp:2.1.0'
5657
```
@@ -63,16 +64,14 @@ compile 'com.github.binarywang:weixin-java-cp:2.1.0'
6364
* https://git.coding.net/binarywang/weixin-java-tools.git
6465

6566

66-
## 目前可参考的Demo项目:
67-
* https://github.com/wechat-group/weixin-java-tools-springmvc
68-
* https://github.com/wechat-group/weixin-mp-demo
69-
* ===========以下为备份仓库,会保持跟主仓库同步
70-
* http://git.oschina.net/binary/weixin-mp-demo
71-
* https://bitbucket.org/binarywang/weixin-mp-demo
67+
## 目前可参考的Demo项目有两个:
68+
1. https://github.com/wechat-group/weixin-mp-demo
69+
1. https://github.com/wechat-group/weixin-java-tools-springmvc
7270

7371
## 关于代码贡献
72+
* 非常欢迎和感谢对本项目发起Pull Request的同学,本项目代码风格为使用2个空格代表一个Tab,因此在提交代码时请注意一下,否则很容易在IDE格式化代码后与原代码产生大量diff,这样会给其他人阅读代码带来极大的困扰。
73+
* 为了便于设置,本项目引入editorconfig插件,请使用eclipse的同学在贡献代码前安装相关插件,IntelliJ IDEA则自带支持,无需额外安装插件。
74+
* 本项目可以采用两种方式接受代码贡献:
7475

75-
* 非常欢迎和感谢对本项目发起Pull Request的同学,本项目可以采用两种方式接受代码贡献:
76-
* 第一种就是基于[Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)开发流程,因此在发起Pull Request的时候请选择develop分支。
77-
* 另外一种贡献代码的方式就是加入SDK Developers开发组,如果对自己的代码足够自信,可以随时提交代码,注意要随时进行单元测试,保证提交代码没有明显问题,具体加入方式,请咨询管理员。
78-
* 本项目代码风格为使用2个空格代表一个Tab,因此在提交代码时请注意一下,否则很容易在IDE格式化代码后与原代码产生大量diff,这样会给其他人阅读代码带来极大的困扰。
76+
1. 第一种就是基于[Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)开发流程,因此在发起Pull Request的时候请选择develop分支。
77+
1. 另外一种贡献代码的方式就是加入SDK Developers开发组,如果对自己的代码足够自信,可以随时提交代码,注意要随时进行单元测试,保证提交代码没有明显问题,具体加入方式,请咨询管理员。

build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ subprojects {
1313

1414
repositories {
1515
mavenLocal()
16-
17-
maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
16+
maven { url "http://central.maven.org/maven2" }
17+
//maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
1818
}
1919

2020

@@ -24,6 +24,8 @@ subprojects {
2424
compile group: 'org.apache.httpcomponents', name: 'httpmime', version:'4.5'
2525
compile group: 'org.jodd', name: 'jodd-http', version:'3.6.7'
2626
compile group: 'com.google.code.gson', name: 'gson', version:'2.7'
27+
compile group: 'com.google.guava', name: 'guava', version:'19.0'
28+
compile group: 'org.jooq', name: 'joor', version:'0.9.6'
2729
compile group: 'commons-codec', name: 'commons-codec', version:'1.10'
2830
compile group: 'commons-io', name: 'commons-io', version:'2.5'
2931
compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.4'

pom.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
<jodd-http.version>3.6.7</jodd-http.version>
5252
<jedis.version>2.9.0</jedis.version>
5353
<gson.version>2.7</gson.version>
54+
<guava.version>19.0</guava.version>
55+
<joor.version>0.9.6</joor.version>
5456
<commons-lang3.version>3.4</commons-lang3.version>
5557
<commons-io.version>2.5</commons-io.version>
5658
<commons-codec.version>1.10</commons-codec.version>
@@ -111,6 +113,14 @@
111113
<version>${jedis.version}</version>
112114
<scope>provided</scope>
113115
</dependency>
116+
<dependency>
117+
<groupId>com.google.guava</groupId>
118+
<artifactId>guava</artifactId>
119+
</dependency>
120+
<dependency>
121+
<groupId>org.jooq</groupId>
122+
<artifactId>joor</artifactId>
123+
</dependency>
114124
</dependencies>
115125

116126
<dependencyManagement>
@@ -151,6 +161,16 @@
151161
<version>${jetty.version}</version>
152162
<scope>test</scope>
153163
</dependency>
164+
<dependency>
165+
<groupId>com.google.guava</groupId>
166+
<artifactId>guava</artifactId>
167+
<version>${guava.version}</version>
168+
</dependency>
169+
<dependency>
170+
<groupId>org.jooq</groupId>
171+
<artifactId>joor</artifactId>
172+
<version>${joor.version}</version>
173+
</dependency>
154174
</dependencies>
155175
</dependencyManagement>
156176

res/github_id.png

-3.91 KB
Binary file not shown.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package me.chanjar.weixin.common.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* 标识某个字段是否是必填的
10+
*
11+
* Created by Binary Wang on 2016/9/25.
12+
* @author binarywang (https://github.com/binarywang)
13+
*
14+
*/
15+
@Retention(RetentionPolicy.RUNTIME)
16+
@Target(ElementType.FIELD)
17+
public @interface Required {
18+
19+
}

weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class WxConsts {
3030
public static final String CUSTOM_MSG_MUSIC = "music";
3131
public static final String CUSTOM_MSG_NEWS = "news";
3232
public static final String CUSTOM_MSG_FILE = "file";
33+
public static final String CUSTOM_MSG_WXCARD = "wxcard";
3334
public static final String CUSTOM_MSG_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
3435
public static final String CUSTOM_MSG_SAFE_NO = "0";
3536
public static final String CUSTOM_MSG_SAFE_YES = "1";

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,8 @@
1919

2020
import java.io.StringReader;
2121
import java.nio.charset.Charset;
22-
import java.util.ArrayList;
2322
import java.util.Arrays;
24-
import java.util.Collections;
25-
import java.util.List;
26-
import java.util.Map;
2723
import java.util.Random;
28-
import java.util.SortedMap;
29-
import java.util.TreeMap;
3024

3125
import javax.crypto.Cipher;
3226
import javax.crypto.spec.IvParameterSpec;
@@ -36,7 +30,6 @@
3630
import javax.xml.parsers.ParserConfigurationException;
3731

3832
import org.apache.commons.codec.binary.Base64;
39-
import org.apache.commons.codec.digest.DigestUtils;
4033
import org.w3c.dom.Document;
4134
import org.w3c.dom.Element;
4235
import org.xml.sax.InputSource;
@@ -79,33 +72,6 @@ public WxCryptUtil(String token, String encodingAesKey,
7972
this.aesKey = Base64.decodeBase64(encodingAesKey + "=");
8073
}
8174

82-
/**
83-
* 微信公众号支付签名算法(详见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3)
84-
* @param packageParams 原始参数
85-
* @param signKey 加密Key(即 商户Key)
86-
* @return 签名字符串
87-
*/
88-
public static String createSign(Map<String, String> packageParams,
89-
String signKey) {
90-
SortedMap<String, String> sortedMap = new TreeMap<>();
91-
sortedMap.putAll(packageParams);
92-
93-
List<String> keys = new ArrayList<>(packageParams.keySet());
94-
Collections.sort(keys);
95-
96-
StringBuffer toSign = new StringBuffer();
97-
for (String key : keys) {
98-
String value = packageParams.get(key);
99-
if (null != value && !"".equals(value) && !"sign".equals(key)
100-
&& !"key".equals(key)) {
101-
toSign.append(key + "=" + value + "&");
102-
}
103-
}
104-
toSign.append("key=" + signKey);
105-
String sign = DigestUtils.md5Hex(toSign.toString()).toUpperCase();
106-
return sign;
107-
}
108-
10975
static String extractEncryptPart(String xml) {
11076
try {
11177
DocumentBuilder db = builderLocal.get();
Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package me.chanjar.weixin.common.util.http;
22

3-
import java.io.File;
4-
import java.io.IOException;
5-
import java.io.InputStream;
6-
import java.util.regex.Matcher;
7-
import java.util.regex.Pattern;
8-
3+
import me.chanjar.weixin.common.bean.result.WxError;
4+
import me.chanjar.weixin.common.exception.WxErrorException;
5+
import me.chanjar.weixin.common.util.StringUtils;
6+
import me.chanjar.weixin.common.util.fs.FileUtils;
97
import org.apache.http.Header;
108
import org.apache.http.HttpHost;
119
import org.apache.http.client.config.RequestConfig;
@@ -14,30 +12,28 @@
1412
import org.apache.http.entity.ContentType;
1513
import org.apache.http.impl.client.CloseableHttpClient;
1614

17-
import me.chanjar.weixin.common.bean.result.WxError;
18-
import me.chanjar.weixin.common.exception.WxErrorException;
19-
import me.chanjar.weixin.common.util.StringUtils;
20-
import me.chanjar.weixin.common.util.fs.FileUtils;
15+
import java.io.File;
16+
import java.io.IOException;
17+
import java.io.InputStream;
18+
import java.util.regex.Matcher;
19+
import java.util.regex.Pattern;
2120

2221
/**
2322
* 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File
24-
*
23+
* 视频文件不支持下载
2524
* @author Daniel Qian
2625
*/
2726
public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> {
2827

2928
private File tmpDirFile;
3029

3130
public MediaDownloadRequestExecutor() {
32-
super();
3331
}
3432

3533
public MediaDownloadRequestExecutor(File tmpDirFile) {
36-
super();
3734
this.tmpDirFile = tmpDirFile;
3835
}
3936

40-
4137
@Override
4238
public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException {
4339
if (queryParam != null) {
@@ -59,34 +55,39 @@ public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String u
5955

6056
Header[] contentTypeHeader = response.getHeaders("Content-Type");
6157
if (contentTypeHeader != null && contentTypeHeader.length > 0) {
62-
// 下载媒体文件出错
63-
if (ContentType.TEXT_PLAIN.getMimeType().equals(contentTypeHeader[0].getValue())) {
58+
if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
59+
// application/json; encoding=utf-8 下载媒体文件出错
6460
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
6561
throw new WxErrorException(WxError.fromJson(responseContent));
6662
}
6763
}
68-
// 视频文件不支持下载
64+
6965
String fileName = getFileName(response);
7066
if (StringUtils.isBlank(fileName)) {
7167
return null;
7268
}
73-
String[] name_ext = fileName.split("\\.");
74-
File localFile = FileUtils.createTmpFile(inputStream, name_ext[0], name_ext[1], this.tmpDirFile);
75-
return localFile;
69+
70+
String[] nameAndExt = fileName.split("\\.");
71+
return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile);
7672

7773
} finally {
7874
httpGet.releaseConnection();
7975
}
8076

8177
}
8278

83-
protected String getFileName(CloseableHttpResponse response) {
79+
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
8480
Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
81+
if(contentDispositionHeader == null || contentDispositionHeader.length == 0){
82+
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
83+
}
84+
8585
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
8686
Matcher m = p.matcher(contentDispositionHeader[0].getValue());
87-
m.matches();
88-
String fileName = m.group(1);
89-
return fileName;
87+
if(m.matches()){
88+
return m.group(1);
89+
}
90+
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
9091
}
9192

9293
}

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import me.chanjar.weixin.common.exception.WxErrorException;
44
import org.apache.http.HttpHost;
5-
import org.apache.http.client.ClientProtocolException;
65
import org.apache.http.impl.client.CloseableHttpClient;
76

87
import java.io.IOException;
@@ -21,7 +20,6 @@ public interface RequestExecutor<T, E> {
2120
* @param uri uri
2221
* @param data 数据
2322
* @throws WxErrorException
24-
* @throws ClientProtocolException
2523
* @throws IOException
2624
*/
2725
T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException;

0 commit comments

Comments
 (0)