Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-203

Multipart/form-data request, if no content-type header in part assume it is wildcard "*/*" instead of "text/plain"

    XMLWordPrintable

Details

    Description

      Assume we have the following example:
      A rest service:
      @Path("/rest/multipartform")
      public class FormService {

      @POST
      @Consumes(MediaType.MULTIPART_FORM_DATA)
      @Produces(MediaType.MULTIPART_FORM_DATA)
      public @MultipartForm
      ContainerBean echoMultipartForm(@MultipartForm ContainerBean containerBean)

      { return containerBean; }

      }

      ContainerBean contains only one field which is an other custom type (XmlBean). The problem will be with the field "foo".
      public class ContainerBean {
      @FormParam("foo")
      @PartType(MediaType.APPLICATION_XML)
      private XmlBean foo;

      public XmlBean getFoo()

      { return foo; }

      public void setFoo(XmlBean foo)

      { this.foo = foo; }

      }

      XmlBean is just a simple bean not really important. In the example it will be encoded/decoded as xml.
      @XmlRootElement
      @XmlAccessorType(XmlAccessType.FIELD)
      public class XmlBean {
      private int myInt;
      private String myString;

      public int getMyInt()

      { return myInt; }

      public void setMyInt(int myInt)

      { this.myInt = myInt; }

      public String getMyString()

      { return myString; }

      public void setMyString(String myString)

      { this.myString = myString; }

      }

      We also have a simple html, acting like a client for our service (multipartform.html):
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>MultipartForm test</title>
      </head>
      <body>
      MultipartForm:<br />
      <form action="rest/multipartform" method="post" enctype="multipart/form-data" target="_blank">
      <textarea name="foo" cols="80" rows="10"><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <xmlBean><myInt>26</myInt><myString>Lorem Ipsum</myString></xmlBean></textarea><br />
      <input type="submit" />
      </form>
      </body>
      </html>

      The problem is the following:
      Some clients, like browsers, don't set content-type for every part in a multipart/form-data encoded http post request. They usually only set it for file uploads but not for the other fields.
      Resteasy currently assumes that if no content-type present it is "text/plain". However when binding to a POJO field like in the example ContainerBean's foo field, which has application/xml as PartType set, resteasy fails to convert the post parameter with the following exception:
      org.jboss.resteasy.spi.LoggableFailure: Could not find JAXBContextFinder for media type: text/plain
      at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.findJAXBContext(AbstractJAXBProvider.java:48)
      at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.readFrom(AbstractJAXBProvider.java:64)
      at org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl$PartImpl.getBody(MultipartInputImpl.java:97)
      at org.jboss.resteasy.plugins.providers.multipart.MultipartFormAnnotationReader.setFields(MultipartFormAnnotationReader.java:108)
      at org.jboss.resteasy.plugins.providers.multipart.MultipartFormAnnotationReader.readFrom(MultipartFormAnnotationReader.java:65)
      at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:76)
      at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:93)
      at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:114)
      at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:260)
      at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:232)
      at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:166)

      I guess this is because Resteasy sees that it should convert to XmlBean but can't find a good converter because it searches for one with "text/plain".
      So I made a change in org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl.java in org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl.PartImpl inner class:
      public void endBody(int index)

      { end = index; String mime = headers.getFirst("content-type"); - if (mime == null) mediaType = MediaType.TEXT_PLAIN; + if (mime == null) mediaType = MediaType.WILDCARD_TYPE; else mediaType = MediaType.valueOf(mime); }

      With this small change the above mentioned example starts working. I don't know if this has any impact on the other parts of resteasy but if not I think it would be nice to include this change.

      Attachments

        Issue Links

          Activity

            People

              patriot1burke@gmail.com Bill Burke (Inactive)
              akiraly Attila Király (Inactive)
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: