jeesite4的文档中完全没有文件上传接口的说明,issue里找了半天有几个相关的但是都没有完整说明,只好自己动手用fiddler和wireshark抓包:
jeesite4中文件上传分为两步请求,对应url都是****/a/file/upload:
- 发送post请求,将fileName、fileMd5传送到服务端,服务端根据fileMd5判断文件是否已经上传过,如果是就直接返回上传成功并附带对应url,否则返回如下信息
{"result":"false","code":"server","message":"没有找到上传的文件!"}
- 第一步中如果未找到上传的文件,执行真正的上传,这里一直上传不成功,看网络包里对应的参数和文件都在了,可就是找不到原因,后来看到这篇文章中关于Retrofit中part组装参数名的部分,文件对应的参数有个filename,于是我也是了一下,竟然成功了:
这是文章中的代码:
Call<ResponseBody> uploadFile(@Part("file\";filename=\"file.txt"\"") RequestBody file);
//这里的三个转义字符是为了将其原本的name="${param}"格式强行拓展为name="${param1}";filename="${param2}"
大致代码如下,实际使用我是结合RxJava的,需要再整理一下:
Service接口方法:
public interface SystemService {
@FormUrlEncoded
@POST("file/upload")
Observable<FileUploadResult> preUploadFile(@Field("fileName") String fileName, @Field("fileMd5") String fileMd5);
@Multipart
@POST("file/upload")
Observable<FileUploadResult> uploadFile(@PartMap Map<String, RequestBody> params);
}
public void upload(){
File file = new File("/storage/emulated/0/PictureSelector/PictureSelector.1547828853860.jpg");
HashMap<String, RequestBody> map= new HashMap<>();
map.put("uploadType", toRequestBody("image"));
map.put("bizType", toRequestBody("0"));
map.put("bizKey", toRequestBody(""));
map.put("fileMd5", toRequestBody(getMD5(file对应的inputstream)));
map.put("fileName", toRequestBody(file.getName());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpg"), file);
//关键部分,key要有filename
map.put("file\"; filename=\"" + file.getName(), fileBody );
service.uploadFile(map);
}
private RequestBody toRequestBody(String value) {
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), value);
return requestBody;
}
附上MD5方法:
public static String getMD5(InputStream input) throws IOException {
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
int bufferLength = 8 * 1024;
byte[] buffer = new byte[bufferLength];
int read = input.read(buffer, 0, bufferLength);
while (read > -1) {
messageDigest.update(buffer, 0, read);
read = input.read(buffer, 0, bufferLength);
}
return byteArrayToHexString(messageDigest.digest()).toLowerCase();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}