【问题标题】:Multiple file upload & json object in a single POST Request on Play FrameworkPlay Framework 上的单个 POST 请求中的多个文件上传和 json 对象
【发布时间】:2013-07-10 17:20:45
【问题描述】:

我有一个 Windows Phone 8 客户端,它发出以下发布请求:

public async Task<string> DoPostRequestAsync(String URI, JSonWriter jsonObject, ObservableCollection<byte[]> attachments)
    {
        var client = new RestClient(DefaultUri);

        var request = new RestRequest(URI, Method.POST);
        request.AddParameter("application/json; charset=utf-8", jsonObject.ToString(), ParameterType.RequestBody);

        // add files to upload
        foreach (var a in attachments)
            request.AddFile("picture", a, "file.jpg");

        var content = await client.GetResponseAsync(request);

        return content;
    }

从 RestSharp 文档中我了解到,通过将文件添加到请求中,它会自动作为“multipart/form-data”请求进行。

Play 2.1中上传操作的控制器如下:

@BodyParser.Of(BodyParser.Json.class)
public static Result createMessage() {
    JsonNode json = request().body().asJson();
    ObjectNode result = Json.newObject();
    String userId = json.findPath("userId").getTextValue();
    String rayz = json.findPath("message").getTextValue();

    Http.MultipartFormData body = request().body().asMultipartFormData();
    Http.MultipartFormData.FilePart picture = body.getFile("picture");

    if (picture != null) {
        String fileName = picture.getFilename();
        String contentType = picture.getContentType();
        File file = picture.getFile();

        result.put("status", "success");
        result.put("message", "Created message!");
        return badRequest(result);
    } else {
        result.put("status", "error");
        result.put("message", "Message cannot be created!");
        return badRequest(result);
    }
}

请注意,在 application.conf 上我设置了以下内容以增加大小限制(似乎不起作用):

# Application settings
# ~~~~~
parsers.text.maxLength=102400K

现在,每次我尝试发出 POST 请求时,我都会在调试器上注意到 IsMaxSizeEsceeded 变量始终为 true 并且 multipart 变量为空。当我尝试使用以下控制器上传一个文件时,一切似乎都正常工作。大小不是问题,并且设置了多部分变量。

public static Result singleUpload() {
    ObjectNode result = Json.newObject();

    Http.MultipartFormData body = request().body().asMultipartFormData();
    Http.MultipartFormData.FilePart picture = body.getFile("picture");
    if (picture != null) {
        String fileName = picture.getFilename();
        String contentType = picture.getContentType();
        File file = picture.getFile();
        result.put("status", "success");
        result.put("message", "File uploaded!");
        return badRequest(result);
    } else {
        result.put("status", "error");
        result.put("message", "File cannot be uploaded!");
        return badRequest(result);
    }
}

问题是附件/文件应与 JSON 对象一起在单个 POST 请求中发送/上传到服务器,而不是单独发送。

以前有没有人遇到过类似的问题?是否有可能实现这一点 - 使用 Play 2.1 在单个 POST 请求中发送一个 json 对象和多个要上传到服务器的文件?

【问题讨论】:

    标签: json post windows-phone-8 playframework-2.0 restsharp


    【解决方案1】:

    找到了方法..发布它以防其他人将来尝试做类似的事情。

    所以首先来自 RestSharp 客户端的请求必须通过以下方式完成:

    public async Task<string> DoPostRequestWithAttachmentsAsync(String ext, JSonWriter jsonObject, ObservableCollection<byte[]> attachments) {
        var client = new RestClient(DefaultUri);
        var request = new RestRequest(ext, Method.POST);
    
        request.RequestFormat = DataFormat.Json;
        request.AddParameter("json", jsonObject.ToString(), ParameterType.GetOrPost);
    
        // add files to upload
        foreach (var a in attachments)
            request.AddFile("attachment", a, "someFileName");
    
        var content = await client.GetResponseAsync(request);
    
        if (content.StatusCode != HttpStatusCode.OK)
                return <error>;
    
        return content.Content;
    }
    

    现在进入 Play 控制器如下:

    public static Result createMessage() {
        List<Http.MultipartFormData.FilePart> attachments;
        String json_str;
    
        Http.MultipartFormData body = request().body().asMultipartFormData();
    
        // If the body is multipart get the json object asMultipartFormData()
        if (body!=null) {
            json_str = request().body().asMultipartFormData().asFormUrlEncoded().get("json")[0];
            attachments= body.getFiles();
        }
        // Else, if the body is not multipart get the json object asFormUrlEncoded()
        else {
            json_str = request().body().asFormUrlEncoded().get("json")[0];
            attachments = Collections.emptyList();
        }
    
        // Parse the Json Object
        JsonNode json = Json.parse(json_str);
    
        // Iterate through the uploaded files and save them to the server
        for (Http.MultipartFormData.FilePart o : attachments)
            FileManager.SaveAttachmentToServer(o.getContentType(), o.getFile());
    
        return ok();
    }
    

    所以RestSharp方面的错误似乎是json对象上的ParameterType.RequestBody;并且在控制器中,大小并没有真正改变任何东西..但重要的部分是不要使用 @BodyParser.Of(BodyParser.Json.class) 因为这会将整个请求正文转换为 json 对象。这与发送到服务器的文件相结合会触发 isMaxSizeExceeded 标志。

    最后,控制器中的多部分文件处理如上所示,唯一棘手的部分是附件是可选的,这意味着必须处理。

    【讨论】:

      猜你喜欢
      • 2013-03-30
      • 2019-05-02
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 2021-08-01
      • 1970-01-01
      • 2021-08-10
      相关资源
      最近更新 更多