【问题标题】:HTTP POST Angular to Java. Cannot send multiple parameters with different typesHTTP POST Angular 到 Java。无法发送不同类型的多个参数
【发布时间】:2019-08-05 08:03:22
【问题描述】:

我正在尝试将上传的文件(来自 Angular 的 FormData)和同一 HTTP POST 请求中的字符串发送到后端(使用 Grizzly 服务器的 Java 和用于 REST 服务的 Ajax)。 问题是我收到 HTTP 400 Bad Request 因为文件未正确映射:

jersey message: Can not construct instance of java.io.InputStream: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type

在前端我有一个名为 Form 的类,使用 ng g class Form 创建,其中包含:

export class Form {
    private file:FormData;
    private bookName: String;

    constructor(file:FormData, bookName: String) {
        this.file = file;
        this.bookName = bookName;
    }
}

来自前端的 HTTP POST 方法是:

  sendFormData() {
    const form  = new Form(this.testData, this.bookName);

    this.pdfService.sendFormData(form).subscribe((res) => {
      console.log(res);
    });
  }

this.testData 上面的类型是 FormData,this.bookName 是一个字符串。它们都包含预期的输入值。

pdfService.sendFormData 是:

  public sendFormData(form: Form) {
    console.log("sending to " + this.baseUrl + "uploadFile")
    return this.http.post(this.baseUrl + "uploadFile", form, { responseType: 'text' });
  }

在后端我有一个类 Form.java(映射类):

public class Form {
    String bookName;
    InputStream file;
    ... (getters & setters & constructor)
}

HTTP POST 方法是:

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_HTML)
    @Path("uploadFile")
    public Response convertPdfToHtml(Form form) {
            ...
    }

要获取我使用的映射字符串:form.getBookName() 并获取我使用的映射文件:form.getFile()。

正如我所说,问题是来自前端的文件没有正确映射到来自后端的 InputStream。

我应该使用什么类型来将前端的 FormData 映射到后端的类型?或者我可以使用哪些其他实现在同一个 POST 请求中发送文件和字符串?

谢谢。

【问题讨论】:

    标签: java ajax angular rest grizzly


    【解决方案1】:

    在 POST 方法中,您应该提供 FormData 类型的对象,然后

    export class Form {
      private file: File;
      private bookName: String;
    
      constructor(file:File, bookName: String) {
        this.file = file;
        this.bookName = bookName;
      }
    }
    
    
    public sendFormData(form: Form) {
      const formData = new FormData();
      formData.append('bookName', form.bookName);
      formData.append('file', form.file, form.file.name);
    
      console.log("sending to " + this.baseUrl + "uploadFile")
      return this.http.post(this.baseUrl + "uploadFile", formData, {responseType: 'text'});
    }
    

    您会收到内容类型为 multipart/form-data 的帖子

    【讨论】:

    • 如果我将值映射到类上,为什么是 @Consumes(MediaType.MULTIPART_FORM_DATA) 而不是 @Consumes(MediaType.APPLICATION_JSON)?因此,我尝试使用 MULTIPART_FORM_DATA 它给了我 415 - 不支持的媒体类型。另外,我不明白为什么我还需要:form.append('bookName', bookName) 和 form.append('file', file, file.name)。我正在调用构造函数: const form = new Form(this.testData, this.bookName);因此 bookName 和文件已经设置好了。我也不能做 form.append('file', file, file.name).
    • 因为 JSON 不能转换 InputStream,它是文本格式,我将更新我的答案以显示,如何发出 POST 请求
    • 您可以使用 JSON,但您必须将文件内容包含为文本(通常也转换为 Base64)。在这种方法中,后端总是得到整个有效载荷,即使不感兴趣
    • 我不喜欢将内容作为文本发送,而是发送整个文件,因此我需要使用 MULTIPART_FORM_DATA,正如你所说的。
    • 成功了。我不再在 Frontend 中使用 Form 类,只是使用带有 append 方法的 FormData 类型来添加对象。在后端,我使用了以下签名:@POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) @Path("uploadFile") public Response convertPdfToHtml(@FormDataParam("bookName") String bookName, @FormDataParam(" file") InputStream UploadInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) {...}
    猜你喜欢
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多