You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@ws.apache.org by Adam Bennett <ad...@videx.com> on 2006/05/11 00:14:46 UTC

Does this library provide a request context?

I've got the server and client example code working, (the Calculator),
and I enhanced it to use HTTP basic authentication.  The next thing I
need is for the server to know which user is making the request.  For
example, on the server we have:
 
package videx;
 
public class Calculator
{
  public int add(int i1, int i2)
  {
    return i1 + i2;
  }
 
  public int subtract(int i1, int i2)
  {
    return i1 - i2;
  }
}
 
But instead lets say the result of the subtract() method depends upon
the user who is making the call.  That is, the user supplied during the
authentication process.  I know that if I can get the HttpServletRequest
object then I can query it for this information, but how do I get at it?
Is this possible with this library?

The real need for this steams from the fact that each user has a
different view of the data in our database and thus the response will be
different for each user.

Thanks for your help on this.
- Adam


This message has been scanned by Symantec Mail Security for SMTP.

Re: Does this library provide a request context?

Posted by Adam Taft <ad...@hydroblaster.com>.
Adam,

I use an older version of the library (v 1.2-b1), so what I do might not 
be the most accurate with the latest version (though I assume it's 
practically the same).

The basic authentication credentials are available by implementing the 
AuthenticatedXmlRpcHandler interface (or ContextXmlRpcHandler) in your 
handler class.  So, if your handler class implements this interface, the 
execute method will be called with the client's username and password 
from the basic authentication.

 From there, it's just a matter of looking up and validating the 
credentials, matching it up to a user session, etc.  I basically keep 
some User objects cached in a Map, keyed off of the username and 
password.  Or, you could just go straight to the database to lookup the 
user each request.

Now, the interesting thing with this approach is that your public 
methods in your handler class are now not "exposed" to the client.  When 
you implement one of the XmlRpcHandler interfaces, the class isn't 
introspected for public methods.  What you can do though is call the 
Invoker class which will then do the reflection just like the 
non-implementing "basic" handler class would.

So, your calculator class might look something like this (note, I didn't 
compile this, just typing off the top of my head):


public class Calculator implements AuthenticatedXmlRpcHandler {
	
	// needed to store the current user in a thread safe way
	private ThreadLocal<User> userThreadLocal = new ThreadLocal<User>();


	public Object execute(String method, Vector params, String username, 
String password) throws Exception {

		// check username and password and store it
		User user = getUser(username, password);
		userThreadLocal.set(user);
		
		// use the Invoker on this class.
		Invoker invoker = new Invoker(this);
		Object obj = invoker.execute(method, params);

		return obj;
	}

	public int add(int i1, int i2) {
		// check the user
		User user = userThreadLocal.get();
		user.checkSomeProperty();
		return i1 + i2;
	}

	public int subtract(int i1, int i2) {
		return i1 - i2;
	}
}

Obviously, in the example above, you'll need a supporting User class.  I 
also end up storing the user in a ThreadLocal (as you can see), so that 
the methods (add, subtract) can get to the user object and change the 
behavior of the method based on it.  I tried to demonstrate this above.

Hope this helps.


Adam Bennett wrote:
> I've got the server and client example code working, (the Calculator),
> and I enhanced it to use HTTP basic authentication.  The next thing I
> need is for the server to know which user is making the request.  For
> example, on the server we have:
>  
> package videx;
>  
> public class Calculator
> {
>   public int add(int i1, int i2)
>   {
>     return i1 + i2;
>   }
>  
>   public int subtract(int i1, int i2)
>   {
>     return i1 - i2;
>   }
> }
>  
> But instead lets say the result of the subtract() method depends upon
> the user who is making the call.  That is, the user supplied during the
> authentication process.  I know that if I can get the HttpServletRequest
> object then I can query it for this information, but how do I get at it?
> Is this possible with this library?
> 
> The real need for this steams from the fact that each user has a
> different view of the data in our database and thus the response will be
> different for each user.
> 
> Thanks for your help on this.
> - Adam
> 
> 
> This message has been scanned by Symantec Mail Security for SMTP.
>