2012-04-19 38 views
5

我正在使用Scalatra框架来构建一个Web应用程序。 应用程序依赖于会话,但我不能使用会话cookie(因为技术上只有一个用户同时运行多个会话)。没有cookies的Scalatra会话

每个会话都有一个唯一的会话密钥,我想用它作为标识符。我希望此密钥作为GET或POST参数而不是cookie标头发送。

我现在的问题是:如何将会话信息(即状态)存储在Scalatra servlet中而不使用cookie,而只是一个参数作为标识符?

到目前为止,我试图使用文件系统来存储所有的会话信息,但这太慢了,不必要,因为会话只持续几秒钟。

(安全不是问题)

回答

5

我想出了如何做到这一点。

在每个Scalatra servlet中,我可以访问实现javax.servlet.ServletContext接口的全局servletContext。我可以使用它的两种方法setAttribute(x: String, y: Any)getAttribute(x : String)来存储有关我的会话的信息,其中x是我的唯一标识符,y是会话信息,编码为案例类Session

切实我具备以下条件:

def storeSession(key : String, session : Session) { 
    servletContext.setAttribute(attributePrefix + key, session) 
} 

def loadSession(key : String) : Session = { 
    val session = servletContext.getAttribute(attributePrefix + key) 
    if (session != null) { 
     session match { 
      case s : Session => s 
      case _ => null 
     } 
    } else { 
     null 
    } 
} 

这样我可以保持状态的服务器上,无需通过cookie,仅客户端必须提供一个GET值一个唯一的标识符。

我想这个技术可以应用于Java和Scala中的任何servlet,它提供了一个ServletContext的实例,而不仅仅是Scalatra。

+0

这是处理Java servlet环境时用于存储“会话数据”的quick-n-easy和默认解决方案 - 正是我所需要的。 – 2013-06-20 00:39:31

+0

你将如何获得钥匙?它会为每个请求生成吗?它如何识别会话? – Rajeev 2013-12-24 10:53:24

+0

在我的情况下,在每个新会话中(而不是每个请求)使用随机数生成器在代码中的其他位置生成密钥。任何唯一的标识符都可以使用。 – Waboodoo 2013-12-24 13:29:30

1

不错的问题。

与其将状态存储到磁盘以及引起性能下降,如何在内存中存储la Redis?

debasishg有一个Scala implementation,它是Scala社区中的一员,它可能适合该账单。例如,在Spray中,我认为这是在维护状态服务器端的替代方法;即将客户端cookie标识符存储到内存中高速缓存,而不是依靠HttpSession