Skip to content

Commit 69ebad5

Browse files
committed
#300 修复微信多媒体文件没有后缀名时下载失败的问题
1 parent 6ce585f commit 69ebad5

File tree

4 files changed

+107
-64
lines changed

4 files changed

+107
-64
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package me.chanjar.weixin.common.util.http;
2+
3+
import jodd.http.HttpResponse;
4+
import me.chanjar.weixin.common.bean.result.WxError;
5+
import me.chanjar.weixin.common.exception.WxErrorException;
6+
import okhttp3.Response;
7+
import org.apache.http.Header;
8+
import org.apache.http.client.methods.CloseableHttpResponse;
9+
10+
import java.util.regex.Matcher;
11+
import java.util.regex.Pattern;
12+
13+
/**
14+
* <pre>
15+
* 三种http框架的response代理类,方便提取公共方法
16+
* Created by Binary Wang on 2017-8-3.
17+
* </pre>
18+
*
19+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
20+
*/
21+
public class HttpResponseProxy {
22+
private CloseableHttpResponse apacheHttpResponse;
23+
private HttpResponse joddHttpResponse;
24+
private Response okHttpResponse;
25+
26+
public HttpResponseProxy(CloseableHttpResponse apacheHttpResponse) {
27+
this.apacheHttpResponse = apacheHttpResponse;
28+
}
29+
30+
public HttpResponseProxy(HttpResponse joddHttpResponse) {
31+
this.joddHttpResponse = joddHttpResponse;
32+
}
33+
34+
public HttpResponseProxy(Response okHttpResponse) {
35+
this.okHttpResponse = okHttpResponse;
36+
}
37+
38+
public String getFileName() throws WxErrorException {
39+
//由于对象只能由一个构造方法实现,因此三个response对象必定且只有一个不为空
40+
if (this.apacheHttpResponse != null) {
41+
return this.getFileName(this.apacheHttpResponse);
42+
}
43+
44+
if (this.joddHttpResponse != null) {
45+
return this.getFileName(this.joddHttpResponse);
46+
}
47+
48+
if (this.okHttpResponse != null) {
49+
return this.getFileName(this.okHttpResponse);
50+
}
51+
52+
//cannot happen
53+
return null;
54+
}
55+
56+
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
57+
Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
58+
if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
59+
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
60+
}
61+
62+
return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
63+
}
64+
65+
private String getFileName(HttpResponse response) throws WxErrorException {
66+
String content = response.header("Content-disposition");
67+
return this.extractFileNameFromContentString(content);
68+
}
69+
70+
private String getFileName(Response response) throws WxErrorException {
71+
String content = response.header("Content-disposition");
72+
return this.extractFileNameFromContentString(content);
73+
}
74+
75+
private String extractFileNameFromContentString(String content) throws WxErrorException {
76+
if (content == null || content.length() == 0) {
77+
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
78+
}
79+
80+
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
81+
Matcher m = p.matcher(content);
82+
if (m.matches()) {
83+
return m.group(1);
84+
}
85+
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
86+
}
87+
88+
}

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

+5-20
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import me.chanjar.weixin.common.bean.result.WxError;
44
import me.chanjar.weixin.common.exception.WxErrorException;
55
import me.chanjar.weixin.common.util.fs.FileUtils;
6+
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
67
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
78
import me.chanjar.weixin.common.util.http.RequestHttp;
9+
import org.apache.commons.io.FilenameUtils;
810
import org.apache.commons.lang3.StringUtils;
911
import org.apache.http.Header;
1012
import org.apache.http.HttpHost;
@@ -17,15 +19,12 @@
1719
import java.io.File;
1820
import java.io.IOException;
1921
import java.io.InputStream;
20-
import java.util.regex.Matcher;
21-
import java.util.regex.Pattern;
2222

2323
/**
2424
* Created by ecoolper on 2017/5/5.
2525
*/
2626
public class ApacheMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> {
2727

28-
2928
public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
3029
super(requestHttp, tmpDirFile);
3130
}
@@ -57,31 +56,17 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx
5756
}
5857
}
5958

60-
String fileName = getFileName(response);
59+
String fileName = new HttpResponseProxy(response).getFileName();
6160
if (StringUtils.isBlank(fileName)) {
6261
return null;
6362
}
6463

65-
String[] nameAndExt = fileName.split("\\.");
66-
return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], super.tmpDirFile);
64+
return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName),
65+
super.tmpDirFile);
6766

6867
} finally {
6968
httpGet.releaseConnection();
7069
}
7170
}
7271

73-
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
74-
Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
75-
if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
76-
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
77-
}
78-
79-
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
80-
Matcher m = p.matcher(contentDispositionHeader[0].getValue());
81-
if (m.matches()) {
82-
return m.group(1);
83-
}
84-
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
85-
}
86-
8772
}

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

+5-20
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,25 @@
55
import jodd.http.HttpResponse;
66
import jodd.http.ProxyInfo;
77
import jodd.util.StringPool;
8-
98
import me.chanjar.weixin.common.bean.result.WxError;
109
import me.chanjar.weixin.common.exception.WxErrorException;
1110
import me.chanjar.weixin.common.util.fs.FileUtils;
11+
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
1212
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
1313
import me.chanjar.weixin.common.util.http.RequestHttp;
14+
import org.apache.commons.io.FilenameUtils;
1415
import org.apache.commons.lang3.StringUtils;
1516

1617
import java.io.ByteArrayInputStream;
1718
import java.io.File;
1819
import java.io.IOException;
1920
import java.io.InputStream;
20-
import java.util.regex.Matcher;
21-
import java.util.regex.Pattern;
2221

2322
/**
2423
* Created by ecoolper on 2017/5/5.
2524
*/
2625
public class JoddHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> {
2726

28-
2927
public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
3028
super(requestHttp, tmpDirFile);
3129
}
@@ -54,28 +52,15 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx
5452
throw new WxErrorException(WxError.fromJson(response.bodyText()));
5553
}
5654

57-
String fileName = getFileName(response);
55+
String fileName = new HttpResponseProxy(response).getFileName();
5856
if (StringUtils.isBlank(fileName)) {
5957
return null;
6058
}
6159

6260
InputStream inputStream = new ByteArrayInputStream(response.bodyBytes());
63-
String[] nameAndExt = fileName.split("\\.");
64-
return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], super.tmpDirFile);
61+
return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName),
62+
super.tmpDirFile);
6563
}
6664

67-
private String getFileName(HttpResponse response) throws WxErrorException {
68-
String content = response.header("Content-disposition");
69-
if (content == null || content.length() == 0) {
70-
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
71-
}
72-
73-
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
74-
Matcher m = p.matcher(content);
75-
if (m.matches()) {
76-
return m.group(1);
77-
}
78-
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
79-
}
8065

8166
}

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

+9-24
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,28 @@
22

33
import me.chanjar.weixin.common.bean.result.WxError;
44
import me.chanjar.weixin.common.exception.WxErrorException;
5-
import me.chanjar.weixin.common.util.fs.FileUtils;
5+
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
66
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
77
import me.chanjar.weixin.common.util.http.RequestHttp;
8-
import okhttp3.*;
8+
import okhttp3.OkHttpClient;
9+
import okhttp3.Request;
10+
import okhttp3.Response;
911
import okio.BufferedSink;
1012
import okio.Okio;
13+
import org.apache.commons.io.FilenameUtils;
1114
import org.apache.commons.lang3.StringUtils;
1215
import org.slf4j.Logger;
1316
import org.slf4j.LoggerFactory;
1417

15-
import java.io.ByteArrayInputStream;
1618
import java.io.File;
1719
import java.io.IOException;
18-
import java.io.InputStream;
19-
import java.util.regex.Matcher;
20-
import java.util.regex.Pattern;
2120

2221
/**
2322
* Created by ecoolper on 2017/5/5.
2423
*/
2524
public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> {
2625
private final Logger logger = LoggerFactory.getLogger(this.getClass());
2726

28-
2927
public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
3028
super(requestHttp, tmpDirFile);
3129
}
@@ -53,31 +51,18 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx
5351
throw new WxErrorException(WxError.fromJson(response.body().string()));
5452
}
5553

56-
String fileName = getFileName(response);
54+
String fileName = new HttpResponseProxy(response).getFileName();
5755
if (StringUtils.isBlank(fileName)) {
5856
return null;
5957
}
60-
String[] nameAndExt = fileName.split("\\.");
61-
File file = File.createTempFile(nameAndExt[0], nameAndExt[1], super.tmpDirFile);
58+
59+
File file = File.createTempFile(FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName),
60+
super.tmpDirFile);
6261
try (BufferedSink sink = Okio.buffer(Okio.sink(file))) {
6362
sink.writeAll(response.body().source());
6463
}
6564
file.deleteOnExit();
6665
return file;
6766
}
6867

69-
private String getFileName(Response response) throws WxErrorException {
70-
String content = response.header("Content-disposition");
71-
if (content == null || content.length() == 0) {
72-
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
73-
}
74-
75-
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
76-
Matcher m = p.matcher(content);
77-
if (m.matches()) {
78-
return m.group(1);
79-
}
80-
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
81-
}
82-
8368
}

0 commit comments

Comments
 (0)