JQuery / Ajax POST调用+下载

时间:2016-12-01 14:14:06

标签: java jquery ajax rest post

我知道有很多次问过类似的问题,但过去几个小时我一直在阅读相关问题并且仍然没有找到合适的解决方案。我有一个使用Ajax调用POST方法的表单,它返回一个pdf文件。

$("form#myForm").submit(function(){
var fileRequest = { data0: "test", data1: true };
var formData = new FormData($(this)[0]);
formData.append('request', JSON.stringify(fileRequest));
$.ajax({
    url: 'http://localhost:8080/path/to/my/method',
    type: 'POST',
    data: formData,
    success: function (response, status, xhr) {

    },
    cache: false,
    contentType: false,
    processData: false,
});

return false;
});

现在,我已经了解到Ajax无法处理文件下载,但我想知道我应该如何制作下载窗口。

这是我的servlet方法:

@Path("/method")
@POST
@Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces("application/pdf")
public Response consumeFile(@DefaultValue("true") @FormDataParam("enabled") boolean enabled,
        @FormDataParam("request") FormDataBodyPart bean,
        @FormDataParam("file") FormDataBodyPart file,
        @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) {

    file.setMediaType(MediaType.APPLICATION_OCTET_STREAM_TYPE);
    bean.setMediaType(MediaType.APPLICATION_JSON_TYPE);
    MyClass mc = bean.getValueAs(MyClass.class);
    InputStream in = file.getValueAs(InputStream.class);
    File pdfToReturn = process(in, mc);
    ResponseBuilder response = Response.ok((Object) pdfToReturn);
    response.header("Content Disposition","attachment;filename="+mc.getFileName());

    return response.build();
}

下载返回文件的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我告诉你我是如何解决这个问题的:

1将文件包装为模型类

中的byte []
public class FileModel {

  private String name;
  private String mimeType;
  private byte[] content;

  public FileModel(String name, String mimeType, byte[] content) {
    this.setName(name);
    this.setMimeType(mimeType);
    this.setContent(content);
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getMimeType() {
    return mimeType;
  }

  public void setMimeType(String mimeType) {
    this.mimeType = mimeType;
  }

  public byte[] getContent() {
    return content;
  }

  public void setContent(byte[] content) {
    this.content = content;
  }

}

2返回控制器中的FileModel

@RequestMapping
  public @ResponseBody FileModel function() throws Exception {
    byte[] bytes = serviceToGetTheFile.getFile();
    return new FileModel("Filename", "application/pdf", bytes);
}

3从响应中获取文件

...
success: function (response, status, xhr) {
    var fileModel = response.data;
    var blob = base64toBlob(fileModel.content, fileModel.mimeType);
    var url = window.URL.createObjectURL(blob);
}
...

function base64toBlob(base64Data, contentType, sliceSize) {
  contentType = contentType || '';
  sliceSize = sliceSize || 512;

  var byteCharacters = atob(base64Data);
  var byteArrays = [];

  for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    var slice = byteCharacters.slice(offset, offset + sliceSize);

    var byteNumbers = new Array(slice.length);
    for (var i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    var byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }

  var blob = new Blob(byteArrays, {
    type : contentType
  });
  return blob;
}

最后你有一个加载pdf的网址。如果您愿意,可以使用href中的url创建一个新的a-link。然后点击链接,通过javascript。

我希望我能帮到你!