Как загрузить изображение с помощью json?
Я пытаюсь загрузить изображение с данными json. Я просто следовал посту и реализовал механизм. Но я получаю ошибку
{ status code: 400, headers {
"Cache-Control" = "no-cache, no-store, max-age=0, must-revalidate";
Connection = close;
"Content-Language" = en;
"Content-Length" = 1033;
"Content-Type" = "text/html;charset=utf-8";
Date = "Wed, 27 Jan 2016 10:44:34 GMT";
Expires = 0;
Pragma = "no-cache";
Server = "Apache-Coyote/1.1";
"X-Content-Type-Options" = nosniff;
"X-XSS-Protection" = "1; mode=block";
} }`
Ниже приведен полный HTTP-запрос
Content-Type: multipart/form-data;boundary=Boundary_123456789
Authorization: Basic bihdwbcIUkbcdwjnoNOn
User-Agent: Jersey/2.21.1 (HttpUrlConnection 1.8.0_45)
MIME-Version: 1.0
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 3526
--Boundary_123456789
Content-Type: application/json
Content-Disposition: form-data; name="userDTO"
{"id":"id","name":"name","age":23}
--Boundary_123456789
Content-Type: image/png
Content-Disposition: form-data; filename="sample-image2.png"; modification-date="Fri, 22 Jan 2016 04:56:48 GMT"; size=3308; name="file"
‰PNG
<Binary data>
--Boundary_123456789—
Ниже приведена моя реализация
func addUser(completion: (message: String?, error: String?) -> Void) -> NSURLSessionDataTask {
// create the request
let request = createRequest()
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
print(response) // 400 Error is printed here
}
task.resume()
return task
}
func createRequest () -> NSURLRequest {
let param = [
"id": "id",
"name": "name",
"age": 23] // build your dictionary however appropriate
let boundary = generateBoundaryString()
let url = NSURL(string: SERVERURL)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.addValue("Basic (base64LoginString())", forHTTPHeaderField: "Authorization")
request.setValue("multipart/form-data; boundary=(boundary)", forHTTPHeaderField: "Content-Type")
let path1 = NSBundle.mainBundle().pathForResource("userImage", ofType: "png") as String!
request.HTTPBody = createBodyWithParameters(param, paths: [path1], boundary: boundary)
return request
}
func createBodyWithParameters(json: [String:AnyObject], paths: [String]?, boundary: String) -> NSData {
let body = NSMutableData()
let key = "userDTO"
body.appendString("--(boundary)rn")
body.appendString("Content-Type: application/json")
body.appendString("Content-Disposition: form-data; name="(key)"rnrn")
var requestBody = NSData()
do {
requestBody = try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions(rawValue:0))
} catch (let e) {
print(e)
}
body.appendData(requestBody)
//body.appendString("(json)rn")
if paths != nil {
for path in paths! {
let url = NSURL(fileURLWithPath: path)
let data = NSData(contentsOfURL: url)!
let mimetype = mimeTypeForPath(path)
let fileName = "sample-image23.png"
let date = "Fri, 22 Jan 2016 04:56:48 GMT"
let name = "file"
body.appendString("--(boundary)rn")
body.appendString("Content-Type: (mimetype)rnrn")
body.appendString("Content-Disposition: form-data; filename="(fileName)"; modification-date="(date)"; size=3308; name="(name)"rn")
body.appendData(data)
body.appendString("rn")
}
}
body.appendString("--(boundary)--rn")
return body
}
func generateBoundaryString() -> String {
return "Boundary-(NSUUID().UUIDString)"
}
func mimeTypeForPath(path: String) -> String {
let url = NSURL(fileURLWithPath: path)
let pathExtension = url.pathExtension
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
return mimetype as String
}
}
return "application/octet-stream";
}
Также расширение
extension NSMutableData {
func appendString(string: String) {
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
appendData(data!)
}
}
Я думаю, что делаю какую-то ошибку в формате json. Кто-нибудь может помочь? Спасибо!
2 ответа:
Похоже, загрузка изображения-это не ваша проблема , насколько я вижу, это удалось. Вы должны понимать, что загрузка изображения не имеет ничего общего с JSON. Скорее всего, вы ищете ответ в ожидаемом формате (JSON). Таким образом, если вам требуется получить ответ, тело которого является JSON, вы должны явно заявить об этом, установив соответствующий заголовок
Accept
. Например:
Accept: application/json
И в коде:
request.setValue("application/json", forHTTPHeaderField: "Accept")
Когда вы получаете ответ, вы также должны сначала проверить код состояния ответа, а затем заголовок
Content-Type
(соответственно, свойство response'MIMEType
), который должен соответствовать тому, что вы ожидаете:application/json
.Если тип контента не соответствует вашим ожиданиям, вы можете попробовать дополнительные "сериализаторы ответов" - каждый из них подходит для анализа других типов контента, например
text/plain
и т. д.- как вам будет угодно.Редактировать:
Сервер ответил намеком, что вторая часть составного запроса является бесформенный. Взглянув на то, как он составлен:
body.appendString("--\(boundary)\r\n") body.appendString("Content-Type: \(mimetype)\r\n\r\n") body.appendString("Content-Disposition: form-data; filename='sample-image23.png'; modification-date='Fri, 22 Jan 2016 04:56:48 GMT'; size=3308; name='file'\r\n") body.appendData(data) body.appendString("\r\n")
Теперь, присмотревшись, мы можем увидеть, что второй заголовок
Content-Type
будет разделен двумяCRLF
- но за этим следует еще один заголовок. Заголовки должны быть разделены только однимCRLF
.Тогда, последний заголовок должен быть разделен двумя
CRLF
.Предложенное исправление:
body.appendString("--\(boundary)\r\n") body.appendString("Content-Disposition: form-data; filename='sample-image23.png'; modification-date='Fri, 22 Jan 2016 04:56:48 GMT'; size=3308; name='file'\r\n") body.appendString("Content-Type: \(mimetype)\r\n\r\n") body.appendData(data) body.appendString("\r\n")
(правка: удалено неверное описание)
Правка 2:
В этих строках, над этой, также отсутствует
CRLF
:let key = "userDTO" body.appendString("--\(boundary)\r\n") body.appendString("Content-Type: application/json") body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
Вы видите проблему?
Content-Type
не имеет концаCRLF
!Смотрите также: NSURLRequest загрузить несколько файлов
Этот фрагмент кода поможет вам загрузить файлUIImage в веб-сервис с помощью методаPOST .
func uploadImageOne(){ var imageData = UIImagePNGRepresentation(exampleImageView.image) if imageData != nil{ var request = NSMutableURLRequest(URL: NSURL(string:"Your URL")!) var session = NSURLSession.sharedSession() request.HTTPMethod = "POST" var boundary = NSString(format: "---------------------------14737809831466499882746641449") var contentType = NSString(format: "multipart/form-data; boundary=%@",boundary) // println("Content Type \(contentType)") request.addValue(contentType, forHTTPHeaderField: "Content-Type") var body = NSMutableData.alloc() // Title body.appendData(NSString(format: "\r\n--%@\r\n",boundary).dataUsingEncoding(NSUTF8StringEncoding)!) body.appendData(NSString(format:"Content-Disposition: form-data; name=\"title\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!) body.appendData("Hello World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!) // Image body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!) body.appendData(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"img.jpg\"\\r\n").dataUsingEncoding(NSUTF8StringEncoding)!) body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!) body.appendData(imageData) body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!) request.HTTPBody = body var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil) var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding) println("returnString \(returnString)") } }