HTTP POST到Java。无法发送不同类型的多个参数

HTTP POST到Java。无法发送不同类型的多个参数,java,ajax,angular,rest,grizzly,Java,Ajax,Angular,Rest,Grizzly,我试图将上传的文件(来自Angular的FormData)和同一HTTP POST请求中的字符串发送到后端(Java使用Grizzly服务器和Ajax提供REST服务)。 问题是,我收到HTTP 400错误请求,因为文件映射不正确: jersey message: Can not construct instance of java.io.InputStream: abstract types either need to be mapped to concrete types, have cu

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

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
在前端,我使用ng g class Form创建了一个名为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(映射类):

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请求中发送文件和字符串


谢谢。

在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/FormData的post,在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\u form\u data)而不是@Consumes(MediaType.APPLICATION\u JSON)?因此,我尝试使用MULTIPART_FORM_数据,它给出了415-不支持的媒体类型。另外,我不明白为什么我还需要:form.append('bookName',bookName)和form.append('file',file,file.name)。我正在调用构造函数:const form=new form(this.testData,this.bookName);因此,已经设置了书名和文件。另外,我不能做form.append('file',file,file.name)。因为JSON不能caryy InputStream,它是文本格式,我会更新我的答案以显示如何发出POST请求。你可以使用JSON,但你必须将文件内容作为文本包含(通常也转换为Base64)。在这种方法中,后端总是获得整个负载,即使不感兴趣。我不希望以文本形式发送内容,而是发送整个文件,因此,正如您所说,我需要使用多部分表单数据。这很有效。我不再在前端使用Form类,只使用带有append方法的FormData类型来添加对象。在后端,我使用了以下签名:@POST@Consumes(MediaType.MULTIPART\u FORM\u DATA)@products(MediaType.TEXT\u HTML)@Path(“uploadFile”)公共响应convertPdfToHtml(@FormDataParam(“bookName”)String bookName,@FormDataParam(“file”)InputStream uploadedInputStream,@FormDataParam(“file”)FormDataContentDispositionFileDetail){…}如果我映射类上的值,为什么@Consumes(MediaType.MULTIPART\u FORM\u DATA)而不是@Consumes(MediaType.APPLICATION\u JSON)?因此,我尝试使用MULTIPART_FORM_数据,它给出了415-不支持的媒体类型。另外,我不明白为什么我还需要:form.append('bookName',bookName)和form.append('file',file,file.name)。我正在调用构造函数:const form=new form(this.testData,this.bookName);因此,已经设置了书名和文件。另外,我不能做form.append('file',file,file.name)。因为JSON不能caryy InputStream,它是文本格式,我会更新我的答案以显示如何发出POST请求。你可以使用JSON,但你必须将文件内容作为文本包含(通常也转换为Base64)。在这种方法中,后端总是获得整个负载,即使不感兴趣。我不希望以文本形式发送内容,而是发送整个文件,因此,正如您所说,我需要使用多部分表单数据。这很有效。我不再在前端使用Form类,只使用带有append方法的FormData类型来添加对象。在后端,我使用了以下签名:@POST@Consumes(MediaType.MULTIPART\u FORM\u DATA)@products(MediaType.TEXT\u HTML)@Path(“uploadFile”)公共响应convertPdfToHtml(@FormDataParam(“bookName”)String bookName,@FormDataParam(“file”)InputStream uploadedInputStream,@FormDataParam(“file”)FormDataContentDispositionFileDetail){…}