2016-12-27 149 views
0

我是服務器端編程的新手。目前,我正在爲iOS應用開發一個RESTful服務器。iOS將base64編碼圖像上傳到RESTful服務器時獲取http 400

當我從iOS應用程序上傳圖像到REST風格的服務器時,出現HTTP響應400和錯誤消息'數據無法讀取,因爲它的格式不正確'。

更新:感謝您對科多的建議:「你應該更具體在哪裏出現錯誤消息我的猜測是,當您分析在iOS上的響應這是你的銀行代碼需要一個JSON響應然而,。 - Codo「

我添加了一個Result類,它只在服務器端包含一個String類型的消息。 (這是一個簡單的字符串響應,而不是類響應。)我在評論中添加了特定的細節。

此外,我添加了一些代碼來檢查圖像數據是否進入'createImage'方法。事實證明,數據永遠不會在'createImage'類中進行。該問題可能是由於傳輸圖像數據的方式不正確造成的。

這是代碼在服務器端:

結果類:

public class Result { 
    private String message; 

    public String getMessage() { 
     return message; 
    } 

    public void setMessage(String message) { 
     this.message = message; 
    } 

    public Result(String message) { 
    super(); 
    this.message = message; 
    } 
} 

控制器:

@PostMapping(value= "/images") 
public ResponseEntity<Result> createImage(@RequestParam("image") String file,@RequestParam("desc") String desc){ 

    // check whether or not image data goes here 
    try{ 
     PrintWriter writer = new PrintWriter("D:/cp/check.txt", "UTF-8"); 
     writer.println("image data is processing"); 
     writer.close(); 
    } catch (IOException e) { 

    } 
    //** file is never created **// 

    //** so nothing happens below **/ 
    if (!file.isEmpty()) { 
    try { 
     byte[] imageByte= parseBase64Binary(file); 

     String directory="D:/cp/" + desc + ".jpg"; 

     new FileOutputStream(directory).write(imageByte); 

     Result result = new Result("You have successfully uploaded "); 

     return new ResponseEntity<Result>(result, HttpStatus.OK); 
    } catch (Exception e) { 
     Result result = new Result("You failed to upload "); 
     return new ResponseEntity<Result>(result, HttpStatus.OK); 
    } 
    } else { 
    Result result = new Result("Unable to upload. File is empty."); 
    return new ResponseEntity<Result>(result, HttpStatus.OK); 
    } 
} 

這是iOS中端代碼:

let serviceUrl = URL(string:"http://192.168.0.17:8080/rest/images/") 

var request = URLRequest(url: serviceUrl!) 

request.httpMethod = "POST" 

let image = UIImage(named: "someImage") 

let data = UIImagePNGRepresentation(image) 

let base64: String! = data?.base64EncodedString() 

let body = ["image": base64, "desc": "firstImage"] 

do {  
    request.httpBody = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted) 

    let session = URLSession.shared.dataTask(with: request) { 

    (data, response, err) in 

    guard err == nil else { 
     // Always no error 
     print(error.localizedDescription) 
     return 
    } 

    let httpResponse = response as! HTTPURLResponse 

    print(httpResponse) 
    // <NSHTTPURLResponse: 0x17003bfa0> { URL: http://192.168.0.17:8080/rest/images/ } 
    // { status code: 400, headers { 
    // Connection = close; 
    // "Content-Language" = en; 
    // "Content-Length" = 1099; 
    // "Content-Type" = "text/html;charset=utf-8"; 
    // Date = "Tue, 27 Dec 2016 23:13:33 GMT"; 
    // } } 

    do { 
     let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, Any> 
     // I pretty sure that parsing data as dictionary is correct because I used same code in many places and they work fine. 

     // code never reaches this line 
     print(json.description) 

    } catch { 
     print(error.localizedDescription) 
     // print: 'The data couldn't read because it isn't in the correct format' 
     return 
    } 
    } 

    session.resume() 

} catch { 
    print(error.localizedDescription) 
    return 
} 

我已經做了很多工作搜索,但仍無法找到解決方案。

+1

您應該更具體地瞭解錯誤消息的發生位置。我的猜測是當你在iOS中解析響應時。你的Swift代碼需要一個JSON響應。但是,在服務器端,您只需發送一個簡單的字符串。這不適合。 – Codo

+0

謝謝你這麼快回復我。我在服務器端進行了一些更改,並根據您的建議添加了更多具體細節 –

+0

如果您收到HTTP錯誤400(或任何其他HTTP錯誤代碼),您不得嘗試將結果解析爲JSON。 400是一個錯誤。所以沒有有效的迴應。它只是產生誤導性的錯誤信息。相反,您應該打印響應,以便可以看到Web服務器返回的完整錯誤消息。你應該設置URL請求的內容類型。目前,它沒有說明。 – Codo

回答

1

好的。我自己找出解決方案。我希望它能幫助像我這樣的其他初學者。此外,感謝Codo的幫助。

首先,我得到'數據無法讀取,因爲它的格式不正確'的原因是我忘了將'Content-Type:application/json'添加到標題中。在iOS中端的代碼應該是:

request.serValue("application/json", forHTTPHeaderField: "Content-Type") 

其次,在服務器端,我改變

createImage(@RequestParam("image") String file,@RequestParam("desc") String desc)

到:

createImage(@RequestBody Image image)

我用@RequestBody,而不是@RequestParamimage類包含兩個文件:String fileString desc

就是這樣。這個對我有用。

相關問題