圖片上傳服務器(formData形式)
網上有許多圖片上傳服務器的方法,但是我通過各種嘗試之后發(fā)現只有這種能夠和我們后臺的開發(fā)人員相溝通,在此做點記錄。
注意:不管是多圖上傳還是單圖上傳,都需要用到AFNetWorking這個三方庫(具體怎么用cocoapods導入我就不說了,百度一下就有),然后導入頭文件
#import <AFNetworking/AFNetworking.h>
1.單圖上傳
(1)服務器接口文檔:

單圖上傳.png
(2)服務器相關代碼:
后臺基本實現思路:使用java的ftpclient,上傳文件到服務器,然后nginx配置靜態(tài)資源訪問就行了
public static String uploadFile(FtpUser user, String remoteSubPath, String remoteFileName, InputStream input)
throws FileNotFoundException {
String result = null;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(user.getHost(), user.getPort());// 連接FTP服務器
// 如果采用默認端口,可以使用ftp.connect(host)的方式直接連接FTP服務器
ftp.login(user.getUserName(), user.getPassWord());// 登錄
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
// 切換到上傳目錄
if (!ftp.changeWorkingDirectory(user.getRemoteBasePath() + remoteSubPath)) {
// 如果目錄不存在,創(chuàng)建目錄
String[] dirs = remoteSubPath.split("/");
String tempPath = user.getRemoteBasePath();
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
// 設置上傳文件的類型為二進制類型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 設置被動模式,默認為主動模式
ftp.enterLocalPassiveMode();
// 上傳文件
String newName = remoteFileName.replaceAll("^([\\s\\S]+)(\\.\\w+)", // 重命名該文件,以配合前端的緩存策略
"$1" + DateTime.now().toString("yyyyMMddHHmmssSSS") + "$2");
if (!ftp.storeFile(newName, input))
return result;
input.close();
ftp.logout();
result = user.getHost() + "/" + "images/" + remoteSubPath + "/" + newName;
logger.info("圖片上傳路徑:" + result);
} catch (IOException e) {
logger.error("文件上傳失敗", e);
return null;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
logger.error("ftp關閉失敗", ioe);
return null;
}
}
}
return result;
}
(3)iOS端相關代碼:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",@"image/jpeg",@"image/png",@"application/octet-stream",@"text/json",nil];
//上傳超時設置
manager.requestSerializer.timeoutInterval = 10.0;
//重點注意:para中的data的key值要和下面文件流的name一致,不然服務器會收到字符串而不是文件。
NSData *data = UIImagePNGRepresentation(image);
NSDictionary *para = @{@"img":data,@"jSessionId":ID};
[manager POST:@"這兒填你們后臺給的完整的上傳圖片的url" parameters:para constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
//上傳的參數(上傳圖片,以文件流的格式)
[formData appendPartWithFileData:data name:@"img" fileName:@"這兒名字可以隨便取" mimeType:@"image/png"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSInteger errCode = [responseObject[@"errorCode"] integerValue];
if (errCode == 0) {
NSLog(@"上傳成功%@",responseObject);
}else{
NSLog(@"錯誤內容%@",responseObject[@"errMessage"]);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"上傳失敗%@",error.description);
}];
2、多圖上傳服務器
(1)服務器接口文檔:

多圖上傳服務器.png
(2)服務器相關代碼:
多圖上傳就是循環(huán)調用單圖上傳方法
public static String uploadImg(String jSessionId, List<MultipartFile> img) throws Exception {
StringBuffer sb = new StringBuffer();
for (MultipartFile file : img) {
String path = uploadImg(jSessionId + DateTime.now().getMillisOfSecond(), file);
if (path == null)
return null;
sb.append(path + ",");
}
return sb.toString().replaceAll("^([\\s\\S]+),", "$1");
}
(3)iOS端相關代碼:
//這里的imageArr是我前面代碼里選擇出來的圖片,放在該數組里的
//imageDataArr同上,這里只貼出了上傳步驟,選圖和壓圖,網上都有很多三方
NSString *urlStr = @"這兒寫后臺給你的完整url";
for (UIImage *image in self.imageArr) {
NSData * imageData = UIImageJPEGRepresentation(image, 0.5);
[self.imageDataArr addObject:imageData];
}
NSDictionary *para = @{@"img":self.imageDataArr[0],@"jSessionId":ID};
AFHTTPSessionManager *imageManager = [AFHTTPSessionManager manager];
imageManager.responseSerializer = [AFHTTPResponseSerializer serializer];
[imageManager POST:urlStr parameters:para constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 上傳 多張圖片
for(NSInteger i = 0; i < self.imageDataArr.count; i++) {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.jpg", str];
//將多張圖的二進制文件拼在一起(name后面的value一定要跟后臺給的接口文檔的key一致)
[formData appendPartWithFileData:self.imageDataArr[i] name:@"img" fileName:fileName mimeType:@"image/jpeg"];
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//將服務器返回的data轉為字典
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"服務器返回內容:%@",result);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"上傳失敗錯誤:%@", error.localizedDescription);
}];