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代碼
- @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);
- }
- }
歡迎關注本站公眾號,獲取更多信息