Server-side, my implementation manages and stores, for each client,
some kind of "conversation state" information. That "conversation
state" information transits back and forth between the server and the
client within the HTTP response & HTTP Request headers.
Using a com.google.gwt.http.client.RequestBuilder , I can easily
access those headers. They are available to the client.
Now, for an RPC call (com.google.gwt.user.client.rpc.RemoteService) ,
I can't get access to those headers. Google made it so, that all the
low-level details are hidden and unavailable to the client.
I could of course adapt the code myself to get the feature, but think
would be a good idea to include it within standard GWT.
Let me know what you think!
Regards,
Marwan SINGER
When in doubt, you should check the docs, FAQ, Gwt-Web-Toolkit
(non-contributors) group, and Issue Tracker before suggesting features
to the contributors list.
-Ray
I think he's talking client-side, though. getThreadLocalRequest()
only works server-side.
Ian
--
Tired of pop-ups, security holes, and spyware?
Try Firefox: http://www.getfirefox.com
-Ray
considering exposing RPC underlying impelentation usefull (there are
jire enhancement request for that, +1) currently there is design
solution for client/server communication to pass discretional/state
information between requests:
- wrap your DTO object into another object
- DTO should have dedicated field to store discretional information
about state
I've seen pattern being proposed many times on regular group when
discussing how to pass some value between GWT RPC based requests
{"mySharedToken":"GENERATED_TOKEN", "success": true, "MyBeans":
{"MyBean":[......]}, "resultsLength":20.0, "currentPage":5.0}
(sorry for JSON format but it should be easier to see it in quick
shot),
regards,
Peter
-Ray
I'm familiar with what he's talking about from my work with Seam,
which provides conversation support as one of its primary use cases.
The key thing about Seam conversation support is that it is
*declarative*. You can specify methods as being conversational, and
when you invoke those methods, it creates a conversational state
context on the server which affects the runtime state of the
components that service those methods (and subsequent ones invoked on
those components).
Essentially, modern server-side component frameworks such as Seam give
you techniques to define scopes that control the state of those
components, *without* modifying the interfaces of the components
themselves. The state scoping is declared through annotations and
could be considered an "aspect" of the components. Exposing the
conversational state in the interface (e.g. in the payload) breaks
this declarativeness and obfuscates the interface. The necessary
conversational state is logically an out-of-band token in the request/
response flow, exactly like the HTTP session cookie is.
A shorter version of this explanation: the conversation state
shouldn't be in the payload proper for exactly the same reason that
the HTTP session cookie shouldn't be in the payload proper; both of
them are metadata about the server interaction, not actual payload or
interface content.
+1 on the suggestion to make the Request object exposed by issue 535
allow access to (and mutation of) HTTP headers; I would want to use
this in a Seam/GWT integration.
Cheers!
Rob
I'm familiar with what he's talking about from my work with Seam,
On Nov 9, 10:36 am, "Miguel Méndez" <mmen...@google.com> wrote:
> However, the Request object that you get does not allow
> you to set headers and the Response object is not exposed outside of RPC.
>
> What is the nature of the conversation state that prevents you from
> including it in the payload proper?
which provides conversation support as one of its primary use cases.
The key thing about Seam conversation support is that it is
*declarative*. You can specify methods as being conversational, and
when you invoke those methods, it creates a conversational state
context on the server which affects the runtime state of the
components that service those methods (and subsequent ones invoked on
those components).
Essentially, modern server-side component frameworks such as Seam give
you techniques to define scopes that control the state of those
components, *without* modifying the interfaces of the components
themselves. The state scoping is declared through annotations and
could be considered an "aspect" of the components. Exposing the
conversational state in the interface ( e.g. in the payload) breaks
Since this data is pure meta-data, I would like to be able to keep it
out of the business services interfaces.
As for the code/interface samples, I have a couple of ideas that I
could maybe propose, if you'd like, when they are a bit more
structured.
Regards,
Marwan SINGER
Cheers!
Rob
http://robjsoftware.org
I'm all in favor of being able to access/mutate the rpc request
headers. I think this is very important for (eg) security tokens. I am
fundamentally opposed to extending the business interface just to
allow security tokens (or other state) to be passed in.
How about having a listener interface for an RPC call that allows the
client code to access/modify the request before it gets sent to the
server. Perhaps AsynCallback could be extended to support a new method
for this type of interaction, or in the interest of backwards
compatibility, a new interface which extends from AsynCallback?
For example, in order to set a security token of some kind (this is
pseudo-ish code)
ExtendedAsynCallback callback = new ExtendedAsynCallback() {
public void onRequest(Request request) {
request.setHeader("my-security-header", someValue);
}
public void onResponse(Request request, Response response) {
someOtherValue = response.getHeader("someHeaderName");
}
public void onFailure(Throwable t) {
...
}
public void onSuccess(Object o) {
...
}
Or something along those lines.
Cheers,
Richard
Something like mP's idea makes sense to me. Proxies already have state (i.e. ServiceDefTarget), so adding another interface you can optionally cast to, such as ServiceConfig, seems appropriate.
But, yes, this is a separate feature request. A pretty useful one!On Nov 14, 2007 6:23 PM, Miroslav Pokorny <miroslav...@gmail.com> wrote:
First problem adding headers to a request.
Why not make all rpc proxies implement an interface (lets call it RpcProxy) and have that interface define a few methods that help one work with headers eg
addHeader( String name, String value )
The problem with this approach is that proxies are now not stateless.
Second problem getting headers within a response...
Perhaps add an interface that extends AsyncCallback that adds a few methods to get headers from the response.
On Nov 16, 2007 10:34 PM, Bruce Johnson <br...@google.com> wrote:Something like mP's idea makes sense to me. Proxies already have state (i.e. ServiceDefTarget), so adding another interface you can optionally cast to, such as ServiceConfig, seems appropriate.
But, yes, this is a separate feature request. A pretty useful one!On Nov 14, 2007 6:23 PM, Miroslav Pokorny <miroslav...@gmail.com> wrote:
First problem adding headers to a request.
Why not make all rpc proxies implement an interface (lets call it RpcProxy) and have that interface define a few methods that help one work with headers eg
addHeader( String name, String value )
The problem with this approach is that proxies are now not stateless.
Is it sufficient to specify headers that affect all methods on a particular proxy? Or do people have use cases that would require method specific headers?
Second problem getting headers within a response...
Perhaps add an interface that extends AsyncCallback that adds a few methods to get headers from the response.
We would need to expose a new interface that allows the callback to access the response headers. This is one scenario where it would have been nice to have an event object style callback.
On Nov 20, 2007 4:21 AM, Miguel Méndez <mme...@google.com> wrote:Is it sufficient to specify headers that affect all methods on a particular proxy? Or do people have use cases that would require method specific headers?
Well considering that JS is singlethreaded this is not really a problem. Its not a nice elegant solution.
A better option that doesnt break the statelessness of the proxy might be to introduce a new interface or even concrete class.
class/interface Headers
void addHeader( name,value)
void setHeader( name, value).
Iterator iterator()
String[] getHeader( name );
If the 2nd last parameter of the method is a Header something special happens.
last parameter - AsyncCallback
if 2nd last parameter is a Header - The headers inside the Header are read and added to the request. In this case 0 to last -2 are actual method parameters.
else 0 to last - 1 are actual method parameters.
Second problem getting headers within a response...
Perhaps add an interface that extends AsyncCallback that adds a few methods to get headers from the response.
We would need to expose a new interface that allows the callback to access the response headers. This is one scenario where it would have been nice to have an event object style callback.
My idea was to create a new interface that called XYZ. This new interface would have methods to set / add the return status code / headers etc. If the callback parameter passed to the method implemented XYZ then the proxy would do the cast and record the headers.
Or one could create a new interface that extends AsyncCallback which contains extra methods to set/add the return status code / headers and so on.
public abstract class ResponseMetadata<T> {
public abstract Request getRequest();
public abstract Response getResponse();
public abstract T getResult();
}
request.addHeader ("conversation-context", context.toString());
What is the meaning of AsyncCallback<ResponseMetadata<List<MyItems>>>?
My understanding was that a Java 1.5-enabled GWT would parameterize
the AsyncCallback by the expected return type so that onSuccess()
could receive an object of that type, rather than of type Object. Is
it a nod to backwards compatibility to throw a ResponseMetadata into
the type parameterization? If so, it seems easier to me as a user of
the API to modify the RPC generators to acknowledge two types of
client-side interface that accept either the old style (with no
response metadata) or a new style where AsyncCallback is something
like this:
public interface AsyncCallback2<T> {
void onFailure(Throwable t); // as before
void onSuccess(T result, ResponseMetadata meta);
}
Perhaps AsyncCallback2 is a terrible name, but my point is that a
hairy type parameterization seems painful and I'd rather solve the
backwards compatibility issue a different way (assuming that the hairy
type parameterization has anything to do with compatibility).
proxy.invokeService(arguments, new
AsyncCallback<ResponseMetadata<List<MyItems>>>() {
public void onFailure(Throwable t) {
// whatever
}
public void onSuccess(ResponseMetadata<List<MyItems>> result) {
// retrieve headers, etc. directly from result
// obviously we'd need a good name here, rather than some
spur-of-the-moment thing
List<MyItems> realResult = result.getRealResult();
}
});
What would you do with server-side actions that result in onFailure()
being called? Is there a way to let the onFailure method inspect
response headers and so on? Would it make any sense for an RPC method
to do things like return a 403 Not Authorized by throwing an
exception? Does anyone care about headers in the failure case? If
people care about headers in the failure case, what do you do about
failures that are so early as not to have a response object?
So I assume the "expected" interface would work as expected: same as
GWT 1.4, but a typesafe onSuccess().
How do you imagine the
ResponseMetadata-enhanced version working? Would it be something like
this?
proxy.invokeService(arguments, new
AsyncCallback<ResponseMetadata<List<MyItems>>>() {
// whatever
public void onFailure(Throwable t) {
}
public void onSuccess(ResponseMetadata<List<MyItems>> result) {
// retrieve headers, etc. directly from result
// obviously we'd need a good name here, rather than some
spur-of-the-moment thing
List<MyItems> realResult = result.getRealResult();
}
});
What would you do with server-side actions that result in onFailure()
being called?
Is there a way to let the onFailure method inspect
response headers and so on?
Would it make any sense for an RPC method
to do things like return a 403 Not Authorized by throwing an
exception? Does anyone care about headers in the failure case? If
people care about headers in the failure case, what do you do about
failures that are so early as not to have a response object?