1

I'm trying to POST an FileInputStream using Retrofit 1.9.x (I can't move to 2.0.x yet)

I've read This Post.

In that post I understood that If I use a TypedInput in my interface and implement TypedInput class wrapper that handled the stream, then it should work. It was unclear if TypedInput vs TypedOutput was the answer (TypedInput sounded the most correct, the linked retrofit documentation didn't specify as far as I could tell. Also It's all moved on to 2.0)

To proceed - I created a class

  private class InputStreamMunger implements TypedInput {
    private InputStream is;
    private String mimeType;
    private Long fileLength;

    public InputStreamMunger(InputStream is, String mimeType, Long fileLength) {
        this.is = is;
        this.fileLength = fileLength;
        this.mimeType = mimeType;
    }

    @Override
    public String mimeType() {
        return mimeType;
    }

    @Override
    public long length() {
        return fileLength;
    }

    @Override
    public InputStream in() throws IOException {
        return is;
    }
}

My Interface:

@Multipart
@POST("/MrService/v1/upload/{accountId}")
Response upload(
    @Path("accountId") String accountId,
    @Part("file") TypedInput file);

Then I call it

    FileInputStream is = new FileInputStream("src/test/java/com/me/MrService/tester.txt");
    InputStreamMunger file ;

    try {
        file = new InputStreamMunger(is, "text/plain", is.getChannel().size());
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }

    Response r = client.upload("12345", file );

The error i get is:

retrofit.RetrofitError: com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class com.me.MrService.IntegrationTestIT$InputStreamMunger and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )

Does this mean that I need to create my own mapper to handle a Stream? I'm hoping that I'm just doing something wrong and that I don't need to jump through that hoop.

Thanks!

David Kerr
  • 146
  • 1
  • 5

1 Answers1

0

In the end I did implement the TypedOutput instead of the TypedInput.

private class InputStreamMunger implements TypedOutput {

    private InputStream is;
    private String mimeType;
    private Long fileLength;
    private String fileName;
    private static final int BUFFER_SIZE = 4096;


    public InputStreamMunger(InputStream is, String mimeType, Long fileLength,
            String fileName) {
        this.is = is;
        this.fileLength = fileLength;
        this.mimeType = mimeType;
        this.fileName = fileName;
    }

    @Override
    public String mimeType() {
        return mimeType;
    }

    @Override
    public long length() {
        return fileLength;
    }

    @Override
    public void writeTo(OutputStream out) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        try {
            int read;
            while ((read = is.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
        } finally {
            is.close();
        }
    }

    public String fileName() {
        return fileName;
    }

}
David Kerr
  • 146
  • 1
  • 5