`
solonote
  • 浏览: 89991 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Play Framework分析1-与Servlet API的整合

阅读更多
Play是标准的Request-Response型框架,类似于Struts。
Play把HTTP请求封装为4个类:Header,Cookie,Request,Response。

和Servlet类似的是,他也是通过处理Request和Response两个对象来完成一次访问的处理。
和Servlet不同的是,在Servlet中你想获得ServletRequest/ServletResponse,你必须通过HttpServlet set到你的Object中。
而Play不这样做,通过Threadlocal机制,可以在程序的任何地方通过调用静态方法
Request.current.get()方法获得当前线程正在处理的Request.
这就相当于你不需要写set方法,你就可以在任何地方都取到当前的Request.
这是非常巧妙的做法,能做到这一点也和服务器本身的处理机制有关。
如果我们只用一个线程来处理所有的请求,那么Play这样的做法就行不通了。

Play整合Servlet API是这样的:
他有一个类叫做ServletWapper,ServletWapper继承了HTTPServlet.当一次请求进来,它首先把HttpServletRequest的内容拷贝到当前的Request中,等Play框架处理完以后,再把Response的内容拷贝到HttpServletResponse中。
这样Play和Servlet API就整合到一起了,非常的简单



可以发现,Play对Servlet API的入侵性很小,可以说它就是一个Servlet.
这只是一个Play的冰山一角,它的代码还有很多有趣的地方,可以用非主流来形容。
比如它使用抛异常的方式返回执行的结果等等,Play的代码阅读起来很简单,推荐有兴趣的朋友可以阅读。

这就是ServletWapper的service方法
    @Override
    protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletRespo
nse) throws ServletException, IOException {
        Logger.trace("ServletWrapper>service " + httpServletRequest.getRequestURI());
        Request request = null;
        try {
            request = parseRequest(httpServletRequest);
            Logger.trace("ServletWrapper>service, request: " + request);
            Response response = new Response();
            Response.current.set(response);
            response.out = new ByteArrayOutputStream();
            boolean raw = false;
            for (PlayPlugin plugin : Play.plugins) {
                if (plugin.rawInvocation(request, response)) {
                    raw = true;
                    break;
                }
            }
            if (raw) {
                copyResponse(Request.current(), Response.current(), httpServletRequest, httpServletResponse);
            } else {
                Invoker.invokeInThread(new ServletInvocation(request, response, httpServletRequest, httpServletResponse));
            }
        } catch (NotFound e) {
            Logger.trace("ServletWrapper>service, NotFound: " + e);
            serve404(httpServletRequest, httpServletResponse, e);
            return;
        } catch (RenderStatic e) {
            Logger.trace("ServletWrapper>service, RenderStatic: " + e);
            serveStatic(httpServletResponse, httpServletRequest, e);
            return;
        } catch (Throwable e) {
            throw new ServletException(e);
        }
    }
  • 大小: 24.4 KB
分享到:
评论
8 楼 依山傍水 2011-08-04  
因为我要用多个文件上传,要用到
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(4096); // 超出这个大小放磁盘,否则放在内存中

ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(MAXFILESIZE);
List fileItems = upload.parseRequest(request);
但这里的request应该是HttpServletRequest,但是怎么得到servletRequest呢?
7 楼 依山傍水 2011-08-04  
还是不太懂,不知道怎么转换过去,你能再指教一下吗?
6 楼 Laynepeng 2009-12-07  
container 写道

哦,谢谢。

我现在还费事的把play的router和ActionInvoker等抽取出来,然后使用velocity作为模板,搞了个GAE定制版的play!...


这样修改应该改进不大。。。在GAE的Group上面有人直接用servlet,在第一次访问的时候都喊慢。。。

瓶颈出现在GAE的运行环境初始化而不是你的程序的初始化。。。
5 楼 container 2009-12-07  
Laynepeng 写道
container 写道

我以前准备使用play!来开发GAE,访问了一下play!自己带的那个GAE的例子,发现第一次访问非常的慢。

后来在play!的google group上看到,play的作者说,由于GAE的运行机制的原因,如果一段时间内没有访问,那么你的GAE应用会停掉,当有新的请求来的时候,GAE会重新装在你的应用。这个过程会重新启动play(看他的ServletWapper就是调用play.init方法),而这个过程比较耗时,所以第一次请求会慢一些。

看play的init方法主要是初始化配置,预编译,加载类等操作...不知道是那一块比较耗费时间?如果打成war包后,可以对init精简一些的话,我想对在GAE上的app来说,可以大大减少第一次响应的时间的。


你理解错了。你部署在GAE上面的程序,如果连续5分钟不被访问的话,GAE会把他停掉;等再有访问来的时候,会重新load整个GAE的java运行context/container。

一般很少网站会5分钟每人访问吧?如果是开发环境或者只是个人Blog的话,我教你个诀窍:

用GAE提供的Cron,每3分钟访问一次你程序的某一个servlet。。。


哦,谢谢。

我现在还费事的把play的router和ActionInvoker等抽取出来,然后使用velocity作为模板,搞了个GAE定制版的play!...

4 楼 Laynepeng 2009-12-07  
container 写道

我以前准备使用play!来开发GAE,访问了一下play!自己带的那个GAE的例子,发现第一次访问非常的慢。

后来在play!的google group上看到,play的作者说,由于GAE的运行机制的原因,如果一段时间内没有访问,那么你的GAE应用会停掉,当有新的请求来的时候,GAE会重新装在你的应用。这个过程会重新启动play(看他的ServletWapper就是调用play.init方法),而这个过程比较耗时,所以第一次请求会慢一些。

看play的init方法主要是初始化配置,预编译,加载类等操作...不知道是那一块比较耗费时间?如果打成war包后,可以对init精简一些的话,我想对在GAE上的app来说,可以大大减少第一次响应的时间的。


你理解错了。你部署在GAE上面的程序,如果连续5分钟不被访问的话,GAE会把他停掉;等再有访问来的时候,会重新load整个GAE的java运行context/container。

一般很少网站会5分钟每人访问吧?如果是开发环境或者只是个人Blog的话,我教你个诀窍:

用GAE提供的Cron,每3分钟访问一次你程序的某一个servlet。。。
3 楼 container 2009-12-06  
Laynepeng 写道
container 写道
如果没有理解错误的话,play!生成war包,部署到jee容器中,真正起作用的还是他内置的Server。

对不?


不对。。。上面他的论述没有讨论到server的问题。

因为整个Play都是对Request和Reponse进行操作的(它内部的Server也是);而Servlet是HttpServletRequest和HttpServletResponse,为了统一两种接口,所以有了ServletWapper这个类。

Tomcat或者其他Container接收到Http的请求,会首先激活HttpServlet,也就是ServletWapper的service方法,Play在这里把HttpServletRequest和HttpServletResponse转成Request和Reponse,往框架内塞。那这就和用自己的server的接口一样了。。。


我以前准备使用play!来开发GAE,访问了一下play!自己带的那个GAE的例子,发现第一次访问非常的慢。

后来在play!的google group上看到,play的作者说,由于GAE的运行机制的原因,如果一段时间内没有访问,那么你的GAE应用会停掉,当有新的请求来的时候,GAE会重新装在你的应用。这个过程会重新启动play(看他的ServletWapper就是调用play.init方法),而这个过程比较耗时,所以第一次请求会慢一些。

看play的init方法主要是初始化配置,预编译,加载类等操作...不知道是那一块比较耗费时间?如果打成war包后,可以对init精简一些的话,我想对在GAE上的app来说,可以大大减少第一次响应的时间的。
2 楼 Laynepeng 2009-12-06  
container 写道
如果没有理解错误的话,play!生成war包,部署到jee容器中,真正起作用的还是他内置的Server。

对不?


不对。。。上面他的论述没有讨论到server的问题。

因为整个Play都是对Request和Reponse进行操作的(它内部的Server也是);而Servlet是HttpServletRequest和HttpServletResponse,为了统一两种接口,所以有了ServletWapper这个类。

Tomcat或者其他Container接收到Http的请求,会首先激活HttpServlet,也就是ServletWapper的service方法,Play在这里把HttpServletRequest和HttpServletResponse转成Request和Reponse,往框架内塞。那这就和用自己的server的接口一样了。。。
1 楼 container 2009-12-06  
如果没有理解错误的话,play!生成war包,部署到jee容器中,真正起作用的还是他内置的Server。

对不?

相关推荐

    play framework api,play! framework api,play api

    1. **模块化设计**:Play Framework采用了模块化的设计,使得开发者可以方便地添加或替换特定功能,如模板引擎、持久化层等。 2. **异步编程**:Play Framework基于Akka框架,支持非阻塞I/O和异步处理,提高了Web...

    play-store-api, 在java中,Google Play 存储 protobuf API包装器.zip

    play-store-api, 在java中,Google Play 存储 protobuf API包装器 play-store-api java中的Google Play 存储protobuf包装器包括从 jitpack 获取它。 或者。单独生成git clone https://github.com/yeriom

    Play-Framework-ElasticSearch-Module

    ### Play-Framework-ElasticSearch-Module:整合Java开发框架与搜索技术 在现代软件开发领域,特别是对于构建大规模、高性能的Web应用而言,选择合适的框架和技术堆栈至关重要。Play Framework作为一款流行且高效的...

    play-services-measurement-sdk-api.properties

    play-services-measurement-sdk-api.properties

    google play service 最新版 firebase sdk 9.2

    play-services-cast-framework-9.2.0.jar play-services-clearcut-9.2.0.jar play-services-contextmanager-9.2.0.jar play-services-drive-9.2.0.jar play-services-fitness-9.2.0.jar play-services-games-9.2.0....

    Play framework 2.0 -第一个应用程序

    Play Framework以其简洁的API、模块化的设计和强大的工具集,使得开发Web应用变得更加高效和愉快。继续深入学习,你会发现更多关于路由、模板引擎、异步处理、安全控制以及与其他服务集成的强大功能。

    google-play-api, 将 Google Play scraper转换为 RESTful API.zip

    google-play-api, 将 Google Play scraper转换为 RESTful API google-play-api将 google-play-scraper 转换为 RESTful API 。 现在看它工作了 。要在本地运行:npm installnpm start要立即使用运行,请执行以

    Play Framework Cookbook.pdf

    #### 三、Play Framework 应用场景与案例分析 - **企业级应用开发**:由于 Play Framework 提供了强大的并发处理能力和灵活的架构支持,非常适合用于构建大型的企业级应用。 - **社交平台建设**:利用 Play ...

    play2-war-plugin, 用于 Play Framework 2.x的WAR插件.zip

    play2-war-plugin, 用于 Play Framework 2.x的WAR插件 用于 Play Framework 2.x的 WAR插件Current versions: Play 2.2.x : 1.2.1 Play 2.3.0 -> 2.3.1 : 1.3-beta1 (Scala 2.1

    playframework-nginx-elastic-beanstalk:在 AWS Elastic Beanstalk 上运行 Playframework 和 Nginx

    AWS Elastic Beanstalk 上的 Nginx + Playframework 最新的公共 AMI: ami-c0ae98a8 2015 年 4 月 1 日构建新自定义 AMI 的说明首先,在 Elastic Beanstalk 上创建一个 tomcat 应用程序。 然后通过 SSH 连接到创建的...

    fabric8-maven-generator-api-3.1.62.zip

    Play JSON则与Play Framework紧密集成,适合于大型Web应用;Circe则以其类型安全和强大的编译时检查著称。 在`akka-http-json-master`这个子目录中,我们可以找到项目的主要源代码和示例。这里展示了如何配置Akka ...

    playframework中文教程.zip

    1. **轻量级**:与传统的Java EE规范相比,Play Framework 更为轻便,不依赖于重量级的容器,而是基于简单的HTTP服务器。 2. **敏捷开发**:Play 支持热部署,即代码修改后无需重启服务器即可看到更新效果,大大...

    Play Framework Cookbook

    - **RESTful API 设计**:Play Framework 鼓励使用 RESTful API 设计原则,这有助于创建清晰、一致且易于使用的接口。书中会有详细的案例分析,展示如何创建符合 REST 规范的服务端点。 - **实时应用**:通过 ...

    Play-Utils是一个专门为PlayFramework开发的实用工具包模块

    Play-Utils 模块是为 Play Framework 设计的一个强大且实用的工具集合,它极大地提升了开发者在使用 Play Framework 进行 Java Web 开发时的效率和便利性。Play Framework 是一个开源的、基于 MVC(模型-视图-控制器...

    play-json-api:playframework 中的 JSON API

    播放-json-api 该项目用于演示 Java 和 Scala 中的 JSON API。 它被用于。 用 Java 构建 JSON 使用 Scala 构建 JSON 使用 Java 使用 JSON(请求正文) ...= -1))验证 id != -1 显示带有Option[String]可选字

    Play framework框架

    Play Framework框架 Play Framework框架是一种基于Java的软件框架,旨在提高开发效率和提供REST式的架构风格。该框架可以让开发者继续使用他们喜欢的开发环境或繻库,不需要切换到另一种语言、IDE或者其他繻库。 ...

    Play--Framework-Example--Library:非常简单的Play演示! 框架

    这个"Play--Framework-Example--Library"项目是一个针对初学者的简单示例,旨在帮助开发者快速理解和上手Play Framework。 在Play Framework中,开发者可以直接用浏览器启动和调试应用,无需构建工具,因为它具有...

    playframework-java-filters:关于如何将 play 的 Scala API 适配到 Java 的示例

    Play Framework 是一个流行的开源Web应用框架,用于...总的来说,理解Play Framework的Java过滤器机制并将其与Scala API相结合,可以帮助Java开发者充分利用Play Framework的强大功能,同时保持代码的清晰和可维护性。

    Play Framework2本教程

    Play Framework2是一个强大的Java和Scala应用开发框架,它以其简洁的API、快速的开发周期以及对Web标准的紧密集成而闻名。本教程旨在为初学者和有经验的开发者提供全面的指导,帮助他们掌握Play Framework2的核心...

    playframework 框架学习之路 1

    在“Playframework框架学习之路 1”中,我们可能要探讨这个框架的基础概念、安装过程以及如何创建一个简单的应用。下面将详细介绍Play Framework的关键知识点。 1. **快速开发**: Play Framework以其快速开发能力而...

Global site tag (gtag.js) - Google Analytics