Thanks, Sergey, for a thorough answer! You got every point right. I
will try to follow suit :)

>> Quick sum-up of the problem:
>> I need to somehow configure a JAX-RS client implemented using CXF's
>> proxy-based client API, to automatically convert parameters annotated
>> with @FormParam to JSON.
>> example code on PasteBin http://www.pastebin.ca/2069097

> Can you clarify please, does the service need to handle form url
> encoded submissions, or have you decided to post name=value sequences
> and use FormParam because you'd like to or may be need to have
> multiple parameters in a resource method signature (such as jsonTest) ?

There is absolutely no need for us to use form encoded submissions; we
have just chosen it for the reasons you suggest (convenience mostly):
1. It allows for arbitrarily long submissions by using POST (although
using GET would probably be more sementically correct. Internet
Explorer 2K GET limit is a show-stopper.)
2. We can use multiple arguments, making it easy to "translate"
existing SOAP based web services.
3. It allows for default values, missing values, and (importantly!)
the possibility of changing the API (by adding more parameters to a
method) without breaking existing clients.
4. WADL

We were especially concerned with (3) when considering using a single
composite object to represent all the parameters for a service, as we
were unsure of what would happen to the deserialization of an object
when fields were missing. This could happen if data were sent from a
client that was developed earlier.

I knew this would work out fine with @FormParam, but quite unsure
about how well the "composite route" would fare in this case. Your
reply nonetheless caused me to play around with the "composite"
approach, and now I see that it is not a problem, as missing fields in
the JSON representation will simply be null when deserialized. That
was a relief, as that means (3) is not an issue. This also opens up
for consuming other content types, such as xml, which is a nice bonus.

Unfortunately, the composite approach makes the WADL quite useless, as
there is no information in it saying what to pass to the service. Any
client developer would have to have either access to the server source
code or a hand written description from the server side developers
describing the legal parameters. Not very attractive ... But maybe you
could enlighten me; is there any way to squeeze out more info than the
following if using the "composite parameter object approach"?
..
<resource path="/oneParam">
     <method name="POST">
        <request>
                <representation mediaType="application/json"/>
        </request>
        <response>
                <representation mediaType="application/json"/>
        </response>
   </method>
</resource>
...

> Also, do you need to use JSON or do you use it because Jackson offers
> a useful Mapper class which can convert a JSON sequence into a complex
> bean.
We need to pass various complex object hierarchies as arguments, and
thus we needed serialization format. JSON was chosen over XML as the
serialization format, due mainly to mobile html5 clients with low
bandwidth.  I was not very pleased with the hackish approach I
described, where I was mixing json-encoded objects and vanilla
string-representations, but it worked - albeit at the expense of
loosing tools based on the common standards.

> Just would like to understand your requirements better. CXF offers an
> extension such as FormParam(""), so you can have
> (@FormParam("myPrimitive") int myPrimitive, @FormParam("") MyObject myComplex)
> but that will work only for plain name/value pairs, but won't when
> values are actually JSON sequences.
Hmm ... You basically mean that if I passed in a string
"myPrimitive=100&foo=abc&bar=def&baz=ghf" in the content body, it
would work? Too bad I need nested objects ... :-(

Reply via email to