已經第三篇了,還沒辦點代碼,來點實惠的
關於GWT RPC 結合spring分發
先說最初的GWT開發
GWT最初的藍本,一次RPC需要這麼些文件
不一一闡述了,rpc需要一個service,一個serviceAsync,一個serviceImpl
以及web.xml中的兩個配置
- <servlet>
- <servlet-name>greetServlet</servlet-name>
- <servlet-class>com.test.kosmos.server.GreetingServiceImpl</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>greetServlet</servlet-name>
- <url-pattern>/testgwt/greet</url-pattern>
- </servlet-mapping>
RPC幾個必要的文件還好說,畢竟是文件隔斷的;web.xml裏面這兩個配置項是萬惡之源;惱人,一個團隊都來修改這個文件,雖說SVN可以同步合併文件,但是還想相當惱人的;一個項目做下來,得加入多少servlet啊。。。。。多個工程分開部署的話,web.xml靠編譯腳本合併?做個分發器吧,配置文件如下:
- <servlet>
- <servlet-name>GWTRemoteServiceServlet</servlet-name>
- <servlet-class>com.openkosmos.chiron.core.server.GWTRemoteServiceServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>GWTRemoteServiceServlet</servlet-name>
- <url-pattern>*.gwt</url-pattern>
- </servlet-mapping>
剩下的問題就是GWTRemoteServiceServlet 實現了;扒google源碼,擴展com.google.gwt.user.server.rpc.RemoteServiceServlet;
獲取spring上下文
- @Override
- public void init(ServletConfig Config) throws ServletException {
- super.init(Config);
- springContext = (WebApplicationContext) Config.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- if (springContext == null) {
- throw new RuntimeException("Check Your Web.Xml Setting, No Spring Context Configured");
- }
- }
分發service,截取requeset和response
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- RemoteService service;
- try {
- String reqrequestURI = req.getRequestURI();
- String beanName = requestURI.substring(requestURI.lastIndexOf("/") + 1, requestURI.lastIndexOf(".gwt"));
- log.debug("beanName:[" + beanName + "]");
- try {
- service = (RemoteService) springContext.getBean(beanName);
- } catch (Exception e) {
- /*
- * resp.sendRedirect((new StringBuilder(String.valueOf(req .getContextPath()))).append("/").toString());
- */
- log.error(e, e);
- return;
- }
- if (beanName.toUpperCase().contains("LOGIN")) {
- req.getSession().setAttribute("LOGIN", "LOGIN");
- } else {
- }
- if (service == null) {
- log.warn("service:[" + beanName + "] not register in context....");
- } else {
- log.debug("service:[" + service.getClass().getSimpleName() + "]");
- req.setAttribute(SERVICE_OBJECT, service);
- }
- super.service(req, resp);
- } catch (Throwable e) {
- synchronized (this) {
- perThreadRequest.set(req);
- perThreadResponse.set(resp);
- }
- doUnexpectedFailure(e);
- } finally {
- // HttpRequestContext.ThreadLocalHttpRequestContext.remove();
- if (perThreadRequest != null) {
- perThreadRequest.set(null);
- }
- if (perThreadResponse != null) {
- perThreadResponse.set(null);
- }
- }
- }
處理回調
- /** rewrite processCall
- *
- * @param bean
- * @param payload
- * @return
- * @throws SerializationException */
- @Override
- public String processCall(String payload) throws SerializationException {
- // First, check for possible XSRF situation
- checkPermutationStrongName();
- RemoteService service = (RemoteService) perThreadRequest.get().getAttribute(SERVICE_OBJECT);
- if (service == null) {
- // service = delegate;
- log.error("service is null ");
- return RPC.encodeResponseForFailure(null, new Throwable("service is null "));
- }
- try {
- RPCRequest rpcRequest = RPC.decodeRequest(payload, service.getClass(), this);
- onAfterRequestDeserialized(rpcRequest);
- Context.current().setCurrentRpcContext(new RpcContext(getThreadLocalRequest(), getThreadLocalResponse(), getServletContext()));
- /* log.debug("processCall session:[" + getThreadLocalRequest().getSession()+"]"); */
- return RPC.invokeAndEncodeResponse(service, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(),
- rpcRequest.getFlags());
- } catch (IncompatibleRemoteServiceException ex) {
- log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
- return RPC.encodeResponseForFailure(null, ex);
- }
- }
大功告成,從url xxx.gwt,獲取service名字,通過註冊的service 回調 spring的service,處理業務請求後回調