OkHttp发XML时Content-Type必须设为application/xml;需用MediaType.get("application/xml; charset=utf-8")构造,RequestBody.create()第二参数不可省略,XML内容须UTF-8无BOM编码。

OkHttp发XML时Content-Type必须设成application/xml
Android用OkHttpClient上传XML,服务器收不到或解析失败,八成是Content-Type没对。默认发出去是text/plain或application/octet-stream,后端框架(比如Spring Boot的@RequestBody)直接拒掉或当成二进制流处理。
实操建议:
- 用
MediaType.get("application/xml; charset=utf-8")构造MediaType,别手写字符串 -
RequestBody.create()第二个参数必须传MediaType,否则类型丢失 - XML内容本身要UTF-8编码,避免BOM头——Windows记事本保存时选“UTF-8 无BOM”
- 如果XML里有中文但服务器报
Invalid byte 2 of 3-byte UTF-8 sequence,就是编码不一致
XML作为文件上传还是纯文本体发送?
看后端接口定义。大多数情况不需要走MultipartBody——那是为上传.xml文件(带文件名、边界符)设计的;如果后端只接受POST /api/data + 原始XML体,就该用RequestBody.create()。
常见错误现象:
- 用
MultipartBody.Builder塞XML,结果请求体多出----boundary和Content-Disposition,后端解析失败 - 后端日志显示收到的是空体或乱码,其实是
RequestBody创建时传了null或空字符串 - XML里含
声明,但OkHttp不关心这个,删不删都行,关键是整个字符串编码要对
OkHttp同步/异步调用中怎么传XML字符串
核心就是把XML内容转成RequestBody,再塞进Request.Builder。别在RequestBody里做网络IO或耗时操作,比如读文件时用FileInputStream再转String——容易OOM或卡主线程。
实操建议:
- XML内容小(RequestBody.create(xmlString, MediaType.get("application/xml; charset=utf-8"))
- XML内容大或来自文件:用
RequestBody.create(file, MediaType.get("application/xml")),OkHttp会内部流式读取,不全加载进内存 - 异步调用记得在
Callback.onResponse()里切回主线程更新UI,别在回调里直接setText() - 同步调用务必放子线程,
execute()会阻塞当前线程,Android上主线程抛NetworkOnMainThreadException
遇到java.net.SocketTimeoutException或400错误怎么办
不是XML格式问题,而是OkHttp默认超时太短(10秒),或者服务器返回了HTTP 400但没给具体原因。XML本身语法错(比如标签没闭合)通常导致后端直接返回400,但OkHttp不会自动打印响应体。
排查步骤:
- 先用
curl -X POST -H "Content-Type: application/xml" --data-binary @test.xml http://your.api确认后端是否正常接收 - OkHttp里加拦截器打印
response.body().string()(注意只能读一次!) - 检查XML根节点是否符合后端要求——比如强制要
,你发了就会400 - 设置超时:
new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS)
&、)必须预先转义,OkHttp不帮你干这事;后端用Jackson或JAXB解析时,如果没配disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES),字段多一个少一个也会静默失败。










