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方法 
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.     }  
相關文章
相關標籤/搜索