利用httpClient向微信上传临时图片素材,HttpClient有ByteArrayBody、FileBody、InputStreamBody和StringBody四种Body。其中已经用到的有除ByteArrayBody之前的三种。FileBody和StringBody请参考httpClient的官方例子,很好理解。http://hc.apache.org/httpcomponents-client-4.5.x/httpmime/examples/org/apache/http/examples/entity/mime/ClientMultipartFormPost.java 。
但是用InputStreamBody的时候,官方没有具体给出例子。所以我就照葫芦画瓢写了,但是向微信服务器上传的时候老是超时也不报错,设置client的超时时间也没什么用。纠结了好长时间再加上谷歌,终于找到了两种解决办法。
1、第一种就是把上传的inputStream先转成文件,在用FileBody上传。
File fout = new File("D:\\aa.jpg");
OutputStream os = new FileOutputStream(fout);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
in.close();
FileBody bin = new FileBody(fout);
2、第二种就是自己实现InputStreamBody,因为我发现FileBody和StringBody上传过程中的ContentLength都是文件的长度,但是InputStreamBody的源码里面获得ContentLength的长度永远是-1,可能就是这个原因让微信识别不了。然后我就自己实现了InputStreamBody。最后终于上传成功了,但是这两种方法本质上没什么区别。
package com.liuxl.httpclient;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MIME;
import org.apache.http.entity.mime.content.AbstractContentBody;
import org.apache.http.util.Args;
public class InputStreamBody extends AbstractContentBody{
private final InputStream in;
private final String filename;
private long length;
public InputStreamBody(final InputStream in, long length, final String filename, ContentType contentType) {
super(contentType);
if (in == null) {
throw new IllegalArgumentException("Input stream may not be null");
}
this.in = in;
this.filename = filename;
this.length = length;
}
public InputStreamBody(final InputStream in, long length, final String filename) {
this(in, length, filename, ContentType.create("application/octet-stream"));
}
public InputStreamBody(final InputStream in, long length) {
this(in, length, "no_name", ContentType.create("application/octet-stream"));
}
public InputStream getInputStream() {
return this.in;
}
public void writeTo(final OutputStream out) throws IOException {
Args.notNull(out, "Output stream");
try {
byte[] tmp = new byte[4096];
int l;
while ((l = this.in.read(tmp)) != -1) {
out.write(tmp, 0, l);
}
out.flush();
} finally {
this.in.close();
}
}
public String getTransferEncoding() {
return MIME.ENC_BINARY;
}
public String getCharset() {
return null;
}
public long getContentLength() {
return this.length;
}
public String getFilename() {
return this.filename;
}
}
File f = new File("D:\\a.jpg");
InputStreamBody fileis = new InputStreamBody((InputStream)source,f.length(),f.getName());
mediaEntityBuilder = MultipartEntityBuilder.create().addPart("file",fileis);
最后我想说,还是谷歌好啊。0.0