Joe,
thx for looking into this! I moved this thread to the dev list since implementing this feature will require some changes to dwr.
Yes, extending DefaultRemoter to allow defining a list of 'ignored' types seems to be the best solution. Since there is an obvious tie between ignored classes and a correctly registered corresponding converter I wonder whether an additional interface for converters would make sense, something like:
public interface ContextConverter {
void Class[] getContextTypes();
}
Not sure about the naming yet, the idea is that these values are not part of the RPC but make up the execution context of the method. This assumes that ServletConverter is usually used to retrieve values like locale, current user, user settings etc.
DefaultRemoter could query ConverterManager to get a list of all types defined by converters implementing this interface. Those type will not be exposed in the Javascript client interface (and use fake parameters as it is implemented now). This would also require a change to the ConverterManager interface.
What do you think?
I have also considered a solution that would omit fake parameters on the client side completely, by altering BaseMarshaller to reflect such server side generated parameters during binding. But the concept of 1:1 mapping of method signatures between client side and server side affects large parts of the code, and the feature is probably not important enough to justify a greater code change.
I will code my changes against the HEAD, I guess.
I'd appreciate any feedback,
Werner
On 6/8/07, Joe Walker <joe@...> wrote:
Hi,
Sorry for the slow reply.
I think that the easy solution is to create a UserContextConverter which uses the techniques demonstrated in ServletConverter to get access to the HttpServletRequest from which a UserContext object can be created and returned.
From the JS POV, you would just pass in 'null' in place of a UserContext, and the converter would 'convert' null to a valid object.
You could alter DefaultRemoter to use something other than
LocalUtil.isServletClass() to get the 'ignored classes'.
Joe.
On 5/30/07, werner loibl <welo.fpw9@...> wrote:
Hi,
I would like to provide a mechanism similar to the one currently implemented in dwr that allows adding
javax.servlet.http.* types (such as HttpServletRequest) as part of the method signature of a service. The current feature will pass the current request, response, etc in case the method signature defines the equivalent type.
I intend to define a UserContext type that allows querying the current user and other information on the execution context. Dwr should implicitly create a UserContext object if the method signature defines an argument of this type. Though this will actually be retrieved via the HttpServletRequest resp. HttpSession I want to decouple the service implementation from the
javax.servlet API. This is to ease testing and to allow creating an API layer that is not tied to the servlet spec. (To be honest, I'm not absolutely sure whether this will work out or not, or will make sense in the end, but I have a good feeling about it ;) ).
Taking a look at ServletConverter and DefaultRemoter it seems that this behaviour is currently hard-wired in dwr. Whereas it is possible to define a Converter that will create the required UserContext object based on the current HttpServletRequest (that can be retrieved from the ThreadLocal WebContext attribute as done by ServletConverter), the DefaultRemoter does not allow extending this behaviour easily. DefaultRemoter will add a dummy variable (with value=false) for every
javax.servlet.http type encountered when creating the Javascript service wrapper, but this behaviour is hard-wired and not extensible (see DefaultRemoter#getMethodJS, which is private). The dummy variable is required otherwise BaseCallMarshaller#findMethod will not find the correct service method since the number of arguments of the ajax call does not match the number of method parameters on the service bean.
Other solutions I came up with so far:
* Create a wrapping layer around my services that will do the conversion and delegate to the service bean passing the created UserContext. This might be automated by using a custom Spring proxy.
* Use a ThreadLocal to hold the SessionContext and use a custom AjaxFilter to create and bind the UserContext.
However, I would prefer to extend the dwr binding since it naturally belongs there IMHO.
I would like to hear the opinion of a dwr developer whether this can be accomplished in a different way, and whether this feature makes sense from a conceptual point of view.
Thx for your help and feedback!
Werner