#300 修复微信多媒体文件没有后缀名时下载失败的问题

This commit is contained in:
Binary Wang 2017-08-11 11:59:38 +08:00
parent 6ce585f246
commit 69ebad5e70
4 changed files with 107 additions and 64 deletions

View File

@ -0,0 +1,88 @@
package me.chanjar.weixin.common.util.http;
import jodd.http.HttpResponse;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import okhttp3.Response;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <pre>
* 三种http框架的response代理类方便提取公共方法
* Created by Binary Wang on 2017-8-3.
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class HttpResponseProxy {
private CloseableHttpResponse apacheHttpResponse;
private HttpResponse joddHttpResponse;
private Response okHttpResponse;
public HttpResponseProxy(CloseableHttpResponse apacheHttpResponse) {
this.apacheHttpResponse = apacheHttpResponse;
}
public HttpResponseProxy(HttpResponse joddHttpResponse) {
this.joddHttpResponse = joddHttpResponse;
}
public HttpResponseProxy(Response okHttpResponse) {
this.okHttpResponse = okHttpResponse;
}
public String getFileName() throws WxErrorException {
//由于对象只能由一个构造方法实现因此三个response对象必定且只有一个不为空
if (this.apacheHttpResponse != null) {
return this.getFileName(this.apacheHttpResponse);
}
if (this.joddHttpResponse != null) {
return this.getFileName(this.joddHttpResponse);
}
if (this.okHttpResponse != null) {
return this.getFileName(this.okHttpResponse);
}
//cannot happen
return null;
}
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
}
private String getFileName(HttpResponse response) throws WxErrorException {
String content = response.header("Content-disposition");
return this.extractFileNameFromContentString(content);
}
private String getFileName(Response response) throws WxErrorException {
String content = response.header("Content-disposition");
return this.extractFileNameFromContentString(content);
}
private String extractFileNameFromContentString(String content) throws WxErrorException {
if (content == null || content.length() == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
Matcher m = p.matcher(content);
if (m.matches()) {
return m.group(1);
}
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
}

View File

@ -3,8 +3,10 @@ package me.chanjar.weixin.common.util.http.apache;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpHost;
@ -17,15 +19,12 @@ import org.apache.http.impl.client.CloseableHttpClient;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by ecoolper on 2017/5/5.
*/
public class ApacheMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> {
public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
super(requestHttp, tmpDirFile);
}
@ -57,31 +56,17 @@ public class ApacheMediaDownloadRequestExecutor extends MediaDownloadRequestExec
}
}
String fileName = getFileName(response);
String fileName = new HttpResponseProxy(response).getFileName();
if (StringUtils.isBlank(fileName)) {
return null;
}
String[] nameAndExt = fileName.split("\\.");
return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], super.tmpDirFile);
return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName),
super.tmpDirFile);
} finally {
httpGet.releaseConnection();
}
}
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
Matcher m = p.matcher(contentDispositionHeader[0].getValue());
if (m.matches()) {
return m.group(1);
}
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
}

View File

@ -5,27 +5,25 @@ import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by ecoolper on 2017/5/5.
*/
public class JoddHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> {
public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
super(requestHttp, tmpDirFile);
}
@ -54,28 +52,15 @@ public class JoddHttpMediaDownloadRequestExecutor extends MediaDownloadRequestEx
throw new WxErrorException(WxError.fromJson(response.bodyText()));
}
String fileName = getFileName(response);
String fileName = new HttpResponseProxy(response).getFileName();
if (StringUtils.isBlank(fileName)) {
return null;
}
InputStream inputStream = new ByteArrayInputStream(response.bodyBytes());
String[] nameAndExt = fileName.split("\\.");
return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], super.tmpDirFile);
return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName),
super.tmpDirFile);
}
private String getFileName(HttpResponse response) throws WxErrorException {
String content = response.header("Content-disposition");
if (content == null || content.length() == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
Matcher m = p.matcher(content);
if (m.matches()) {
return m.group(1);
}
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
}

View File

@ -2,22 +2,21 @@ package me.chanjar.weixin.common.util.http.okhttp;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import okhttp3.*;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okio.BufferedSink;
import okio.Okio;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by ecoolper on 2017/5/5.
@ -25,7 +24,6 @@ import java.util.regex.Pattern;
public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
super(requestHttp, tmpDirFile);
}
@ -53,12 +51,13 @@ public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExec
throw new WxErrorException(WxError.fromJson(response.body().string()));
}
String fileName = getFileName(response);
String fileName = new HttpResponseProxy(response).getFileName();
if (StringUtils.isBlank(fileName)) {
return null;
}
String[] nameAndExt = fileName.split("\\.");
File file = File.createTempFile(nameAndExt[0], nameAndExt[1], super.tmpDirFile);
File file = File.createTempFile(FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName),
super.tmpDirFile);
try (BufferedSink sink = Okio.buffer(Okio.sink(file))) {
sink.writeAll(response.body().source());
}
@ -66,18 +65,4 @@ public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExec
return file;
}
private String getFileName(Response response) throws WxErrorException {
String content = response.header("Content-disposition");
if (content == null || content.length() == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
Pattern p = Pattern.compile(".*filename=\"(.*)\"");
Matcher m = p.matcher(content);
if (m.matches()) {
return m.group(1);
}
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}
}