GWT開發札記三

 已經第三篇了,還沒辦點代碼,來點實惠的

關於GWT RPC 結合spring分發

先說最初的GWT開發

GWT最初的藍本,一次RPC需要這麼些文件

不一一闡述了,rpc需要一個service,一個serviceAsync,一個serviceImpl

以及web.xml中的兩個配置

  1. <servlet> 
  2.   <servlet-name>greetServlet</servlet-name> 
  3.   <servlet-class>com.test.kosmos.server.GreetingServiceImpl</servlet-class> 
  4. </servlet> 
  5.  
  6. <servlet-mapping> 
  7.   <servlet-name>greetServlet</servlet-name> 
  8.   <url-pattern>/testgwt/greet</url-pattern> 
  9. </servlet-mapping> 

RPC幾個必要的文件還好說,畢竟是文件隔斷的;web.xml裏面這兩個配置項是萬惡之源;惱人,一個團隊都來修改這個文件,雖說SVN可以同步合併文件,但是還想相當惱人的;一個項目做下來,得加入多少servlet啊。。。。。多個工程分開部署的話,web.xml靠編譯腳本合併?做個分發器吧,配置文件如下:

  1. <servlet> 
  2.     <servlet-name>GWTRemoteServiceServlet</servlet-name> 
  3.     <servlet-class>com.openkosmos.chiron.core.server.GWTRemoteServiceServlet</servlet-class> 
  4. </servlet> 
  1. <servlet-mapping> 
  2.     <servlet-name>GWTRemoteServiceServlet</servlet-name> 
  3.     <url-pattern>*.gwt</url-pattern> 
  4. </servlet-mapping> 

剩下的問題就是GWTRemoteServiceServlet 實現了;扒google源碼,擴展com.google.gwt.user.server.rpc.RemoteServiceServlet;

獲取spring上下文

  1. @Override 
  2.     public void init(ServletConfig Config) throws ServletException { 
  3.         super.init(Config); 
  4.         springContext = (WebApplicationContext) Config.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 
  5.  
  6.         if (springContext == null) { 
  7.             throw new RuntimeException("Check Your Web.Xml Setting, No Spring Context Configured"); 
  8.         } 
  9.  
  10.     } 

分發service,截取requeset和response

  1. @Override 
  2.     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  3.         RemoteService service; 
  4.         try { 
  5.             String reqrequestURI = req.getRequestURI(); 
  6.             String beanName = requestURI.substring(requestURI.lastIndexOf("/") + 1, requestURI.lastIndexOf(".gwt")); 
  7.             log.debug("beanName:[" + beanName + "]"); 
  8.  
  9.             try { 
  10.                 service = (RemoteService) springContext.getBean(beanName); 
  11.             } catch (Exception e) { 
  12.                 /* 
  13.                  * resp.sendRedirect((new StringBuilder(String.valueOf(req .getContextPath()))).append("/").toString()); 
  14.                  */ 
  15.                 log.error(e, e); 
  16.                 return; 
  17.             } 
  18.  
  19.             if (beanName.toUpperCase().contains("LOGIN")) { 
  20.                 req.getSession().setAttribute("LOGIN", "LOGIN"); 
  21.             } else { 
  22.             } 
  23.  
  24.             if (service == null) { 
  25.                 log.warn("service:[" + beanName + "] not register in context...."); 
  26.             } else { 
  27.                 log.debug("service:[" + service.getClass().getSimpleName() + "]"); 
  28.                 req.setAttribute(SERVICE_OBJECT, service); 
  29.             } 
  30.             super.service(req, resp); 
  31.         } catch (Throwable e) { 
  32.             synchronized (this) { 
  33.                 perThreadRequest.set(req); 
  34.                 perThreadResponse.set(resp); 
  35.             } 
  36.             doUnexpectedFailure(e); 
  37.         } finally { 
  38.             // HttpRequestContext.ThreadLocalHttpRequestContext.remove(); 
  39.             if (perThreadRequest != null) { 
  40.                 perThreadRequest.set(null); 
  41.             } 
  42.             if (perThreadResponse != null) { 
  43.                 perThreadResponse.set(null); 
  44.             } 
  45.         } 
  46.     } 

處理回調

  1. /** rewrite processCall 
  2.      *  
  3.      * @param bean 
  4.      * @param payload 
  5.      * @return 
  6.      * @throws SerializationException */ 
  7.     @Override 
  8.     public String processCall(String payload) throws SerializationException { 
  9.         // First, check for possible XSRF situation 
  10.         checkPermutationStrongName(); 
  11.         RemoteService service = (RemoteService) perThreadRequest.get().getAttribute(SERVICE_OBJECT); 
  12.         if (service == null) { 
  13.             // service = delegate
  14.             log.error("service is null "); 
  15.             return RPC.encodeResponseForFailure(null, new Throwable("service is null ")); 
  16.         } 
  17.         try { 
  18.             RPCRequest rpcRequest = RPC.decodeRequest(payload, service.getClass(), this); 
  19.             onAfterRequestDeserialized(rpcRequest); 
  20.             Context.current().setCurrentRpcContext(new RpcContext(getThreadLocalRequest(), getThreadLocalResponse(), getServletContext())); 
  21.             /* log.debug("processCall session:[" + getThreadLocalRequest().getSession()+"]"); */ 
  22.             return RPC.invokeAndEncodeResponse(service, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(), 
  23.                     rpcRequest.getFlags()); 
  24.         } catch (IncompatibleRemoteServiceException ex) { 
  25.             log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex); 
  26.             return RPC.encodeResponseForFailure(null, ex); 
  27.         } 
  28.     } 

大功告成,從url xxx.gwt,獲取service名字,通過註冊的service 回調 spring的service,處理業務請求後回調

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章