JAXWS和会话

时间:2010-05-01 23:41:55

标签: java web-services soap session jax-ws

我很擅长编写Web服务。我正在使用JAXWS开发SOAP服务。我希望能够让用户登录并在我的服务中知道哪个用户正在发出命令。换句话说,有一些会话处理。

我看到这样做的一种方法是使用cookie并从我的Web服务访问HTTP层。但是,这依赖于使用HTTP作为传输层(我知道HTTP几乎总是传输层,但我是纯粹的)。

是否有更好的方法可以使服务层不知道传输层?有没有办法用servlet过滤器实现这个目的?我希望答案尽可能与框架无关。

2 个答案:

答案 0 :(得分:5)

  

我正在使用JAXWS开发SOAP服务。我希望能够让用户登录并在我的服务中知道哪个用户正在发出命令。换句话说,有一些会话处理。

传统的Web服务本质上是无状态的,Web服务中没有会话处理(据说与识别调用者没有任何关系)。

如果您要求对您的用户进行身份验证以呼叫服务,则传统方法是:

  1. 公开返回身份验证令牌的“身份验证”Web服务(传递用户凭据)。
  2. 让用户先调用此身份验证。
  3. 让用户在后续“业务”Web服务调用中在自定义标头中传递令牌。
  4. 在服务器端:

    1. 拒绝任何不包含有效令牌的电话。
    2. 在一段时间不活动后使令牌失效
    3. 您可以为此方法实施自定义解决方案(这是一种高度可互操作的解决方案)。或者您可以使用WS-Security / UsernameTokens提供开箱即用的类似内容。 WS-Security是一个标准(Metro实现它),它不是“框架”特定的。

答案 1 :(得分:1)

正如您所提到的,servlet过滤器可以提供解决方案的基础。使用过滤器将当前会话详细信息(例如会话上下文映射)存储在threadLocal存储中。这是作为您的应用程序类实现的,因此与传输无关。您的服务只是使用静态方法来获取当前上下文,而不知道它来自何处。

E.g。

class ServiceSessionContext
{
    static ThreadLocal<Map> local = new ThreadLocal<Map>();

    // context set by the transport layer, e.g. servlet filter
    static public void setContext(Map map)
    {
        local.put(map);
    }

    // called when request is complete
    static public void clearContext()
    {
        local.put(null);
    }

    // context fetched by the service
    static public Map getContext()
    {
        return local.get();
    }
}