users@jersey.java.net

[Jersey] FormDataMultiPart http post in RESTful application

From: <dave.banan_at_oracle.com>
Date: Thu, 12 Jul 2012 14:29:31 +0000 (GMT)

Hey everyone, I'm trying to to send an HTTP post that contains a
FormDataMultiPart object to my REST resource. The server responds with
"Unsupported media type" and logs the error message:

"SEVERE: A message body reader for Java class
com.sun.jersey.multipart.FormDataMultiPart, and Java type class
com.sun.jersey.multipart.FormDataMultiPart, and MIME media type
multipart/form-data was not found."

I've included the mimepull.jar in the classpath as was recommended in a
previous post. That didn't help.

Here's the code I'm using:

The test method:

       @Test
        public void testGetDocumentDetails() {
                RestUriBuilder builder = new
RestUriBuilder(System.getProperty(IntgConstants.INTG_BASE_URL) +
RestConstants.REST_PATH, "/documents/adddocument");

                byte[] data = "hello world".getBytes();

                UCRDocument doc = new UCRDocument();

                doc.setFileName("Name");
                doc.setCreationDate(new Date());
                doc.setAtRootLevel(true);
                doc.setFileSize(data.length);
                doc.setMimeType("text/plain");
                doc.setTitle("Title");
                
                FormDataMultiPart multiPart = new FormDataMultiPart();
                
            multiPart.bodyPart(new BodyPart(doc,
MediaType.APPLICATION_JSON_TYPE));
            multiPart.bodyPart(new BodyPart(data,
MediaType.APPLICATION_OCTET_STREAM_TYPE));

                UCRDocument returnedDocument =
HttpUtils.doMultiPartPost(builder.buildUri(), m_sessionId, multiPart,
new TypeReference<UCRDocument>(){});
                
                RestUriBuilder getDetailsBuilder = new
RestUriBuilder(System.getProperty(IntgConstants.INTG_BASE_URL) +
RestConstants.REST_PATH, "/documents/getdocumentdetails");
                UCRDocument content =
HttpUtils.doPost(getDetailsBuilder.buildUri(), m_sessionId,
returnedDocument, new TypeReference<UCRDocument>(){});
                
                Assert.assertEquals(data.length,
content.getFileSize());
        }



The HTTP Post:

    public static <T> T doMultiPartPost(String url, String sessionId,
FormDataMultiPart obj, TypeReference<T> ref) {
        HttpUriRequest postObject = getMultiPartPost(url, sessionId,
obj);
        String jsonResponse = execute(postObject);
        return IntgUtils.convertJsonToObject(jsonResponse, ref);
    }

    public static HttpPost getMultiPartPost(String url, String
sessionId, FormDataMultiPart obj){
        HttpPost post = getPost(url, sessionId);
        post.setHeader(HttpConstants.CONTENT_TYPE,
MediaType.MULTIPART_FORM_DATA);
        MultipartEntity entity = new
MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        
        List<BodyPart> parts = obj.getBodyParts();
        UCRDocument doc = (UCRDocument) parts.get(0).getEntity();
        String objectAsJson = IntgUtils.convertObjectToJson(doc);
        try {
                        entity.addPart("UCRDocument", new
StringBody(objectAsJson));
                } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                }
        entity.addPart("Bytes", new ByteArrayBody( (byte[])
parts.get(1).getEntity(), "File"));
        
        post.setEntity(entity);
        return post;
    }



The server resource:

    @POST
    @Path("adddocument")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public UCRDocument addDocument(FormDataMultiPart multipart) throws
Exception {
        UniversalContentRepository repo =
m_connectionFactory.getRepository();

        UCRSession ucrSession =
m_session.getSessionProperty(Session.DOCUMENTS_OBJECTS,
UCRSession.class);
        repo.init(ucrSession); // this is suspect -- it would seem we
need a
                               // repo per user, or do locking
        UCRDocument document =
multipart.getBodyParts().get(0).getEntityAs(UCRDocument.class);
        byte[] data =
multipart.getBodyParts().get(1).getEntityAs(byte[].class);
        
        return repo.addDocument(ucrSession, document, data,
Calendar.getInstance());
    }

Hope the formatting is ok.
Thanks for any help.
--Dave