How to post file as an attachment in CXF JAX-RS

10,166

Fixed it by replacing MediaType.APPLICATION_OCTET_STREAM and InputStream stream as below

@Consumes("multipart/form-data")
  public Response postTestData( final List<Attachment> attachments,
    @Context HttpServletRequest request)
Share:
10,166
Karthik Prasad
Author by

Karthik Prasad

Its always fun to write a beautiful piece of code for a complex problem.

Updated on June 04, 2022

Comments

  • Karthik Prasad
    Karthik Prasad almost 2 years

    I'm trying to post a csv.file which is zipped using gzip using cxf and jaxrs.

    Below is the server side code.

    import java.io.File;
     import java.io.FileOutputStream;
     import java.io.IOException;
     import java.io.InputStream;
     import java.io.OutputStream;
     import java.util.zip.GZIPInputStream;
    
    import javax.servlet.http.HttpServletRequest;
     import javax.ws.rs.Consumes;
     import javax.ws.rs.POST;
     import javax.ws.rs.Path;
     import javax.ws.rs.Produces;
     import javax.ws.rs.core.Context;
     import javax.ws.rs.core.MediaType;
     import javax.ws.rs.core.Response;
     import javax.ws.rs.core.Response.Status;
    
    import org.apache.cxf.helpers.IOUtils;
     import org.apache.cxf.jaxrs.ext.multipart.Multipart;
    
    import org.kp.common.LogConstants;
     import org.kp.util.LogHelper;
    
    @Path("TestData")
     public class TestDataResource {
    
      @POST
      @Produces("text/xml")
      @Consumes(MediaType.APPLICATION_OCTET_STREAM)
      public Response postTestData( final @Multipart InputStream stream,
        @Context HttpServletRequest request) {
    
        boolean result = true;
    
        LogHelper.setLog(LogConstants.INFO, request.getContentType());
        LogHelper.setLog(LogConstants.INFO, request.getCharacterEncoding());
        LogHelper.setLog(LogConstants.INFO, request.getHeader("charset"));
        LogHelper.setLog(LogConstants.INFO, request.getHeader("Content-Encoding"));
        LogHelper.setLog(LogConstants.INFO, request.getHeader("Content-Length"));
        LogHelper.setLog(LogConstants.INFO, request.getHeader("Transfer-Encoding"));
    
    
        writeToFile(stream);
        return Response.status(result == true ? Status.OK : Status.EXPECTATION_FAILED).build();
    
      }
    
     private void writeToFile(InputStream inputStream) {
    
      OutputStream outputStream = null;
    
      try {
    
       GZIPInputStream gzis = new GZIPInputStream(inputStream);
        // write the inputStream to a FileOutputStream
        outputStream = new FileOutputStream(new File(
          "d:\\temp\\test.csv"));
        IOUtils.copy(gzis, outputStream);
       } catch (IOException ex) {
        ex.printStackTrace();
       }
       finally{
        try {
         outputStream.close();
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
       }
      }
    
    }
    

    And the client side code is below.

    import java.io.FileInputStream;
     import java.io.FileNotFoundException;
     import java.io.InputStream;
     import java.util.LinkedList;
     import java.util.List;
    
    import javax.ws.rs.core.MediaType;
     import javax.ws.rs.core.Response;
    
    import org.apache.cxf.jaxrs.client.WebClient;
     import org.apache.cxf.jaxrs.ext.multipart.Attachment;
     import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
    
    
     public class kpTest {
    
     public static void main(String[] str) throws FileNotFoundException{
    
      final String  URL = "http://localhost:8080/kp_services/services/kpservices/TestData";
    
      WebClient client = WebClient.create(URL);
    
      //client.type(MediaType.APPLICATION_OCTET_STREAM);
       client.type(MediaType.APPLICATION_OCTET_STREAM);
       ContentDisposition cd = new ContentDisposition("attachment;filename=test.csv.gz");
       List<Attachment> atts = new LinkedList<Attachment>();
       InputStream stream = new FileInputStream("D:\\kp\\test.csv.gz");
       Attachment att = new Attachment("root", stream, cd);
       atts.add(att);
       //Response response = client.post(new MultipartBody(att));
    
      // or just post the attachment if it's a single part request only
      // Response response = client.post(atts);
    
      // or just use a file
       //client.post(new File("D:\\kp\\test.csv"));
    
       Response response = client.post(new File("D:\\kp\\test.csv.gz"));
       System.out.println(response.getStatus());
      }
     }
    

    The above program works fine.

    Response response = client.post(new File("D:\\kp\\test.csv.gz"));
    

    From the above code what I believe is that I'm not sending the file as attachment rather I'm sending it as input stream, with url encoded.

    When I try to modify the code by commenting the above line and uncomment

    Response response = client.post(atts);
    

    I get error message saying No message body writer is found. I even try to change the server side code from @Multipart InputStream stream to List attachement. Still I gate the same error. How to I need to add provider for message body writer. Can some on help me in fixing the issue.