博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Play Framework分析1-与Servlet API的整合
阅读量:5836 次
发布时间:2019-06-18

本文共 2034 字,大约阅读时间需要 6 分钟。

hot3.png

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就整合到一起了,非常的简单 
07110534_boVL.jpg
 
可以发现,Play对Servlet API的入侵性很小,可以说它就是一个Servlet. 
这只是一个Play的冰山一角,它的代码还有很多有趣的地方,可以用非主流来形容。 
比如它使用抛异常的方式返回执行的结果等等,Play的代码阅读起来很简单,推荐有兴趣的朋友可以阅读。 
这就是ServletWapper的service方法 
Java代码  
收藏代码
  1.     @Override  
  2.     protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletRespo  
  3. nse) throws ServletException, IOException {  
  4.         Logger.trace("ServletWrapper>service " + httpServletRequest.getRequestURI());  
  5.         Request request = null;  
  6.         try {  
  7.             request = parseRequest(httpServletRequest);  
  8.             Logger.trace("ServletWrapper>service, request: " + request);  
  9.             Response response = new Response();  
  10.             Response.current.set(response);  
  11.             response.out = new ByteArrayOutputStream();  
  12.             boolean raw = false;  
  13.             for (PlayPlugin plugin : Play.plugins) {  
  14.                 if (plugin.rawInvocation(request, response)) {  
  15.                     raw = true;  
  16.                     break;  
  17.                 }  
  18.             }  
  19.             if (raw) {  
  20.                 copyResponse(Request.current(), Response.current(), httpServletRequest, httpServletResponse);  
  21.             } else {  
  22.                 Invoker.invokeInThread(new ServletInvocation(request, response, httpServletRequest, httpServletResponse));  
  23.             }  
  24.         } catch (NotFound e) {  
  25.             Logger.trace("ServletWrapper>service, NotFound: " + e);  
  26.             serve404(httpServletRequest, httpServletResponse, e);  
  27.             return;  
  28.         } catch (RenderStatic e) {  
  29.             Logger.trace("ServletWrapper>service, RenderStatic: " + e);  
  30.             serveStatic(httpServletResponse, httpServletRequest, e);  
  31.             return;  
  32.         } catch (Throwable e) {  
  33.             throw new ServletException(e);  
  34.         }  
  35.     }  

转载于:https://my.oschina.net/hanzhankang/blog/205924

你可能感兴趣的文章
opennebula 开发记录
查看>>
sql 内联,左联,右联,全联
查看>>
C++关于字符串的处理
查看>>
Breaking parallel loops in .NET C# using the Stop method z
查看>>
修改故障转移群集心跳时间
查看>>
[轉]redis;mongodb;memcache三者的性能比較
查看>>
让你的WPF程序在Win7下呈现Win8风格主题
查看>>
802.11 学习笔记
查看>>
Leetcode-Database-176-Second Highest Salary-Easy(转)
查看>>
构建Docker Compose服务堆栈
查看>>
Hadoop生态圈-Kafka常用命令总结
查看>>
如何基于Redis Replication设计并实现Redis-replicator?
查看>>
浮点数内存如何存储的
查看>>
贪吃蛇
查看>>
EventSystem
查看>>
用WINSOCK API实现同步非阻塞方式的网络通讯
查看>>
玩一玩博客,嘿嘿
查看>>
Ubuntu设置python3为默认版本
查看>>
JsonCpp 的使用
查看>>
问题账户需求分析
查看>>