dev@jsr311.java.net

Re: JSR311: POSTed form data

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 15 Feb 2008 17:50:01 +0100

Marc Hadley wrote:
> What Bill suggests would require expanding the targets of the @*Param
> annotations. They are currently only allowed on parameters. If we did
> that we could support something like:
>
> @Path("foo")
> @ConsumeMime("application/x-www-form-urlencoded")
> public class Foo {
>
> @FormParam("name") String name;
> @FormParam("rank") String rank;
> @FormParam("serial") int serial;
>
> @POST
> public void register() {
> // do something with name, rank, serial
> }
> }
>
> Essentially the resource class is also the form bean suggested by Paul.
>

I was not suggesting the resource class becomes a bean i was suggesting
a separate bean be used for the form data, like the following:

@Form // An annotation!!!
public class MyForm {
   String name;
   String rank;
   int serial;
   MultivaluedMap<String, String> otherStuff;
}

public class Foo {
   @POST
   public void register(MyForm form) {
     // do something with name, rank, serial
   }
}

@Provider
@ConsumeMime("application/x-www-form-urlencoded")
public FormReader implements MessageBodyReader<Object> {
    public boolean isReadable(Class<?> type) {
      return type.getAnnotation(Form.class) != null;
    }

    ...
}

@Provider
@ConsumeMime("multipart/form-data")
public FormReader implements MessageBodyReader<Object> {
    public boolean isReadable(Class<?> type) {
      return type.getAnnotation(Form.class) != null;
    }

    ...
}

This fits nicely into the model we already have for entities without any
confusion over the overloading of @QueryParam and can work with both
form media types and requires no changes or additions to the current
@*Param annotations. And it can almost be done today with the existing
API. It can be done with Jersey by an external developer because it is
possible to inject onto a MessageBodyReader a context class to get
another reader or writer given a media type and Java type (say for
example if JSON or XML is a content part of a multipart/form).

I think it would be best to get a good pluggable design for processing
forms first, then consider whether it is worthwhile to unwrap the fields
as parameters of the HTTP method or the inverse to consider a bean that
acts the same as method parameters. Those bring along a whole set of
other problems where as the use of a Form bean is isolated to the
particular problem of forms themselves.

Paul.

> Marc.
>
> On Feb 15, 2008, at 9:35 AM, Bill Burke wrote:
>
>>
>>
>> Paul Sandoz wrote:
>>> Hi Marc,
>>> So far the @*Param concept has been associated with the HTTP
>>> meta-data and not that of the entity so it might create some
>>> confusion (like you highlighted when overloading @QueryParam for form
>>> parameters).
>>> What happens if the developer specified the following:
>>> @POST @ConsumeMime("application/x-www-form-urlencoded")
>>> public Foo update(@QueryParam("name") String name, String formData)
>>> ?
>>> My ideal preference would be for a way to unify the processing of the
>>> media types "application/x-www-form-urlencoded" and
>>> "multipart/form-data"
>>
>>
>> I think we should explore this idea further for complex cases, but, I
>> still think we need an "ease-of-use" @*Param annotation. I know we
>> all have found a simple way to get parameters very useful when writing
>> Servlets the same should be available for JAX-RS.
>>
>>
>> [1] using a Java bean that is the entity, for
>>> example:
>>> // The Form interface is a marker for message body readers/writers
>>> public MyForm implements Form {
>>> public String name;
>>> public InputStream uploadedFile.
>>> }
>>
>> We don't need "marker" interfaces anymore. We have annotations :)
>>
>>> and allow for:
>>> @POST @ConsumeMime({"application/x-www-form-urlencoded",
>>> "multipart/form-data"})
>>> public Foo update(MyForm form)
>>> From this we could consider what it means to specify unwrapped form
>>> parameters in a way that does not clash with the concept of the
>>> entity parameter already specified.
>>
>> Instead of a form specific approach, why not expand this to all
>> injection types? i.e.
>>
>> @Mapped
>> public class MyBean {
>>
>> private @HeaderParam("foo") int foo;
>> public void setSessionId(@CookieParam("sessionid") int sessionId) {...}
>>
>> private @Param("file") InputStream file;
>> }
>>
>> --
>> Bill Burke
>> JBoss, a division of Red Hat
>> http://bill.burkecentral.com
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>>
>
> ---
> Marc Hadley <marc.hadley at sun.com>
> CTO Office, Sun Microsystems.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>

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