dev@jsr311.java.net

Re: ProduceMime and ConsumeMime

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 09 Apr 2007 09:32:28 +0200

On Apr 7, 2007, at 7:21 AM, Dhanji R. Prasanna wrote:

>
>
> On 4/7/07, Marc Hadley <Marc.Hadley_at_sun.com> wrote:
> On Apr 6, 2007, at 3:59 AM, Jerome Louvel wrote:
> Naming is always tricky. One thing I'd like to maintain is the
> ability to specify the (possibly different) types of consumed and
> produced entities at the class level since that reduces the number of
> annotations you need on each method.
>
> I thought that the annotation on the entity parameter was a good
> way to indicate consumption type.
> Btw, will this JSR be able to take advantage of JSR 308 to do
> something like:
>
> @HttpMethod
> public Representation<@MediaType("text/xml") String> getString
> (@MediaType("text/raw") String text) {
> //...
> }
>
>
>
>
> Marc, I also like your idea of tagging classes with "global"
> mimetypes, I certainly think there is a case for that to reduce
> verbosity.
> I would encourage different names at the class level though, to
> dispel confusion about annotations appearing in several places.
>

It is not uncommon for annotations to be reused as long the reuse is
reasonably intuitive and clearly specified e.g. see the EE5 Resource
annotation.

That i why the names of the annotation are Consume/ProduceMime
(although Consume/ProduceMedia would be better). If a POJO that is a
resource is annotated it says that all HTTP methods of that resource
are capable of consuming or producing the media types declared by
those annotations. The annotations on the method override those of
the class.

Note that these annotations do not have a direct correspondence with
a media type that is used as a Content-Type. The closest analogy is
the list of media type of Accept i.e. it is much more general and
fits well with the static nature of annotation declarations.

Perhaps a slightly contrived example will help explain the rational.
Consider an image conversion service. A client POSTs an image and
requests it to be converted to a different image format.

@UriTemplate("imcon")
@ConsumeMime("image/*, application/octet-stream")
@ProduceMime("image/*")
public class ImConReosurce {

     @HttpMethod
     Representation<InputStream> postToConvert(
         Entity<InputStream> image) {
         ...
     }

     @UriTemplate("lastConverted")
     @HttpMethod
     Representation<InputStream> getLastConverted() {
         ...
     }

     @UriTemplate("numberConverted")
     @HttpMethod
     @ProduceMime("text/plain")
     String getNumberConverted() {
         ...
     }
}

A client could POST a request containing an image using known image
media type or the client may not know what it is, and uses
application/octet-stream. The client can via the Accept header inform
the service of the image media types it prefers for the returned
representation. In such cases the postToConvert method will get
invoked. The impl of the postToConvert method can get access to the
ordered list of media type in the Accept header (using a method on
the HttpRequestContext, this method parses the Accept header and
sorts the media types according to the q parameter).

There is a sub-method annotated with the URI template "lastConverted"
that returns the image that was last converted (so the URI path would
be "imcon/lastConverted"). This method inherits the ConsumeMime/
ProduceMime annotations from the class.

There is a sub-method annotated with the URI template
"numberConverted" that returns the number of images that have been
converted, as a number in lexical form. This produces the text/plain
media type and overrides that which is declared to be produced by the
class.

Hope this further explains the rational behind Consume/ProduceMime,
Paul.