Closed TxcA closed 1 year ago
当然可以修改为
param("json", xxx.toRequestBody(MediaConst.JSON))
👇
partBody.addFormDataPart("json", null, xxx.toRequestBody(MediaConst.JSON))
主要想了解添加"RequestBody"的意义,或是否可以优化。
历史提交备注不明确
我认为应该是之前为了避免RequestBody打印文件日志, 包含filename就可以作为当前参数为文件类型的依据
fun MultipartBody.Part.fileName(): String? {
val contentDisposition = headers?.get("Content-Disposition") ?: return null
val regex = ";\\s${"filename"}=\"(.+?)\"".toRegex()
val matchResult = regex.find(contentDisposition)
return matchResult?.groupValues?.getOrNull(1)
}
虽然这个接口格式奇异,但是正常form-data
也非一定为文件。
接口工具示例,非真实请求
OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("multipart/form-data; boundary=--------------------------753244884812106692899942"); RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) .addFormDataPart("name","TxcA") .addFormDataPart("data","abc123") .addFormDataPart("num","111") .addFormDataPart("file","X:\\68b9254587874f5ba28288bbe9bbe26a.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), new File("X:\\68b9254587874f5ba28288bbe9bbe26a.jpg"))) .build();
Request request = new Request.Builder() // ... .build(); Response response = client.newCall(request).execute();
那我删了这个默认文件名吧
另外再新增一个方法如何
fun param(name: String, filename: String?, value: RequestBody?) {
value ?: return
partBody.addFormDataPart(name, filename, value)
}
由于参照okhtpp函数规则, 另外顺便兼容java函数重载我并没有使用默认参数
之前因为RequestBody和表单参数结合导致日志乱七八糟, 我认为日志不需要打印Part中的RequestBoyd具体内容
Part中附带RequestBody几乎可以肯定为文件吧
默认参数@JvmOverloads
应该可以覆盖。
去年你都不考虑兼容Java的,今年居然变了。另,实在要兼容Java感觉还是再做一层比较合适😁
之前因为RequestBody和表单参数结合导致日志乱七八糟, 我认为日志不需要打印Part中的RequestBoyd具体内容
Part中附带RequestBody几乎可以肯定为文件吧
当下90%是,这个也不一定。一些上古接口json没流行时,除了x-www-form-urlencoded
,form-data
里提交参数的也不少。
我不考虑是没有精力并且害怕臃肿, 但是有考虑支持java二次封装来使用
默认参数
@JvmOverloads
应该可以覆盖。去年你都不考虑兼容Java的,今年居然变了。另,实在要兼容Java感觉还是再做一层比较合适😁
fun param(name: String, fileName: String?, value: File?) // 但是之前的filename顺序在File之前
我直接限制日志对Part的RequestBody打印最大长度512
吧
fun MultipartBody.Part.value(): String? {
return fileName() ?: body.peekBytes(512).utf8()
}
上传File
的,大部分应该还是会用fun param(name: String, fileName: String?, value: File?)
,用fun param(name: String, value: RequestBody?)
的,大部分就应该不是传File
。
如果因为优化
日志改动了其它地方,感觉处理目标错了。应该去找日志地方筛除File
的二进制Body段。
我直接限制日志对Part的RequestBody打印最大长度
512
吧fun MultipartBody.Part.value(): String? { return fileName() ?: body.peekBytes(512).utf8() }
个人感觉打印File
body 意义不大,除了纯文本,其它任何文件也看不出是什么东西。可以置一个变量是否打印File Body
,默认false。
我直接限制日志对Part的RequestBody打印最大长度
512
吧fun MultipartBody.Part.value(): String? { return fileName() ?: body.peekBytes(512).utf8() }
个人感觉打印
File
body 意义不大,除了纯文本,其它任何文件也看不出是什么东西。可以置一个变量是否打印File Body
,默认false。
怎么判断是file? 没filename存在无法判断
okhttp3.MultipartBody
line: 210
@JvmStatic fun createFormData(name: String, filename: String?, body: RequestBody): Part { val disposition = buildString { append("form-data; name=") appendQuotedString(name) if (filename != null) { append("; filename=") appendQuotedString(filename) } }
听你的意思,当初加filename = "RequestBody"
应该是为了
fun MultipartBody.Part.value(): String? {
return fileName() ?: body.peekBytes().utf8()
}
但目前的问题是
form-data
不一定必须是File
Content-Disposition
判断是否有filename,也可以从Content-Type
判断非文件类型,但是做框架的话非做项目,要考虑各异人使用的兼容(比如我这边这个奇葩接口的问题),所以的确也麻烦。iana media-types Content-Type
太多了,且自生不断也再更新🥲
但是常用的应该能缕一缕 WiKi MediaType
Content-Type
可以针对单个PartBody吗? 我依然不确定如何处理Part日志打印
问题描述
咨询为何固定
filename
为 RequestBody,是否有其它的意义。关联提交: 412e293 refactor: 删除param(RequestBody, Header)
fun param(name: String, value: RequestBody?...) {
相关问题
接口比较奇特,需要在
FormData
中提交Content-Type: application/json
,具体数据也为json,同时也会提交一个文件。 之前实现的方法为之前不带
filename="RequestBody"
,正常解析为非文件段,所以可以正常解析,目前自动带了filename,应该是被解析成文件了,所以参数获取失败。(PS: 第三方后端,改不了) 咨询为何固定filename
为 RequestBody,是否有其它的意义。错误的请求
正确的请求
期望行为
如果此处的filename "RequestBody" 有其存在的意义,是否可以
如何复现
无需复现
fork仓库并复现问题可以快速解决, 猜测只会让问题晦涩难懂, 耽误所有人时间截图
异常堆栈信息或者手机截图/视频(拖拽到输入框即可上传)
版本