java.lang.IllegalArgumentException: Unexpected char 0x5a46 at 35 in Content-Disposition value: f

java.lang.IllegalArgumentException: Unexpected char 0x5a46 at 35 in Content-Disposition value: form-data; name=“files”; filename=“婆婆说.mp3”

问题描述

使用Retrofit +okhttp上传文件时,当文件名称含有中文字符时,如下错误

 java.lang.IllegalArgumentException: Unexpected char 0x5a46 at 35 in Content-Disposition value: form-data; name="files"; filename="婆婆说.mp3"
        at okhttp3.Headers.checkValue(Headers.java:272)
        at okhttp3.Headers.of(Headers.java:224)
        at okhttp3.MultipartBody$Part.createFormData(MultipartBody.java:259)
        at common.myh.com.common.network.RequestBodyUtils.prepareFilePartForCall(RequestBodyUtils.java:69)
        at com.geotmt.collection.net.ApiRequest.getMulPartFileListForCall(ApiRequest.java:909)
        at com.geotmt.collection.net.ApiRequest.addPhoneRecord(ApiRequest.java:865)

在这里插入图片描述

原因分析

如图报错处
在这里插入图片描述

createFormData方法源码:
    public static Part createFormData(String name, @Nullable String filename, RequestBody body) {
      if (name == null) {
        throw new NullPointerException("name == null");
      }
      StringBuilder disposition = new StringBuilder("form-data; name=");
      appendQuotedString(disposition, name);

      if (filename != null) {
        disposition.append("; filename=");
        appendQuotedString(disposition, filename);
      }
		/**
		 * 最后掉用 Headers.of方法
		 */
      return create(Headers.of("Content-Disposition", disposition.toString()), body);
    }
继续看Headers的of方法源码
  public static Headers of(String... namesAndValues) {
    if (namesAndValues == null) throw new NullPointerException("namesAndValues == null");
    if (namesAndValues.length % 2 != 0) {
      throw new IllegalArgumentException("Expected alternating header names and values");
    }

    // Make a defensive copy and clean it up.
    namesAndValues = namesAndValues.clone();
    for (int i = 0; i < namesAndValues.length; i++) {
      if (namesAndValues[i] == null) throw new IllegalArgumentException("Headers cannot be null");
      namesAndValues[i] = namesAndValues[i].trim();
    }

    // Check for malformed headers.
    for (int i = 0; i < namesAndValues.length; i += 2) {
      String name = namesAndValues[i];
      String value = namesAndValues[i + 1];
      //检查  name  注意抛出的异常是此处抛出的
      checkName(name);
      //检查 value
      checkValue(value, name);
    }

    return new Headers(namesAndValues);
  }
chekName()方法源码校验文件的名字
  static void checkName(String name) {
    if (name == null) throw new NullPointerException("name == null");
    if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
    for (int i = 0, length = name.length(); i < length; i++) {
      char c = name.charAt(i);
      if (c <= '\u0020' || c >= '\u007f') {
      /**
        *  最终抛出的异常的地方
        */
        throw new IllegalArgumentException(Util.format(
            "Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
      }
    }
  }

解决办法

方案一不完美,直接try catch

这种方案本质上没解决问题, 不是一个好的方案
在这里插入图片描述

方案二 将文件名进行规范,想办法去掉中文

有很多办法如通过 文件名的md5值进行或者通过 URLEncoder进行编码, 到了服务器在进行解码等

 URLEncoder.encode(file.getName(), "UTF-8")

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_37639900/article/details/104009283
今日推荐