使用Jersey为RESTful Web服务进行会话管理

6
我正在开发一个使用Jersey构建的Restful Web Service,用于连接我的Android、iPhone应用和MySQL数据库。我还使用Hibernate将数据映射到数据库中。
我有一个sessionId(键),它在用户登录系统时生成。
在User类中:
public Session daoCreateSession() {
    if (session == null) {
        session = new Session(this);
    } else {
        session.daoUpdate();
    }
    return session;
}

在Session类中:
Session(User user) {
    this.key = UUID.randomUUID().toString();
    this.user = user;
    this.date = new Date();
}

void daoUpdate() {
    this.key = UUID.randomUUID().toString();
    this.date = new Date();
}

当用户成功登录系统后,我会将该sessionId发送给移动应用程序客户端。然后,当我想要根据已登录用户从数据库获取一些信息时,我会在每个请求中使用Session key作为身份验证在REST服务中进行检查。
例如,对于用户参与的项目列表,我使用client.GET(SERVER_ADDRESS/project/get/{SessionID})而不是client.GET(SERVER_ADDRESS/project/get/{username})
如果它不是有效的会话密钥,我将向客户端发送403禁止代码。您也可以在此处查看。
问题是我不确定我的方法是否正确。考虑到Jersey和移动应用程序,您认为这种方法的缺点如何?我仍然不知道在我的情况下Session key方法是否是一个好主意。

这不是RESTful的。SessionID会改变,因此您的URL将不会引用资源。 - user647772
为什么?我只是使用这种方法 - Ali
一个URL标识着一个资源。你的资源是什么? - user647772
不,MySQL是你的后端。在你的上下文中,项目和用户是资源。请阅读REST简介 - user647772
好的,谢谢,你是对的,但你已经知道了问题的答案 :) - Ali
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/16186/discussion-between-ali-and-tichodroma - Ali
2个回答

6

如果您想使用 SessionId,则应设置验证时间,如下所示:

private static final int MINUTES = 90;

public boolean isValid() {
   return System.currentTimeMillis() - date.getTime() < 1000 * 60 * MINUTES;
}

4
这是一个已解决的问题 - 类似Tomcat的servlet容器已经进行了会话管理,并且可以通过TCP广播或使用共享数据源(如memcache)将会话状态分配给集群中的其他容器。
我建议您阅读一下已有的内容,而不是无意中重复造轮子。此外,如果您的应用程序变得受欢迎,这将成为一个非常热门的话题。您将如何清除旧的会话ID?

每次用户登录系统时,都会生成一个新的会话ID。此外,这是一个临时ID,在一段时间后会过期。 - Ali
如果您期望高负载,那么每个请求都需要在同一张表上执行操作是不好的。每次登录都需要写入,每次其他操作都需要读取一个大表,该表无法有效地进行索引(UUID对此很差),然后您将需要一个后台线程来扫描表并删除过期的会话ID,否则表将填满无用数据。我真的建议您考虑使用Tomcat内置的会话管理,支持http://code.google.com/p/memcached-session-manager。 - DeejUK
他实际上正在为无会话请求创建一个令牌系统。 - Brill Pappin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接