okhttp 遇到的Content-Type 自定义设置问题

okhttp 遇到的Content-Type 自定义设置问题

  1. 有些接口Content-Type 必须设置application/json,但是okhttp 会自动加上 charset=utf-8
    看一下源码
requestBody = RequestBody.create(MediaType.parse("application/json"), json);
  public static RequestBody create(@Nullable MediaType contentType, String content) {
    Charset charset = UTF_8;
    if (contentType != null) {
      charset = contentType.charset();
      if (charset == null) {
        charset = UTF_8;
        contentType = MediaType.parse(contentType + "; charset=utf-8");
      }
    }
    byte[] bytes = content.getBytes(charset);
    return create(contentType, bytes);
  }

3 如果不需要加上charset=utf-8 json 需要转换成ByteString

 ByteString byteString =
                                    ByteString.encodeUtf8(json);
                            requestBody = RequestBody.create(MediaType.parse(headers.get(HttpHeaders.CONTENT_TYPE)), byteString);
  public static RequestBody create(
      final @Nullable MediaType contentType, final ByteString content) {
    return new RequestBody() {
      @Override public @Nullable MediaType contentType() {
        return contentType;
      }

      @Override public long contentLength() throws IOException {
        return content.size();
      }

      @Override public void writeTo(BufferedSink sink) throws IOException {
        sink.write(content);
      }
    };
  }

使用ByteString 就可以使用定义的Content-Type

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,对于这个问题,我可以给出以下的代码示例: ```java private void uploadFileWithProgress(String url, File file, final MediaType mediaType, final ProgressListener progressListener) { OkHttpClient client = new OkHttpClient.Builder() .addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request.Builder requestBuilder = originalRequest.newBuilder() .method(originalRequest.method(), new ProgressRequestBody(originalRequest.body(), progressListener)); return chain.proceed(requestBuilder.build()); } }) .build(); RequestBody requestBody = RequestBody.create(mediaType, file); Request request = new Request.Builder() .url(url) .post(requestBody) .build(); try { Response response = client.newCall(request).execute(); // 处理响应结果 } catch (IOException e) { e.printStackTrace(); } } ``` 其中,`ProgressRequestBody` 是一个自定义的 `RequestBody`,用于在上传文件时监听上传进度。它的代码实现如下: ```java public class ProgressRequestBody extends RequestBody { private RequestBody requestBody; private ProgressListener progressListener; private CountingSink countingSink; public ProgressRequestBody(RequestBody requestBody, ProgressListener progressListener) { this.requestBody = requestBody; this.progressListener = progressListener; } @Override public MediaType contentType() { return requestBody.contentType(); } @Override public long contentLength() { try { return requestBody.contentLength(); } catch (IOException e) { e.printStackTrace(); } return -1; } @Override public void writeTo(BufferedSink sink) throws IOException { countingSink = new CountingSink(sink); BufferedSink bufferedSink = Okio.buffer(countingSink); requestBody.writeTo(bufferedSink); bufferedSink.flush(); } private final class CountingSink extends ForwardingSink { private long totalBytesWritten = 0L; public CountingSink(Sink delegate) { super(delegate); } @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); totalBytesWritten += byteCount; progressListener.onProgress(totalBytesWritten, contentLength()); } } } ``` 然后,在调用 `uploadFileWithProgress` 方法时,只需要传入文件、媒体类型、进度监听器等参数即可: ```java uploadFileWithProgress(url, file, MediaType.parse("image/png"), new ProgressListener() { @Override public void onProgress(long currentBytes, long contentLength) { // 更新进度条 } }); ``` 注意,这里的 `MediaType` 必须要正确指定,否则可能会导致上传失败。另外,由于上传文件是一个比较耗时的操作,建议在子线程中执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值