`
xianbin
  • 浏览: 214842 次
  • 来自: ...
社区版块
存档分类
最新评论

Play! 框架可扩展性的一些疑问

阅读更多
最近在研究如何将Membase NoSQL应用到Play! 框架中,需求主要是为了将一些用户状态,比如登录状态、页面操作状态等缓存起来。

众所周知,Play!是一个无状态的框架,意思就是Play!没有Session!但是使用过Play!的朋友一定知道Play!的Control里面是有一个session的,别急,这个session实际上并不是我们真正意义上的浏览器session,而是cookie哦!要理解这点,需要我们打开Play!的源码:
    /**
     * Session scope
     */
    public static class Session {
......
        static Session restore() {
            try {
                Session session = new Session();
                Http.Cookie cookie = Http.Request.current().cookies.get(COOKIE_PREFIX + "_SESSION");
                if (cookie != null && Play.started && cookie.value != null && !cookie.value.trim().equals("")) {
                    String value = cookie.value;
                    String sign = value.substring(0, value.indexOf("-"));
                    String data = value.substring(value.indexOf("-") + 1);
                    if (sign.equals(Crypto.sign(data, Play.secretKey.getBytes()))) {
                        String sessionData = URLDecoder.decode(data, "utf-8");
                        Matcher matcher = sessionParser.matcher(sessionData);
                        while (matcher.find()) {
                            session.put(matcher.group(1), matcher.group(2));
                        }
                    }
                    if (COOKIE_EXPIRE != null) {
                        // Verify that the session contains a timestamp, and that it's not expired
                        if (!session.contains(TS_KEY)) {
                            session = new Session();
                        } else {
                            if (Long.parseLong(session.get(TS_KEY)) < System.currentTimeMillis()) {
                                // Session expired
                                session = new Session();
                            }
                        }
                        session.put(TS_KEY, System.currentTimeMillis() + (Time.parseDuration(COOKIE_EXPIRE) * 1000));
                    } else {
                        // Just restored. Nothing changed. No cookie-expire.
                        session.changed = false;
                    }
                } else {
                    // no previous cookie to restore; but we may have to set the timestamp in the new cookie
                    if (COOKIE_EXPIRE != null) {
                        session.put(TS_KEY, System.currentTimeMillis() + (Time.parseDuration(COOKIE_EXPIRE) * 1000));
                    }
                }

                return session;
            } catch (Exception e) {
                throw new UnexpectedException("Corrupted HTTP session from " + Http.Request.current().remoteAddress, e);
            }
        }

        Map<String, String> data = new HashMap<String, String>(); // ThreadLocal access
        boolean changed = false;
        public static ThreadLocal<Session> current = new ThreadLocal<Session>();

        public static Session current() {
            return current.get();
        }
......
        void save() {
            if (Http.Response.current() == null) {
                // Some request like WebSocket don't have any response
                return;
            }
            if(!changed && SESSION_SEND_ONLY_IF_CHANGED && COOKIE_EXPIRE == null) {
                // Nothing changed and no cookie-expire, consequently send nothing back.
                return;
            }
            if (isEmpty()) {
                // The session is empty: delete the cookie
                if(Http.Request.current().cookies.containsKey(COOKIE_PREFIX + "_SESSION") || !SESSION_SEND_ONLY_IF_CHANGED) {
                    Http.Response.current().setCookie(COOKIE_PREFIX + "_SESSION", "", null, "/", 0, COOKIE_SECURE, SESSION_HTTPONLY);
                }
                return;
            }
            try {
                StringBuilder session = new StringBuilder();
                for (String key : data.keySet()) {
                    session.append("\u0000");
                    session.append(key);
                    session.append(":");
                    session.append(data.get(key));
                    session.append("\u0000");
                }
                String sessionData = URLEncoder.encode(session.toString(), "utf-8");
                String sign = Crypto.sign(sessionData, Play.secretKey.getBytes());
                if (COOKIE_EXPIRE == null) {
                    Http.Response.current().setCookie(COOKIE_PREFIX + "_SESSION", sign + "-" + sessionData, null, "/", null, COOKIE_SECURE, SESSION_HTTPONLY);
                } else {
                    Http.Response.current().setCookie(COOKIE_PREFIX + "_SESSION", sign + "-" + sessionData, null, "/", Time.parseDuration(COOKIE_EXPIRE), COOKIE_SECURE, SESSION_HTTPONLY);
                }
            } catch (Exception e) {
                throw new UnexpectedException("Session serializationProblem", e);
            }
        }
......
    }


上面的代码很明显的看出,Play!的session操作实际上就是对cookie的操作。

但是对于我来说很不幸的事情并不是这点,而是play!的session是一个静态类!并且还是Scope里面的一个子类,这意味着我无法很轻易的替换它,除非修改这个类的源码。

这样我非常还念基于接口的编程,如果session是一个接口,而不是一个静态类,那么我就可以实现一个基于session接口的实现类,用于替换这个session类,这样的话,我就能将对membase的操作封装在session中,可以做到很灵活的扩展。

也许从中我们可以看出,play!在强调敏捷性的同时,失去了一定的灵活性,又或者,我对play!的了解还不够深入吧。
分享到:
评论

相关推荐

    play!框架学习文档(汉化了一部分)

    - **高效性**:Play! 采用了一系列优化措施来提高开发效率,比如热加载功能,即在开发过程中无需重启服务器即可看到改动的效果。 - **无状态的 MVC 架构**:这使得 Play! 可以更好地支持分布式部署和横向扩展。 - **...

    play!framework框架——japid源码

    **Play! Framework框架与Japid源码解析** 在软件开发领域,使用高效的框架可以极大地提升开发效率和代码质量。Play! Framework是一个流行的Java Web应用程序框架,它采用模型-视图-控制器(MVC)架构模式,支持敏捷...

    Learning Play!Framework 2

    1. **简洁性**:Play! Framework 使用简洁明了的代码风格,这使得应用程序易于理解和维护。 2. **实时重载**:该框架支持热重载功能,即当代码发生变化时,应用会自动更新,无需重启服务器,大大提高了开发效率。 3....

    play framework api,play! framework api,play api

    在描述中提到的"play framework api,play! framework api,play api"都是指Play Framework的API文档,它包含了框架的所有公共类、方法和接口,供开发者在编写代码时查阅和引用。API文档是理解框架工作原理、学习如何...

    play框架学习手册

    Play框架是一款基于Java的全栈Web开发框架,它的设计理念是帮助开发者使用最小的配置和编码来构建高性能、可扩展的Web应用。本手册将详细介绍Play框架的核心概念、安装配置、项目结构、基本使用和高级特性。 **一....

    play_入门学习手册

    作为一款纯Java框架,Play!允许开发者在不改变原有开发工具和类库的基础上提升开发效率,对于熟悉Java平台的开发者来说,它是一个理想的选择,无需切换语言或IDE。 配置Play!环境的关键步骤是将Play!的路径添加到...

    JAVA PLAY框架入门学习手册

    Java PLAY框架是基于Java语言的Web应用程序框架,旨在提高Web应用程序的开发效率和可维护性。下面是Java PLAY框架的入门学习手册,涵盖了框架的主要概念、目录结构、请求生命周期、HTTP路由、类增强等方面的知识点。...

    play框架 2.1 api

    play框架 2.1 api

    play framework框架教程

    ### Play Framework框架教程 ...总之,Play框架提供了一种现代化的Web开发体验,它不仅支持多种编程语言,而且还具有高度可扩展性和灵活性。对于希望构建高性能Web应用的开发者来说,Play是一个值得考虑的选择。

    play framework 框架手册 word 版

    《Play Framework 框架手册》是一份深入介绍Play框架的文档,主要涵盖了从基础概念到高级特性的全面内容,适合初学者和经验丰富的开发者参考。以下是对手册中部分核心知识点的详细阐述: 1. **MVC应用程序模型**:...

    对play!的CRUD的一次改造

    对play!的CRUD 进行改造,改代码还会持续重构,并不完善。 1.将create,show,delete,list都改成@Util方法,可以类似 public static void show(String id){ MyCRUD.show(id); } 的方式调用。更通用。 2.增加@...

    Play框架的一个demo

    Play框架是一个开源的Java和Scala应用开发框架,它遵循模型-视图-控制器(MVC)架构模式。Play强调简洁的代码和实时反馈,使得开发过程更为高效。它支持TDD(测试驱动开发),并且与现代Web技术如HTML5、CSS3和...

    play框架手册完整版本

    Play框架是基于Java和Scala的开源Web应用框架,遵循MVC(Model-View-Controller...以上就是Play框架的一些核心概念和特性,Play 1.2.4版本的手册会详细讲解这些内容,帮助开发者更好地理解和使用Play框架进行Web开发。

    Play框架中文文档.pdf

    Play框架中文文档.pdf

    play框架jar包

    Play框架是一款基于Java和Scala的开源Web应用...总之,这个“Play框架jar包”资源为开发者提供了搭建Play应用所需的基础组件,通过理解和熟练运用这些jar包,开发者可以快速、高效地构建出高性能、可扩展的Web应用。

    Play framework框架

    Play Framework框架的缺陷是相对较少的,但是该框架仍然存在一些问题,如性能问题、配置问题等。 十二、Play Framework框架的未来 Play Framework框架的未来看起来非常光明,该框架正在不断地发展和改进,提供了更...

Global site tag (gtag.js) - Google Analytics