论坛首页 Web前端技术论坛

gwt spring 完美整合

浏览 13473 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-11-25  
GWT

1.3版本前整合gwt spring,用到了第三方类,如cglib扩展类具备gwt servlet的功能,随着1.4版本的发布(发布很久了T_T '),整合有了新的方式,闲话不说,看看整合后的servlet如何调用服务:

java 代码
  1. /**  
  2.  * GWTRemoteServiceServlet act as a dispatch servlet for all GWT services  
  3.  *   
  4.  * in your web.xml, mapping all request /gwtrpc/ to this servlet  
  5.  *   
  6.  */  
  7. public class GWTRemoteServiceServlet extends RemoteServiceServlet {   
  8.   
  9.     private WebApplicationContext springContext;   
  10.   
  11.     @Override  
  12.     public void init(ServletConfig config) throws ServletException {   
  13.            
  14.         super.init(config);   
  15.            
  16.         springContext = (WebApplicationContext) config   
  17.                 .getServletContext()   
  18.                 .getAttribute(   
  19.                         WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);   
  20.   
  21.         if (springContext == null) {   
  22.             throw new RuntimeException(   
  23.                     "Check your web.xml setting, no Spring context configured");   
  24.         }   
  25.   
  26.     }   
  27.   
  28.     @Override  
  29.     protected void service(HttpServletRequest req, HttpServletResponse resp)   
  30.             throws ServletException, IOException {   
  31.         try {   
  32.             HttpRequestContext context = new HttpRequestContext(req, resp, this  
  33.                     .getServletConfig());   
  34.   
  35.             HttpRequestContext.ThreadLocalHttpRequestContext.set(context);   
  36.   
  37.             ServletContext servletContext = getServletContext();   
  38.   
  39.             perThreadRequest.set(req);   
  40.             perThreadResponse.set(resp);   
  41.   
  42.             String pathInfo = req.getPathInfo();   
  43.             if (pathInfo.startsWith("/")) {   
  44.                 pathInfo = pathInfo.substring(1);   
  45.             }   
  46.   
  47.             RemoteService service = (RemoteService) springContext.getBean(pathInfo);   
  48.   
  49.             String requestPayload = readPayloadAsUtf8(req);   
  50.   
  51.             // Let subclasses see the serialized request.   
  52.             //   
  53.             onBeforeRequestDeserialized(requestPayload);   
  54.   
  55.             // Invoke the core dispatching logic, which returns the serialized   
  56.             // result.   
  57.             //   
  58.             String responsePayload = processCall(service, requestPayload);   
  59.   
  60.             // Let subclasses see the serialized response.   
  61.             //   
  62.             onAfterResponseSerialized(responsePayload);   
  63.   
  64.             // Write the response.   
  65.             //   
  66.             writeResponse(req, resp, responsePayload);   
  67.         } catch (Throwable e) {   
  68.             // Give a subclass a chance to either handle the exception or   
  69.             // rethrow it   
  70.             //   
  71.             doUnexpectedFailure(e);   
  72.         } finally {   
  73.             HttpRequestContext.ThreadLocalHttpRequestContext.remove();   
  74.         }   
  75.     }   
  76.   
  77.     /**  
  78.      * rewrite processCall  
  79.      *   
  80.      * @param bean  
  81.      * @param payload  
  82.      * @return  
  83.      * @throws SerializationException  
  84.      */  
  85.     public String processCall(RemoteService bean, String payload)   
  86.             throws SerializationException {   
  87.         try {   
  88.             RPCRequest rpcRequest = RPC.decodeRequest(payload, bean.getClass(),   
  89.                     this);   
  90.             return RPC.invokeAndEncodeResponse(bean, rpcRequest.getMethod(),   
  91.                     rpcRequest.getParameters(), rpcRequest   
  92.                             .getSerializationPolicy());   
  93.         } catch (IncompatibleRemoteServiceException ex) {   
  94.             getServletContext()   
  95.                     .log(   
  96.                             "An IncompatibleRemoteServiceException was thrown while processing this call.",   
  97.                             ex);   
  98.             return RPC.encodeResponseForFailure(null, ex);   
  99.         }   
  100.     }   
  101. }   

 xml代码:

  1. <bean id="bookservice" class="com.service.BookService" />  
java 代码
  1. class BookService implements IBookService{   
  2. }   
  3.   
  4. interface IBookService extends RemoteService{   
  5. }  

ok,该servlet继承RemoteServiceServlet,做了三件事

1.init时获得spring webContext

2.service时解析请求字符,如/service/bookservice,获得bookservice名,对应spring bean id

3.重写processCall方法,通过bookservice,在springContext中获得注册了的bookservice,提供调用

   发表时间:2007-11-26  
新架构优势:
1.没有使用第三方包扩展,更快速、更稳定
2.由一个servlet转发请求,服务类为spring注册的类,无需继承RemoteServlet,服务类不是servlet
0 请登录后投票
   发表时间:2007-11-27  
这样做好像不支持aop
0 请登录后投票
   发表时间:2007-11-28  
支持啊,其实就是gwt调用了一个spring服务,而spring服务是一个gwt服务而已
0 请登录后投票
   发表时间:2007-11-28  
方便快速强大,不要把简单问题复杂化
0 请登录后投票
   发表时间:2007-11-30  
谢谢yongyuan.jiang,支持aop
另一个版本

delegate 用法参照 org.springframework.web.servlet.mvc.multiaction.MultiActionController

public class GwtRemoteServiceController extends RemoteServiceServlet implements
		Controller, ServletContextAware {
	private static final long serialVersionUID = 8175888785480720736L;

	private Object delegate;

	private ServletContext servletContext;

	@Override
	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	@Override
	public ServletContext getServletContext() {
		return servletContext;
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		super.doPost(request, response);
		return null;
	}

	@Override
	public String processCall(String payload) throws SerializationException {
		Object delegateToUse = this.delegate;
		if (delegateToUse == null) {
			return super.processCall(payload);
		} else {
			try {
				RPCRequest rpcRequest = RPC.decodeRequest(payload,
						delegateToUse.getClass(), this);
				return RPC.invokeAndEncodeResponse(delegateToUse, rpcRequest
						.getMethod(), rpcRequest.getParameters(), rpcRequest
						.getSerializationPolicy());
			} catch (IncompatibleRemoteServiceException ex) {
				getServletContext()
						.log(
								"An IncompatibleRemoteServiceException was thrown while processing this call.",
								ex);
				return RPC.encodeResponseForFailure(null, ex);
			}
		}
	}

	public Object getDelegate() {
		return delegate;
	}

	public void setDelegate(Object delegate) {
		this.delegate = delegate;
	}
}
0 请登录后投票
   发表时间:2007-12-03  
so good ,唉。我对spring那个ModelAndView 还是不懂
0 请登录后投票
   发表时间:2008-01-02  
yongyuan.jiang,对你的代码我有些疑惑,还请多多指教。
1 perThreadRequest和perThreadResponse是private的,你这里怎么可以引用?
2 HttpRequestContext这个类是哪里的?
3 readPayloadAsUtf8这个方法为什么我引用不到?
谢谢!
0 请登录后投票
   发表时间:2008-01-09  
哦,是这样子的。

1 perThreadRequest和perThreadResponse是private的,你这里怎么可以引用?
我把父类的方法全部写成protected了

2 HttpRequestContext这个类是哪里的?
这个类是自己写的一个类,用于存放requestde

3 readPayloadAsUtf8这个方法为什么我引用不到?
这个方法也是在父类当中
0 请登录后投票
   发表时间:2008-05-14  


博主是javaeye上的gwt第一高人,特别希望博主可以就如何用gwt开发一个伸展性比较好的应用整理出一篇完整的文章,这样大家学习起来也比较方便。
再次谢谢博主。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics