users@jersey.java.net

Re: Multiple parameters to resource methods

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 18 Apr 2008 15:45:29 +0200

Hi Martin,

Martin Probst wrote:
> Hi,
>
> first: I'm new to this list, so hello everyone. I'm just starting with
> Jersey, but I like it a lot so far, so thanks for this nice tool :-)
>

Welcome, and thanks :-)


> next: I'm aware that this question has been asked before, but it didn't
> really receive an answer, or at least none that I'd like (or I missed
> it, in which case I apologize).
>

Does the email i sent recently help in any matter:

https://jersey.dev.java.net/servlets/ReadMsg?list=users&msgNo=1057

?

If we could support forms beans say as follows:

   @Form
   public class FormBean {
      // Parameter "a"
      String a;

      // Parameter "b"
      String b;

      // Parameter "c"
      JAXBBean c;
   }

and have a message body reader like:

   @ProduceMime({"application/x-www-form-encoded", "multipart/form"})
   public class FormReader implements MessageBodyReader<Object> {
      // Get access to other readers/writers for handling
      // form bean properties (type, generic type and annotations)
      @Context MessageBodyWorkers mbw;

      boolean isReadable(
          Class<?> type,
          Type genericType,
          Annotation annotations[]) {
        return type.getAnnotation(Form.class) != null;
      }

     public Object readFrom(
          Class<Object> type,
          Type genericType,
          MediaType mediaType,
          Annotation annotations[],
          MultivaluedMap<String, String> httpHeaders,
          InputStream entityStream) throws IOException {

       // Use bean reflection API on class to get bean properties
       // and annotations, get message body reader for each property
     }

   }

then we can support forms rather nicely with the current model:

    @POST String form(FormBean f) {
      ...
    }

The next step is to add a different resource method dispatcher to Jersey
(we did a similar trick for prototyping Comet support and using Scala's
closures for prototyping better precondition support) to handle
unwrapped form parameters, essentially the form parameters are
equivalent to bean properties so we can have another message body reader
that utilizes the same logic as the for form beans:

    // This method assumes that the request entity is of
    // the type "application/x-www-form-encoded" or
    // "multipart/form"
    @POST String form(
         @FormParam("a") String a,
         @FormParam("b") String b
         @FormParam("c") JAXBBean c) {
      ...
    }

The method signatures for form-based processing will be matched if there
is one or more parameters annotated with @FormParam and there is no
unannotated parameter.

Thus I don't think it is necessary to modify the existing interfaces. I
think we can support all this with the existing infrastructure in a
pluggable manner.

Does that seem like a sensible approach to you?


As i said before i think the biggest hurdle is non-technical and it is
about getting the time to implement it :-) anybody want to have a go? If
so i can send more details on the resource method dispatching logic, as
it is not well documented.

Paul.

> Would it be possible to allow MessageBodyReaders to produce not only a
> single parameter, but a set of parameters for a method call, so that
> single resource methods could take e.g. multiple named parameters from a
> form POST as application/x-www-form-encoded?
>
> I'd think of something like this:
> Replace in MessageBodyReader<T>:
> T readFrom(Class<T> type, Type genericType, MediaType mediaType,
> Annotation annotations[],
> MultivaluedMap<String, String> httpHeaders,
> InputStream entityStream) throws IOException;
> with:
> Object[] readFrom(Class<T>[] types, Type[] genericTypes, MediaType
> mediaType,
> Annotation annotations[],
> MultivaluedMap<String, String> httpHeaders,
> InputStream entityStream) throws IOException;
>
> So that MessageBodyReader could inspect the types, find those types that
> have names fitting - for example - the method parameter names with the
> form values, and set those accordingly?
>
> The problem is of course that this reflection is somewhat costly and you
> ideally wouldn't want to do this every time. So maybe we could
> instantiate one message body reader for each method that has multiple
> parameters and set that up to read messages for this method properly.
>
> Alternatively you could create a holder class for each form submission
> and either create a separate MIME type for each different form you have,
> associate the MessageBodyReaders with certain URIs to produce different
> classes from the same MIME type, but that seems wrong.
>
> Best regards,
> Martin
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109