最近在接豆瓣的分享,期间碰到了较多的陷阱,一路磕磕碰碰,还好最终都解决了。下面总结下期间耗费了我一天的一个巨坑。。。
第一次使用在使用豆瓣广播api(shuo/v2/statuses/)即碰壁,查找原因后发现最后的“/”必不可少。
那么我们继续:
MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(httpConnectionManager);
PostMethod postMethod = new PostMethod("https://api.douban.com/shuo/v2/statuses/");
Part[] parts = new Part[2];
parts[0] = new StringPart("source","XXXXXXXXX", "UTF-8");
parts[0] = new StringPart("text", "ttttt", "UTF-8");
File file = new File("D:\\upload.jpg");
FilePart filePart = new FilePart("image", file.getName(), file,new MimetypesFileTypeMap().getContentType(file), "UTF-8");
parts[1] = filePart;
MultipartRequestEntity requestEntity = new MultipartRequestEntity(parts, postMethod.getParams());
postMethod.setRequestEntity(requestEntity);
postMethod.setRequestHeader("Authorization", "Bearer XXXXXX");
int statusCode = client.executeMethod(postMethod);
String response = new String(postMethod.getResponseBody(), "UTF-8");
System.out.println("response--->" + response);
System.out.println("statusCode--->" + statusCode);
我用的是httpclient3.1,返回结果为{"msg":"不支持的图片格式","r":0}
怎么办?检查多次代码,尝试调整编码多次后,依旧,宣告失败,上豆瓣api小组上搜索,满眼尽是提问的,官方的回复也很简单:"我们的api没问题,请检查参数Content-Type"。
好吧我怕你了,既然你说你们的api没问题,我拿你们提供的sdk参考下总可以吧。于是
下载sdk,我x,老版本的。attachments方式的,不支持image参数。
灵光一显,没准豆瓣自己官方的android里可以用一定的借鉴意义,反编译之,上
应用汇下载豆瓣广播,使用
apk2java解压,jdgui反编译之。
发现android客户端里使用的是httpclient4。参数设置可我也没什么不同。
使用httpclient4写了一个demo,果然可以发送成功。
public static void main(String[] args) throws FileNotFoundException, IOException {
MultipartEntity localMultipartEntity = new MultipartEntity();
localMultipartEntity.addPart("text", new StringBody("texttexttext", Charset.forName("UTF-8")));
File file = new File("D:\\upload.jpg");
localMultipartEntity.addPart("image", new ByteArrayBody(IOUtils.toByteArray(new FileInputStream(file)),
"image/jpeg", "upload.jpg"));
HttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams(); // 计算网络超时用
HttpConnectionParams.setConnectionTimeout(params, 5 * 1000);
HttpConnectionParams.setSoTimeout(params, 2 * 1000);
HttpPost request = new HttpPost("http://api.douban.com/shuo/v2/statuses/");
request.addHeader("Authorization", "Bearer XXXXXX");
request.setEntity(localMultipartEntity);
HttpResponse response = httpClient.execute(request);
System.out.println(response.getStatusLine());
response.getEntity().writeTo(System.out);
}
static class ByteArrayBody extends AbstractContentBody {
private final byte[] data;
private final String filename;
public ByteArrayBody(byte[] paramArrayOfByte, String paramString) {
this(paramArrayOfByte, "application/octet-stream", paramString);
}
public ByteArrayBody(byte[] paramArrayOfByte, String paramString1,
String paramString2) {
super(paramString1);
if (paramArrayOfByte == null)
throw new IllegalArgumentException("byte[] may not be null");
this.data = paramArrayOfByte;
this.filename = paramString2;
}
public String getCharset() {
return null;
}
public long getContentLength() {
return this.data.length;
}
public String getFilename() {
return this.filename;
}
public String getTransferEncoding() {
return "binary";
}
public void writeTo(OutputStream paramOutputStream) throws IOException {
paramOutputStream.write(this.data);
}
}
如意料,httpclient4正常,ok,有了样本,那就离胜利不远了。开始分析。。。。
下载fiddler抓包,由于fiddler无法对java的应用抓包,需要额外设置下,分别对以上两个应用设置代理。
这里豆瓣使用的协议为https,需要进行认证,虽然可以通过注册一个自己的EasySSLProtocolSocketFactory跳过认证,但我们只是为了看下request报文的body,没必要捣鼓这些,将请求地址中的https改为http即可。
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost("127.0.0.1", 8888)); //httpclient4
client.getHostConfiguration().setProxy("127.0.0.1", 8888); //httpclient3
抓包获得的boundary如下:
httpclient3抓到的内容:
------------------314159265358979323846
Content-Disposition: form-data; name="image"; filename="upload.jpg"
Content-Type: image/jpeg
; charset=UTF-8
Content-Transfer-Encoding: binary
XXXXXXX图片bytesXXXXXXX
httpclient4抓到的内容:
--Ih2sX8QV86yWiK_Mux82mBVKkDLWVxG4
Content-Disposition: form-data; name="image"; filename="upload.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
XXXXXXX图片bytesXXXXXXX
可以看出来唯一的区别在于4比3少了一个“charset=UTF-8”,重写httpclient3的boundary输出,发表成功。。
看来是豆瓣接收上传的图片时没有完全按http1.1协议来。摔~~~~~~
重写httpclient3的boundary输出的方法,自定义一个自己的FilePart:
public class DoubanFileBase extends FilePart {
public MyFileBase(String name, String fileName, File file,
String contentType, String charset)
throws FileNotFoundException {
super(name, fileName, file, contentType, charset);
}
protected void sendContentTypeHeader(OutputStream out)
throws IOException {
String contentType = getContentType();
if (contentType != null) {
out.write(CRLF_BYTES);
out.write(CONTENT_TYPE_BYTES);
out.write(EncodingUtil.getAsciiBytes(contentType));
}
}
}
分享到:
相关推荐
豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试豆瓣api测试
微信小程序demo:豆瓣电影:使用API(源代码+截图)微信小程序demo:豆瓣电影:使用API(源代码+截图)微信小程序demo:豆瓣电影:使用API(源代码+截图)微信小程序demo:豆瓣电影:使用API(源代码+截图)微信小程序demo:...
java 豆瓣网API jar 可支持基于豆瓣网的第三方开发
一个基于豆瓣API的书架借阅平台,涉及到技术或者框架:vue2、element、es2015
豆瓣读书v2API访问小程序(python).pdf
程序是通过ISBN获取到书籍信息,调用的接口是豆瓣的API接口 程序使用C#代码编写
一个基于豆瓣官方公开的api接口,写的android实践项目
豆瓣新API Java SDK发布(含OAuth2.0+几乎全部API) 是 豆瓣小组发布的。我只是把包补全了,可以在myeclipse里跑通。
豆瓣API php应用 豆瓣API php应用豆瓣API php应用
使用豆瓣API,根据书籍ISBN码,获取该本书籍的详细信息
豆瓣网开放了很多API,这些API给开发客户端提供了方便。 该客户端实现了授权登陆 通过这个实例,学习如何运用API 功能: 1.登陆 2.书评 3.新书查看 4.电影 音乐 书籍 搜索 5.等等
苹果CMS8X 豆瓣资料采集API 自己搭建单独的域名 建议使用HTTPS安全模式 把里面的index.php文件上传到新站首页 后台添加下面伪静态规则 location / { index index.php; try_files $uri @rewriteapp; } ...
运行此python文件可调用豆瓣api,有正在上映、即将上映、搜索等接口
基于微信小程序,构建的豆瓣电影项目,接口访问来自豆瓣api,目前功能有 搜索功能 下拉刷新 上拉加载 功能说明 接口访问来自豆瓣api,目前功能有 搜索功能 下拉刷新 上拉加载 代码说明 部分采用es6语言,组件化,...
微信小程序demo:豆瓣电影:使用API53.zip
采用vue-resource.js获取豆瓣api制作的豆瓣图书搜索。豆瓣接口已经无法调用,可作为参考学习
NULL 博文链接:https://jykenan.iteye.com/blog/1225212
使用豆瓣API,根据书籍ISBN码,获取该本书籍的详细信息
最近也在看angular,于是就萌生了使用Angular + 豆瓣API 做一个web app。于是…网上回家就折腾了。 体验地址:http://vczero.github.io/t/html/index.html#/ 项目地址:https://github.com/vczero/search
用知乎和gankio 网易新闻 豆瓣电影的API,模仿网易云音乐UI来完成一个基于Material Design Rxjava Retrofit dagger2 MVP构架的项目