我在Android上使用Retrofit2和OkHttp来获取HTTP请求.在这里,我正在进行文档上传的POST请求.我在下面遇到了错误:
D/OkHttp:
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:
D/OkHttp:
D/OkHttp:
D/OkHttp:
Error 500 Server ErrorD/OkHttp:
D/OkHttp:
HTTP ERROR 500
D/OkHttp:
Problem accessing /v1/documents. Reason:
D/OkHttp:
Server Error
Caused by:
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多部分请求:

我的代码片段如下:
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方法的接口类:
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 addDocument(
@Part("token") RequestBody token,
@Part("documentType") RequestBody documentType,
@Part MultipartBody.Part file);
}
3)在我的Fragment类中,在onCreate()中调用POST请求:
public class AddDocumentTaskFragment extends Fragment implements Callback {
@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 call, Response response) {
.....
}
@Override
public void onFailure(Call call, Throwable t) {
......
}
知道这里出了什么问题吗?谢谢!
开发者在使用Retrofit2和OkHttp进行Android应用的HTTP POST多部分文件上传时遇到500错误,原因可能是Apache CXF的错误,焦点在于如何解决边界解析问题。代码示例和详细调试日志提供了线索。
1163

被折叠的 条评论
为什么被折叠?



