使用 Retrofit2 将文件上传到 slack
Upload file to slack with Retrofit2
我正在尝试使用 retrofi2 最新发布版本将文件(堆转储)上传到松弛通道。
@Override
public void onCreate() {
super.onCreate();
slackApi = new Retrofit.Builder()
.baseUrl("https://slack.com/")
.build() //
.create(SlackApi.class);
}
@Multipart
@GTConverterAnnotation(value = GTConverterAnnotation.GSON)
@POST("api/files.upload")
Call<ResponseBody> uploadFile(
@Part("token") String token,
@Part("file") RequestBody file, @Part("filetype") String filetype,
@Part("filename") String filename, @Part("title") String title,
@Part("initial_comment") String initialComment, @Part("channels") String channels);
RequestBody file = RequestBody
.create(MediaType.parse("multipart/form-data"), heapDump.heapDumpFile);
final Call<ResponseBody> call = slackApi.uploadFile(SlackApi.TOKEN,
file,
null,
heapDump.heapDumpFile.getName(), title, initialComment,
SlackApi.MEMORY_LEAK_CHANNEL);
以下代码甚至在 "slack.uploaFile" 执行之前就失败并出现异常,但出现以下异常:
> E/AndroidRuntime: FATAL EXCEPTION: IntentService[com.squareup.leakcanary.AbstractAnalysisResultService]
Process: com.gettaxi.dbx.android, PID: 11127
java.lang.IllegalArgumentException: Could not locate RequestBody converter for class java.lang.String.
Tried:
* retrofit2.BuiltInConverters
at retrofit2.Retrofit.nextRequestBodyConverter(Retrofit.java:298)
at retrofit2.Retrofit.requestBodyConverter(Retrofit.java:258)
at retrofit2.ServiceMethod$Builder.parseParameterAnnotation(ServiceMethod.java:577)
at retrofit2.ServiceMethod$Builder.parseParameter(ServiceMethod.java:328)
at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:201)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166)
at retrofit2.Retrofit.invoke(Retrofit.java:145)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy13.uploadFile(Unknown Source)
at com.gettaxi.dbx.android.services.LeakSlackUploadService.afterDefaultHandling(LeakSlackUploadService.java:50)
at com.squareup.leakcanary.DisplayLeakService.onHeapAnalyzed(DisplayLeakService.java:86)
at com.squareup.leakcanary.AbstractAnalysisResultService.onHandleIntent(AbstractAnalysisResultService.java:49)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
我错过了什么?为什么要为字符串寻找 RequestBody 转换器?
更新
刚刚创建了类似于 Matrix 建议的完整解决方案:
https://gist.github.com/parahall/cbba57d9d10f6dcd850f
您是否为 Retrofit
添加了转换器?
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.example.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
首先,我想指出还有其他方法可以实现这一点,但我继续前进只是确保该解决方案没有重大缺陷。
请在此处查看我的回购协议:
更新:url 和 repo 名称已更改
https://github.com/MaTriXy/Slackrofit
同时粘贴相关代码:
@Multipart
@POST("api/files.upload")
Call<UploadFileResponse> uploadFile(
@Query("token") String token,
@PartMap Map<String, RequestBody> params,
@Query("filetype") String filetype,
@Query("filename") String filename, @Query("title") String title,
@Query("initial_comment") String initialComment, @Query("channels") String channels);
slackApi = new Retrofit.Builder().baseUrl("https://slack.com/").client(new OkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build().create(SlackApi.class);
String str = "Google Places API for Android Samples\n" +
"===================================\n" +
"\n" +
"Samples that use the [Google Places API for Android](https://developers.google.com/places/android/).\n" +
"\n" +
"This repo contains the following samples:";
file = RequestBody.create(MediaType.parse("multipart/form-data"), str.getBytes());
Map<String, RequestBody> map = new HashMap<>();
map.put("file\"; filename=\"heapDump.md\"", file);
call = slackApi.uploadFile(SlackApi.TOKEN, map, "text",
"heapDump.md", "Test Dump", "Check this out", SlackApi.MEMORY_LEAK_CHANNEL);
稍后激活通话:
call.clone().enqueue(new Callback<SlackApi.UploadFileResponse>() {
@Override
public void onResponse(Call<SlackApi.UploadFileResponse> call, Response<SlackApi.UploadFileResponse> response) {
if (response != null) {
Log.e("GAG", response.body().toString());
}
}
@Override
public void onFailure(Call<SlackApi.UploadFileResponse> call, Throwable t) {
t.printStackTrace();
}
});
我正在使用克隆来测试多个上传,而这使我不必在每次要使用它时都重新构建一个新调用。
UploadFileResponse 很简单:
public static class UploadFileResponse {
boolean ok;
String error;
@Override
public String toString() {
return "UploadFileResponse{" +
"ok=" + ok +
", error='" + error + '\'' +
'}';
}
}
我正在尝试使用 retrofi2 最新发布版本将文件(堆转储)上传到松弛通道。
@Override
public void onCreate() {
super.onCreate();
slackApi = new Retrofit.Builder()
.baseUrl("https://slack.com/")
.build() //
.create(SlackApi.class);
}
@Multipart
@GTConverterAnnotation(value = GTConverterAnnotation.GSON)
@POST("api/files.upload")
Call<ResponseBody> uploadFile(
@Part("token") String token,
@Part("file") RequestBody file, @Part("filetype") String filetype,
@Part("filename") String filename, @Part("title") String title,
@Part("initial_comment") String initialComment, @Part("channels") String channels);
RequestBody file = RequestBody
.create(MediaType.parse("multipart/form-data"), heapDump.heapDumpFile);
final Call<ResponseBody> call = slackApi.uploadFile(SlackApi.TOKEN,
file,
null,
heapDump.heapDumpFile.getName(), title, initialComment,
SlackApi.MEMORY_LEAK_CHANNEL);
以下代码甚至在 "slack.uploaFile" 执行之前就失败并出现异常,但出现以下异常:
> E/AndroidRuntime: FATAL EXCEPTION: IntentService[com.squareup.leakcanary.AbstractAnalysisResultService]
Process: com.gettaxi.dbx.android, PID: 11127
java.lang.IllegalArgumentException: Could not locate RequestBody converter for class java.lang.String.
Tried:
* retrofit2.BuiltInConverters
at retrofit2.Retrofit.nextRequestBodyConverter(Retrofit.java:298)
at retrofit2.Retrofit.requestBodyConverter(Retrofit.java:258)
at retrofit2.ServiceMethod$Builder.parseParameterAnnotation(ServiceMethod.java:577)
at retrofit2.ServiceMethod$Builder.parseParameter(ServiceMethod.java:328)
at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:201)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166)
at retrofit2.Retrofit.invoke(Retrofit.java:145)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy13.uploadFile(Unknown Source)
at com.gettaxi.dbx.android.services.LeakSlackUploadService.afterDefaultHandling(LeakSlackUploadService.java:50)
at com.squareup.leakcanary.DisplayLeakService.onHeapAnalyzed(DisplayLeakService.java:86)
at com.squareup.leakcanary.AbstractAnalysisResultService.onHandleIntent(AbstractAnalysisResultService.java:49)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
我错过了什么?为什么要为字符串寻找 RequestBody 转换器?
更新 刚刚创建了类似于 Matrix 建议的完整解决方案: https://gist.github.com/parahall/cbba57d9d10f6dcd850f
您是否为 Retrofit
添加了转换器?
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.example.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
首先,我想指出还有其他方法可以实现这一点,但我继续前进只是确保该解决方案没有重大缺陷。
请在此处查看我的回购协议: 更新:url 和 repo 名称已更改 https://github.com/MaTriXy/Slackrofit
同时粘贴相关代码:
@Multipart
@POST("api/files.upload")
Call<UploadFileResponse> uploadFile(
@Query("token") String token,
@PartMap Map<String, RequestBody> params,
@Query("filetype") String filetype,
@Query("filename") String filename, @Query("title") String title,
@Query("initial_comment") String initialComment, @Query("channels") String channels);
slackApi = new Retrofit.Builder().baseUrl("https://slack.com/").client(new OkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build().create(SlackApi.class);
String str = "Google Places API for Android Samples\n" +
"===================================\n" +
"\n" +
"Samples that use the [Google Places API for Android](https://developers.google.com/places/android/).\n" +
"\n" +
"This repo contains the following samples:";
file = RequestBody.create(MediaType.parse("multipart/form-data"), str.getBytes());
Map<String, RequestBody> map = new HashMap<>();
map.put("file\"; filename=\"heapDump.md\"", file);
call = slackApi.uploadFile(SlackApi.TOKEN, map, "text",
"heapDump.md", "Test Dump", "Check this out", SlackApi.MEMORY_LEAK_CHANNEL);
稍后激活通话:
call.clone().enqueue(new Callback<SlackApi.UploadFileResponse>() {
@Override
public void onResponse(Call<SlackApi.UploadFileResponse> call, Response<SlackApi.UploadFileResponse> response) {
if (response != null) {
Log.e("GAG", response.body().toString());
}
}
@Override
public void onFailure(Call<SlackApi.UploadFileResponse> call, Throwable t) {
t.printStackTrace();
}
});
我正在使用克隆来测试多个上传,而这使我不必在每次要使用它时都重新构建一个新调用。
UploadFileResponse 很简单:
public static class UploadFileResponse {
boolean ok;
String error;
@Override
public String toString() {
return "UploadFileResponse{" +
"ok=" + ok +
", error='" + error + '\'' +
'}';
}
}