Skip to content
This repository has been archived by the owner on Dec 31, 2024. It is now read-only.

POST JSON with File not working (multipart/form-data) #118

Open
will-molloy opened this issue Jun 12, 2023 · 4 comments
Open

POST JSON with File not working (multipart/form-data) #118

will-molloy opened this issue Jun 12, 2023 · 4 comments

Comments

@will-molloy
Copy link

Using these deps: feign-core and feign-gson 12.3. feign-form 3.8.0. JDK 19.


I can't get JSON serialisation working when using POST multipart/form-data for POJO->JSON and File.

Example:

interface Example {
  static Example createInstance() {
    return Feign.builder()
        .encoder(new FormEncoder(new GsonEncoder()))
        .target(Example.class, "https://anything.com");
  }

  @RequestLine("POST")
  @Headers("Content-Type: multipart/form-data")
  void uploadWithDto(@Param("dto") Dto dto, @Param("file") File file);

  record Dto(String word, int number) {}

  public static void main(String[] args) throws URISyntaxException {
    Example api = Example.createInstance();
    File file = new File(Thread.currentThread().getContextClassLoader().getResource("file.txt").toURI());
    api.uploadWithDto(new Dto("hello", 123), file);
  }
}

Debugger showed the POJO is not written to the output at all:
image

If I serialise the POJO first then it works, (but uses text/plain):

interface Example {
  static Example createInstance() {
    return Feign.builder()
        .encoder(new FormEncoder(new GsonEncoder()))
        .target(Example.class, "https://anything.com");
  }

  @RequestLine("POST")
  @Headers("Content-Type: multipart/form-data")
  void uploadWithDto(@Param("dto") String dto, @Param("file") File file);

  record Dto(String word, int number) {}

  public static void main(String[] args) throws URISyntaxException {
    Example api = Example.createInstance();
    File file =
        new File(Thread.currentThread().getContextClassLoader().getResource("file.txt").toURI());
    api.uploadWithDto(new Gson().toJson(new Dto("hello", 123)), file);
  }
}

image


There have been previous issues (#24, #28) on this but I haven't been able to get it to work, what am I missing 😕? Also I'm not using Spring which many answers/solutions seem to use.

@will-molloy
Copy link
Author

will-molloy commented Jun 12, 2023

Btw the MultipartFormContentProcessor uses PojoWriter (which doesn't write anything) - how can I make it use Writer with GsonEncoder?

@mirzaprangon
Copy link

mirzaprangon commented Feb 15, 2024

Facing the same issue. Basically, sending an object in the multipart/form-data, the content type becomes text/plain. Which is not desirable. Could not find a way to set the content type to application/json.

@TimerkhanIskhakov
Copy link

First of all the PojoWriter ignores final and static fields, and in Java record all fields are final. Use Java class instead.

The second part of the issue is that the PojoWriter writes all fields of a pojo as a part of a multipart/form-data request. You may follow this solution to solve the problem.

@matmar-91
Copy link

matmar-91 commented Oct 11, 2024

I had the same issue and I resolved it like below. I'm using jackson here but it doesn't matter as long as you are able to serialize your dto to json string:

var json = mapper.writeValueAsString(data);
this.data = FormData.builder().fileName("dto").data(json.getBytes()).contentType("application/json").build();

And my client method looks as follows:

@RequestLine("POST /myEndpoint")
@Headers("Content-Type: multipart/form-data")
ResponseData<Void> myMethod(
    @Param("dto") FormData dto,
    @Param("files") List<File> files
);

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants