iOS 将 base64 编码的图像上传到 RESTful 服务器时获取 http 400

iOS Get http 400 when upload base64 encoded image to a RESTful server

我是服务器端编程的新手。目前,我正在为 iOS 应用程序开发 RESTful 服务器。

从我的 iOS 应用程序上传图像到 RESTful 服务器。

更新:感谢Codo的建议:"You should be more specific about where the error message occurs. My guess is it's when you parse the response in iOS. Your Swift code expects a JSON response. However, on the server side you just send a simple string. That doesn't fit. – Codo"

我添加了一个结果 class,它在服务器端只包含一个字符串类型的消息。 (这是一个简单的字符串响应,而不是 class 响应。)我在评论中添加了具体细节。

此外,我添加了一些代码来检查图像数据是否进入 'createImage' 方法。事实证明数据永远不会进入 'createImage' class。问题可能是由于传输图像数据的方式不正确造成的。

这是服务器端的代码:

结果class:

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
}

我已经做了很多研究,但仍然找不到解决方案。

好的。我自己找出解决办法。我希望它能帮助像我一样的其他初学者。另外,感谢 Codo 的帮助。

首先,我得到“数据无法读取,因为它的格式不正确”的原因是我忘记添加 'Content-Type: application/json' 到header。 iOS 端的代码应该是:

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

其次,在服务器端,我改变

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

至:

createImage(@RequestBody Image image)

我使用 @RequestBody 而不是 @RequestParamimage class 包含两个文件:String fileString desc

就是这样。它对我有用。