已经第三篇了,还没办点代码,来点实惠的
关于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,处理业务请求后回调