Search code examples
javamultipartrest-clientquarkusmicroprofile

Quarkus multipart client without use form field


I want to write a rest client for old code, which as I understand it accepts multipart. My client is written in quarkus and uses resteasy-multipart-provider I have old code which I want to call with:

 @POST
  @Path("/upload")
  @Produces(MediaType.APPLICATION_JSON)
  public Response addFiles(@Context HttpServletRequest request, @Context ServletContext context)
  {
    try
    {
      File repository = (File) context.getAttribute("javax.servlet.context.tempdir");

      DiskFileItemFactory factory = Utils.getDiskFileItemFactory(context, repository);
      factory.setRepository(repository);

      ServletFileUpload upload = new ServletFileUpload(factory);
      upload.setHeaderEncoding("UTF-8");
      List<FileItem> items = upload.parseRequest(request);

      for (FileItem item: items)
      {
          if (!item.isFormField())
          {
            ....
          }        
      }
.....
  }

And my client:

@Path("/upload")
@RegisterRestClient(configKey = "scannedimage")
@ClientHeaderParam(name = "Authorization", value = "{lookupAuth}")
public interface UploadClient extends BearerAuthorizedHeader {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    Response upload(@MultipartForm UploadBody data);

}

public class UploadBody {

    @FormParam("objectId")
    @PartType(MediaType.TEXT_PLAIN)
    public Long long1;

    @FormParam("entityId")
    @PartType(MediaType.TEXT_PLAIN)
    public Long long2;

    @FormParam("doctype")
    @PartType(MediaType.TEXT_PLAIN)
    public Long documentType;

    @FormParam("file")
    @PartFilename("{file.getName}")
    @PartType(MediaType.APPLICATION_OCTET_STREAM)
    public File file;

}

Response always return emty list

{
  "lon1": 1,
  "long2": 2,
  "list": [],
  "error": ""
}

what am I doing wrong

I have a valid request example creating using org.apache.httpcomponents:httpmime

HttpEntity entity = MultipartEntityBuilder.create().addTextBody("long1", "1").addTextBody("long2", "2499").addTextBody("doctype", "3306").addBinaryBody("file", file, ContentType.create("application/octet-stream"), "test.pdf").build();
HttpPost httpPost = new HttpPost("http://serviece/upload");
httpPost.setEntity(entity);
httpPost.setHeader("Authorization", "Bearer token");
HttpResponse response = httpClient.execute(httpPost);
HttpEntity result = response.getEntity();
System.out.println(EntityUtils.toString(result));

But I would like to implement it with rest-client, if it possible


Solution

  • As a result. I used org.apache.httpcomponents:httpmime:4.5.3 and writed method:

    public UploadResponse upload(String long1, String long2, String documentType, String fileName, InputStream file) {
        try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
            HttpEntity entity = MultipartEntityBuilder
                    .create()
                    .addTextBody("long1", long1)
                    .addTextBody("long2", long2)
                    .addTextBody("documentType", documentType)
                    .addBinaryBody("file", file, ContentType.create(MediaType.APPLICATION_OCTET_STREAM), fileName)
                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                    .setCharset(StandardCharsets.UTF_8)
                    .build();
            HttpPost httpPost = new HttpPost(url + "/upload");
            httpPost.setEntity(entity);
            httpPost.setHeader("Authorization", "Bearer " + token());
            HttpResponse response = httpClient.execute(httpPost);
            return objectMapper.readValue(response.getEntity().getContent(), UploadResponse.class);
        } catch (IOException e) {
            log.error("Error create httpClient", e);
        }
        return new UploadResponse();
    }
    

    Because i can't finded like through resteasy-multipart-provider add file name to file FormParam :(. Maybe it's fix next version quarkus or restEasy