- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在 Android 上将 Retrofit2 与 OkHttp 一起用于 HTTP 请求。在这里,我正在执行带有文档上传的 POST 请求。我遇到了以下错误:
D/OkHttp: <-- 500 Server Error http://api.drivewealth.io/v1/documents (4289ms)
D/OkHttp: Date: Tue, 11 Apr 2017 03:29:48 GMT
D/OkHttp: Cache-Control: must-revalidate,no-cache,no-store
D/OkHttp: Content-Type: text/html; charset=ISO-8859-1
D/OkHttp: Server: Jetty(9.2.17.v20160517)
D/OkHttp: Content-Length: 9323
D/OkHttp: Connection: keep-alive
D/OkHttp: <html>
D/OkHttp: <head>
D/OkHttp: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
D/OkHttp: <title>Error 500 Server Error</title>
D/OkHttp: </head>
D/OkHttp: <body><h2>HTTP ERROR 500</h2>
D/OkHttp: <p>Problem accessing /v1/documents. Reason:
D/OkHttp: <pre> Server Error</pre></p><h3>Caused by:</h3><pre>org.apache.cxf.interceptor.Fault: Couldn't determine the boundary from the message!
D/OkHttp: at org.apache.cxf.interceptor.AttachmentInInterceptor.handleMessage(AttachmentInInterceptor.java:60)
D/OkHttp: at org.apache.cxf.jaxrs.ext.MessageContextImpl.createAttachments(MessageContextImpl.java:279)
D/OkHttp: at org.apache.cxf.jaxrs.ext.MessageContextImpl.get(MessageContextImpl.java:77)
D/OkHttp: at org.apache.cxf.jaxrs.impl.tl.ThreadLocalMessageContext.get(ThreadLocalMessageContext.java:42)
D/OkHttp: at org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils.getMultipartBody(AttachmentUtils.java:114)
D/OkHttp: at org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils.getAttachments(AttachmentUtils.java:119)
完整调试日志已上传here
API 服务器要求 HTTP POST 多部分请求采用这种格式:
我的代码 fragment 如下:
1) 创建 Retrofit Handler 类:
Interceptor headerInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
String sessionKey = JStockApplication.instance().getTradingOptions().getSessionKey();
okhttp3.Request request = original.newBuilder()
//.header("Accept", "application/json")
.header("Content-Type", "multipart/form-data")
.header("x-mysolomeo-session-key", sessionKey)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
};
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
// add static common headers
httpClient.addInterceptor(headerInterceptor);
// add Logging for development, Log Level: NONE, BASIC, HEADERS, BODY
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logInterceptor);
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://api.drivewealth.io/v1/")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build());
Retrofit retrofit = builder.build();
DriveWealthApi api = retrofit.create(DriveWealthApi.class);
2) Retrofit方法的接口(interface)类:
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
public interface DriveWealthApi {
@Multipart
@POST("documents")
Call<ResponseBody> addDocument(
@Part("token") RequestBody token,
@Part("documentType") RequestBody documentType,
@Part MultipartBody.Part file);
}
3) 在我的 Fragment 类中,在 onCreate() 中调用 POST 请求:
public class AddDocumentTaskFragment extends Fragment implements Callback<ResponseBody> {
@Override
public void onCreate(Bundle savedInstanceState) {
........
........
Bundle bundle = this.getArguments();
String userID = bundle.getString(INTENT_EXTRA_USER_ID);
String docType = bundle.getString(INTENT_EXTRA_DOCUMENT_TYPE);
String fileUri = bundle.getString(INTENT_EXTRA_FILE_URI);
Uri uri = Uri.parse(fileUri);
String filePath = MyUtils.getPath(this.getActivity(), uri);
if (filePath == null || filePath.isEmpty()) {
return;
}
final File myFile = new File(filePath);
MediaType mediaType = MediaType.parse(getActivity().getContentResolver().getType(uri));
if (myFile == null) {
return;
}
// create RequestBody instance from file
RequestBody requestFile = RequestBody.create(mediaType, myFile);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part fileBody = MultipartBody.Part.createFormData("documentImage", myFile.getName(), requestFile);
// add another part within the multipart request
RequestBody tokenBody = RequestBody.create(okhttp3.MultipartBody.FORM, userID);
RequestBody docTypeBody = RequestBody.create(okhttp3.MultipartBody.FORM, docType);
// params: token, documentType, file
this.call = driveWealthApi.addDocument(tokenBody, docTypeBody, fileBody);
this.call.enqueue(this);
}
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
.....
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
......
}
知道这里出了什么问题吗?谢谢!
最佳答案
引用Retrofit 2 can't upload a file with two additional separate string parameters后,我是按照@TommySM的建议实现的。我用这个解决了我的问题:
// create RequestBody instance from file
RequestBody requestFile = RequestBody.create(
mediaType,
myFile);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part file = MultipartBody.Part.createFormData(
"documentImage",
myFile.getName(),
requestFile);
// add another part within the multipart request
RequestBody token = RequestBody.create(
MediaType.parse("text/plain"), // Fixed here
//okhttp3.MultipartBody.FORM, => PROBLEMATIC
userID);
RequestBody docType = RequestBody.create(
MediaType.parse("text/plain"), // Fixed here
//okhttp3.MultipartBody.FORM, => PROBLEMATIC
docTypeStr);
// token, documentType, file
this.call = driveWealthApi.addDocument(token, docType, file);
那些字符串参数应该指定为 Content-Type: text/plain
而不是 Content-Type: multipart/form-data
。
详情见截图:
1) 有问题的 POST
2) 正确的 POST
关于带有 Retrofit2 OkHttp3 的 Android - 多部分 POST 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43320205/
我已经制作了一个用于报名参加 Activity 的小应用程序。用户输入他们的数据,然后单击“登录我”。 现在有时人们在数据库中是双倍的,完全相同的数据彼此之间很快被插入了两次。这只能表示某人单击了两次
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: PHP: “Notice: Undefined variable” and “Notice: Undefin
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: PHP: “Notice: Undefined variable” and “Notice: Undefin
我正在尝试将数据从 Textarea 发布到经典的 ASP 脚本,该脚本更新本地计算机上的 MS SQL,然后发布到另一台服务器上的 PHP 脚本。但是,执行以下操作不起作用,因为它会切断文本区域的数
无效的代码: login_form = page.form_with(:method => 'post') 和有效的代码: login_form = page.form_with(:method =>
我希望能够在 HTTP Post 请求被触发时拦截它,然后修改其请求正文(或参数),然后发送它。 这怎么可能用 jquery/js 实现。 谢谢 最佳答案 Jquery ajax beforeSend
我想编写一个 Mysql 语句,从表(发布)中选择所有内容,其中标题类似于 $title 除了 $title 的标题。基本上我想显示某个帖子的所有相关帖子。我希望查询选择表中标题或详细信息中具有标题名
我已经成功创建了一个简单的 HTML 表单,它将上传的文件发布到我的 Amazon S3 存储桶。我遵循了以下说明: http://aws.amazon.com/articles/1434 现在我正在
我正在实现一个 PayPal IPN 页面,并想检查以确保请求真正来自 PayPal 而不是被欺骗。我假设 HTTP_REFERRER 不是一个好的检查方式?我已经尝试过这种方法,但变量只是空的。 有
我有一个非常简单的设置有一个非常特殊的问题。 该设置部署了 nginx Web 服务器以提供一些静态页面。它还有一个用于处理 POST 请求的后端 uwsgi 守护进程。 我的nginx位置配置如下
我认为我做错了什么,或者误解了我在网上阅读的有关 POST 和 GET 请求的内容。我在 myNumber.ejs 上有一个提交表单。当我按下提交时,有 Add.ejs 的 View 。 Add.ej
我需要将数据从 Express 应用程序的前端发送到后端,然后使用需要显示该数据的 EJS 呈现页面。 问题是 app.post() 方法,随后 res.render() 函数似乎没有完全执行或者当我
根据AWS Documentation对于 CloudFormation cfn-hup 帮助程序脚本,cfn-hup Hook 可以具有“要检测的以逗号分隔的条件列表”。这些条件/触发器可以是 po
位于“wp-admin/includes/”的“post.php”文件中的 wordpress 函数“get_default_post_to_edit”无法正常工作。 当我加载页面时:wp-admin
我使用请求库发布数据,但在服务器上收到空主体,没有传递任何数据。我在代码中遗漏了什么吗? Map map = new Map(); map[csrfNameKey] = csrfName;
我正在尝试使用 siege 3.0.1 测试我的网站。但是好像siege不发送POST数据。这是我从网络浏览器收到的请求 POST / HTTP/1.0 Accept: text/html,appli
我正在尝试为 stockfigher 游戏 api 编写包装器,只是为了了解 feign 是如何工作的,而且我在第一个 POST 方法中遇到了问题: @RequestMapping(method =
如何使用 Jersey 获取原始 POST? @FormParam将不起作用,因为我发布的原始 JSON 不在任何特定的 POST 字段中。 最佳答案 Jersey 带有一个用于将 JSON 映射到
我正在尝试同时创建一个实体和两个子实体的实例。 如果我将以下 JSON 发布到/user_objects 资源,它会很高兴地创建父 user_object 实体和链接的 User_object_att
在 IPV6 中如何使用 IPV6 地址和端口号构建 CURL POST http 请求。任何类型的线程都将受到赞赏。 尝试构建如下请求 >curl --interface 'http://[2001
我是一名优秀的程序员,十分优秀!