Hi

Some quick & dirty testing shows that doing a transparent read & reset
on the InputStream before wrapping it in a GWTObjectInputStream (using
iterator semantics) does actually let you access the parameters in
series.

great...


I see your point about the API and the annotations. I'm mildly
annotation-phobic so have preferred the XML configuration approach to
date along these lines:

<resource name="com.myservice.cxf.gwt.server.JaxRsGwtServiceImpl" path="/">
   <operation name="processGwt" verb="POST" path="/processGwt"
       consumes="text/x-gwt-rpc;charset=utf-8"
produces="text/x-gwt-rpc;charset=utf-8">
       <param name="username" type="REQUEST_BODY" />
       <param name="password" type="REQUEST_BODY" />
   </operation>
</resource>

Sounds good... As I said, I'll ensure this works even after CXF JAXRS gets more restrictive by letting users to set some new jaxrs:property. But note that you can replace "REQUEST_BODY" with "QUERY" if you decide to try to override the REQUEST_URI so you won't need to add the annotations...


I'll have a go at overriding the REQUEST_URI mapping - any chance you
can post a link to an example in the documentation?

Not really, but it is something along these lines (assuming it is done in the 
request filter) :

String requestURI = (String)message.get(Message.REQUEST_URI);
// parse the sequence
requestURI += "?" + "username=" + someValue...
message.put(Message.REQUEST_URI, requestURI);


Having not looked
at the way the URI parameters are stored, does the approach you've
suggested come unstuck if the payload represents non-String,
potentially complex objects? Or is a Map involved (which solves the
problem)?

ParameterHandlers can handle complex (query) values, please check

http://cxf.apache.org/docs/jax-rs.html#JAX-RS-DealingwithParameters

cheers, Sergey


I anyone's been following this thread I have posted the code I've
knocked up (in a hurry) so far at pastebin:

GWTRequestHandler.java http://pastebin.com/f66e8e3ce
GWTIterableObjectInputStream.java http://pastebin.com/f6b97cbe8
GWTMessageBodyReader.java http://pastebin.com/fafcb133

Cheers

Mike

On 8 February 2010 16:33, Sergey Beryozkin <sbery...@progress.com> wrote:
Hi Michael

Introducing the Iterable InputStream impl should also work, sounds like a
neat idea... but the runtime itself will unlikely use it itself, you'd need
to check in MessageBodyReader.readFrom().

As far as JAXRS is concerned, the portable approach is not to have more than
one method parameter which is assumed to represent a request body as opposed
to request parameters. Ex,

public String greetServer(String greeting, String subject);

may not be recognized as a JAXRS resource method, while

public String greetServer(@PathParam("1") String greeting, String subject);

or

public String greetServer(@PathParam("1") String greeting, @PathParam("2")
String subject);

would be accepted. CXF JAXRS server runtime is lenient here but the client
(proxy) code will report a failure. The server runtime will eventually
become more restrictive too but I will introduce a property which will let
users to continue working with method signatures like the one used in your
case.

Thus, perhaps another idea, instead of relying on a MessageBodyReader is to
do annotate the method like this :

public String greetServer(@QueryParam("1") String greeting, @QueryParam("2")
String subject);

and then in a request filter, to override a Message.REQUEST_URI, ex, given
the sequence below and the request uri

/myservice/remote/service/path

you can override the Message.REQUEST_URI like this :

/myservice/remote/service/path?1=hello&2=world

one possible advantage of this approach is that non GWT clients will also be
able to invoke on the same method...

what do you think...I'd be interested to know which approach works for you
best

cheers, Sergey

Hi Sergey,

I've mocked up something which produces a similar output to the
payload referred to in the linked page (see older post). The HTTP
request, Java service interface and the relevant parts of the web.xml
appear below:

POST /myservice/remote/service/path HTTP/1.1

Host: 127.0.0.1:8888

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.4)
Gecko/20091016 Firefox/3.5.4

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-us,en;q=0.5

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Connection: keep-alive

X-GWT-Permutation: HostedMode

X-GWT-Module-Base: http://127.0.0.1:8888/myservice/

Content-Type: text/x-gwt-rpc; charset=utf-8

Referer: http://127.0.0.1:8888/myservice/hosted.html?myservice

Content-Length: 189

Pragma: no-cache

Cache-Control: no-cache



5|0|7|http://127.0.0.1:8888/myservice/|0EBF8645C6C142BAE05961AFDE515F13|com.myservice.gwttest.client.GreetingService|greetServer|java.lang.String/2004016611|hello|world|1|2|3|4|2|5|5|6|7|

----------------------8<-----------------------

package com.myservice.gwttest.client;


public interface GreetingService extends RemoteService {

public String greetServer(String greeting, String subject);

}

----------------------8<-----------------------

<web-app>

<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.myservice.gwttest.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/remote/service/path</url-pattern>
</servlet-mapping>

</web-app>

----------------------8<-----------------------

I'm sorry but I haven't really had time to think about your proposed
solutions. Just extemporizing briefly, what do you think of wrapping
the InputStream of the message (as per your suggestion) in some sort
of parameter-aware, Iterable InputStream? The parsing would be done at
construction time after which it could reset itself for reading by
other components. The additional methods it could provide may then be:

boolean hasNextParameter();
Object nextParameter();

You could avoid having to track the index or use a thread-local Map that
way.

Cheers

Mike



On 5 February 2010 17:08, Sergey Beryozkin <sergey.beryoz...@iona.com>
wrote:

Hi

Sorry, was about to reply earlier on....

That is a useful link indeed. Can you please let me know how does the the
method signature look like ?
I'd like to understand how a GWT RPC sequence is supposed to mapped to a
real method....Then we can see what is the best option is...

Perhaps one option is to replace an incoming InputStream with the
ByteArrayInputStream on the incoming message from a custom CXF JAXRS
filter,
given that the sequences seem to be quite small :

ByteArrayInputStream bos =
IOUtils.loadIntoBais(message.getContent(InputStream.class))
message.setContent(bos);

Next build some sort of the map by passing this stream and set it as a
message property, say message.put("gwt.map", map);

this all can be done in a filter.

Next your message reader can have a CXF @MessageContext injected and you
can
get the map out of it.
Finally, in readFrom(), you can try to retrieve the value, perhaps using
some of the readFrom parameters ?

If needed you can also have a thread local map which will be used to
increment the parameters index ?

If you could post the sample method signature then it would help

cheers, Sergey


Michael Guyver-3 wrote:

Hi everyone,

I've been having a closer look at how to implement a MessageBodyReader
for the GWT RPC protocol, and while I'm aware of a JSON-related
project (http://hiramchirino.com/blog/tag/json/), it's not a solution
for GWT-RPC.

I'm a relative GWT noob but I think you gain much greater type-safety
from using the GWT-RPC mechanism over JSON as your application
receives the strongly-typed response object from your remote service,
possibly replete with methods to afford encapsulation, rather than
just some opaque data-only JavaScriptObject. Perhaps someone can set
me straight here?

The problem so far as implementing a MessageBodyReader is, as I see
it, that the GWT RPC protocol describes its payload types and values
in a non-sequential way. This is summarised in a very helpful article
here (search for the string "This is where the Payload gets a little
more interesting" to get to the payload section):

http://www.gdssecurity.com/l/b/2009/10/08/gwt-rpc-in-a-nutshell/

I anticipate that the initial part of the payload can be disregarded
as it contains routing information for the RemoteServiceServlet,
contrary to the routing for JAX-RS where it is derived from the path
itself - /path/to/my/service. The data-portion of the payload is the
bit that's important, but I don't see that it is amenable to
sequential processing as per the normal operation of the JAXRS call
stack:

JAXRSInInterceptor.processRequest(Message): 78
JAXRSUtils.processParameters(OperationResourceInfo,MultivaluedMap<String,
String>,Message): 502

JAXRSUtils.processParameter(Class<?>,Type,Annotation[],Parameter,MultivaluedMap<String,
String>,Message,OperationResourceInfo): 538

JAXRSUtils.readFromMessageBody(Class<T>,Type,Annotation[],InputStream,MediaType,List<MediaType>,Message):
933

MessageBodyReader.readFrom(Class,Type,Annotation[],MediaType,MultivaluedMap<String,
String>,InputStream)

It's even unfortunate that a parameter index is not passed to the
MessageBodyReader, so you could suffer the cost of parsing the payload
on each invocation. As almost all of these methods are static there's
no chance of introducing a custom processor - unless I've missed
something?

Is there a way of hooking into the request processing system such that
you can return a parameter Object[] from the request body rather than
being invoked as if the payload were a nicely sequential stream? Can
anyone suggest an approach to this problem?

Cheers

Mike

On 19 January 2010 00:09, Michael Guyver <michael.guy...@gmail.com>
wrote:

Hi there,

This is a borderline hypothetical question - but say I had a GWT
application
that existed within a custom static HTML/Velocity/Trimpath/Spring MVC
application and I wanted to have GWT's AJAX requests handled by the CXF
JAXRS implementation, how would I go about parsing and writing GWT-JSON
(IIRC it's worlds apart from "normal" JSON). Would you create some sort
of
MessageBodyReader and MessageBodyWriter implementation analogous to the
AbstractJAXBProvider?

Cheers

Mike




--
View this message in context:
http://old.nabble.com/GWT-service-from-CXF--tp27218968p27470896.html
Sent from the cxf-user mailing list archive at Nabble.com.





Reply via email to