11package me .chanjar .weixin .common .util .http ;
22
3+ import jodd .http .HttpConnectionProvider ;
4+ import jodd .http .HttpRequest ;
5+ import jodd .http .HttpResponse ;
6+ import jodd .http .ProxyInfo ;
37import me .chanjar .weixin .common .bean .result .WxError ;
48import me .chanjar .weixin .common .exception .WxErrorException ;
59import me .chanjar .weixin .common .util .fs .FileUtils ;
10+ import me .chanjar .weixin .common .util .http .apache .InputStreamResponseHandler ;
11+ import me .chanjar .weixin .common .util .http .apache .Utf8ResponseHandler ;
612import org .apache .commons .lang3 .StringUtils ;
713import org .apache .http .Header ;
814import org .apache .http .HttpHost ;
1218import org .apache .http .entity .ContentType ;
1319import org .apache .http .impl .client .CloseableHttpClient ;
1420
21+ import java .io .ByteArrayInputStream ;
1522import java .io .File ;
1623import java .io .IOException ;
1724import java .io .InputStream ;
2128/**
2229 * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File
2330 * 视频文件不支持下载
31+ *
2432 * @author Daniel Qian
2533 */
2634public class MediaDownloadRequestExecutor implements RequestExecutor <File , String > {
2735
2836 private File tmpDirFile ;
2937
30- public MediaDownloadRequestExecutor () {
31- }
32-
3338 public MediaDownloadRequestExecutor (File tmpDirFile ) {
3439 this .tmpDirFile = tmpDirFile ;
3540 }
3641
3742 @ Override
38- public File execute (CloseableHttpClient httpclient , HttpHost httpProxy , String uri , String queryParam ) throws WxErrorException , IOException {
43+ public File execute (RequestHttp requestHttp , String uri , String queryParam ) throws WxErrorException , IOException {
44+ if (requestHttp .getRequestHttpClient () instanceof CloseableHttpClient ) {
45+ CloseableHttpClient httpClient = (CloseableHttpClient ) requestHttp .getRequestHttpClient ();
46+ HttpHost httpProxy = (HttpHost ) requestHttp .getRequestHttpProxy ();
47+ return executeApache (httpClient , httpProxy , uri , queryParam );
48+ }
49+ if (requestHttp .getRequestHttpClient () instanceof HttpConnectionProvider ) {
50+ HttpConnectionProvider provider = (HttpConnectionProvider ) requestHttp .getRequestHttpClient ();
51+ ProxyInfo proxyInfo = (ProxyInfo ) requestHttp .getRequestHttpProxy ();
52+ return executeJodd (provider , proxyInfo , uri , queryParam );
53+ } else {
54+ //这里需要抛出异常,需要优化
55+ return null ;
56+ }
57+ }
58+
59+ private String getFileNameJodd (HttpResponse response ) throws WxErrorException {
60+ String content = response .header ("Content-disposition" );
61+ if (content == null || content .length () == 0 ) {
62+ throw new WxErrorException (WxError .newBuilder ().setErrorMsg ("无法获取到文件名" ).build ());
63+ }
64+
65+ Pattern p = Pattern .compile (".*filename=\" (.*)\" " );
66+ Matcher m = p .matcher (content );
67+ if (m .matches ()) {
68+ return m .group (1 );
69+ }
70+ throw new WxErrorException (WxError .newBuilder ().setErrorMsg ("无法获取到文件名" ).build ());
71+ }
72+
73+ private String getFileNameApache (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+
87+
88+ /**
89+ * apache-http实现方式
90+ * @param httpclient
91+ * @param httpProxy
92+ * @param uri
93+ * @param queryParam
94+ * @return
95+ * @throws WxErrorException
96+ * @throws IOException
97+ */
98+ private File executeApache (CloseableHttpClient httpclient , HttpHost httpProxy , String uri , String queryParam ) throws WxErrorException , IOException {
3999 if (queryParam != null ) {
40100 if (uri .indexOf ('?' ) == -1 ) {
41101 uri += '?' ;
@@ -50,8 +110,8 @@ public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String u
50110 }
51111
52112 try (CloseableHttpResponse response = httpclient .execute (httpGet );
53- InputStream inputStream = InputStreamResponseHandler .INSTANCE
54- .handleResponse (response )) {
113+ InputStream inputStream = InputStreamResponseHandler .INSTANCE
114+ .handleResponse (response )) {
55115
56116 Header [] contentTypeHeader = response .getHeaders ("Content-Type" );
57117 if (contentTypeHeader != null && contentTypeHeader .length > 0 ) {
@@ -62,7 +122,7 @@ public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String u
62122 }
63123 }
64124
65- String fileName = getFileName (response );
125+ String fileName = getFileNameApache (response );
66126 if (StringUtils .isBlank (fileName )) {
67127 return null ;
68128 }
@@ -76,18 +136,46 @@ public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String u
76136
77137 }
78138
79- private String getFileName (CloseableHttpResponse response ) throws WxErrorException {
80- Header [] contentDispositionHeader = response .getHeaders ("Content-disposition" );
81- if (contentDispositionHeader == null || contentDispositionHeader .length == 0 ){
82- throw new WxErrorException (WxError .newBuilder ().setErrorMsg ("无法获取到文件名" ).build ());
139+
140+ /**
141+ * jodd-http实现方式
142+ * @param provider
143+ * @param proxyInfo
144+ * @param uri
145+ * @param queryParam
146+ * @return
147+ * @throws WxErrorException
148+ * @throws IOException
149+ */
150+ private File executeJodd (HttpConnectionProvider provider , ProxyInfo proxyInfo , String uri , String queryParam ) throws WxErrorException , IOException {
151+ if (queryParam != null ) {
152+ if (uri .indexOf ('?' ) == -1 ) {
153+ uri += '?' ;
154+ }
155+ uri += uri .endsWith ("?" ) ? queryParam : '&' + queryParam ;
83156 }
84157
85- Pattern p = Pattern .compile (".*filename=\" (.*)\" " );
86- Matcher m = p .matcher (contentDispositionHeader [0 ].getValue ());
87- if (m .matches ()){
88- return m .group (1 );
158+ HttpRequest request = HttpRequest .get (uri );
159+ if (proxyInfo != null ) {
160+ provider .useProxy (proxyInfo );
89161 }
90- throw new WxErrorException (WxError .newBuilder ().setErrorMsg ("无法获取到文件名" ).build ());
162+ request .withConnectionProvider (provider );
163+ HttpResponse response = request .send ();
164+ String contentType = response .header ("Content-Type" );
165+ if (contentType != null && contentType .startsWith ("application/json" )) {
166+ // application/json; encoding=utf-8 下载媒体文件出错
167+ throw new WxErrorException (WxError .fromJson (response .bodyText ()));
168+ }
169+
170+ String fileName = getFileNameJodd (response );
171+ if (StringUtils .isBlank (fileName )) {
172+ return null ;
173+ }
174+
175+ InputStream inputStream = new ByteArrayInputStream (response .bodyBytes ());
176+ String [] nameAndExt = fileName .split ("\\ ." );
177+ return FileUtils .createTmpFile (inputStream , nameAndExt [0 ], nameAndExt [1 ], this .tmpDirFile );
91178 }
92179
180+
93181}
0 commit comments