android okhttp post 编码,Android与Retrofit2 OkHttp3 – 多部分POST错误

开发者在使用Retrofit2和OkHttp进行Android应用的HTTP POST多部分文件上传时遇到500错误,原因可能是Apache CXF的错误,焦点在于如何解决边界解析问题。代码示例和详细调试日志提供了线索。

我在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 Error

D/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多部分请求:

810a477d6e01489d35da49a2c6e27e3d.png

我的代码片段如下:

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) {

......

}

知道这里出了什么问题吗?谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值