2007-12-19
使用一个servlet来分配所有的gwt service
关键字: java gwt guice
GWT中默认一个service对应一个servlet,这样会使web.xml要配置很多servlet, 不是很方便。我这里通过一个Dispatch servlet来分配service, 这样每个service都成了pojo,使得配置更加方便,也容易测试。
1. Server code
Configure web.xml like
<servlet>
<servlet-name>gwt-dispatch</servlet-name>
<servlet-class>
com.xxxxx.gwt.GwtRpcServiceDispatch
</servlet-class>
<init-param>
<param-name>prefix</param-name>
<param-value>/gsvc</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>gwt-dispatch</servlet-name>
<url-pattern>/gsvc/*</url-pattern>
</servlet-mapping>
prefix参数表示service访问url的根路径
Why it works: Let's see the code of GwtRpcServiceDispatch.java
1 /**
2 * @author xwang
3 * Dispatch the gwt services
4 */
5 public class GwtRpcServiceDispatch extends RemoteServiceServlet {
6 private static final long serialVersionUID = -2797202947611240618L;
7
8 private Injector injector;
9
10 private int beginIndexOfClassName;
11
12 @Override
13 public void init(ServletConfig config) throws ServletException {
14 super.init(config);
15 // get guice injector, it init by ServletContextListener
16 injector = InjectorHolder.getInjector();
17 if (injector == null) {
18 throw new UnavailableException("Guice Injector not found (did you forget to register a "
19 + this.getClass().getSimpleName() + "?)");
20 }
21
22 // set prefix of service url
23 String prefix = config.getInitParameter("prefix");
24 if (prefix == null || prefix.length() == 0) {
25 beginIndexOfClassName = 1;
26 } else if (prefix.startsWith("/")) {
27 beginIndexOfClassName = prefix.length() + 1;
28 } else {
29 beginIndexOfClassName = prefix.length() + 2;
30 }
31 }
这里先要设置Guice Injector, 应为我们的service中用到了guice. 其次设置prefix的长度.
接着就可以根据URL来实例化RomteService,如下:
1 /**
2 * get service implement class's instance
3 * @return service implement class's instance
4 */
5 protected Object getCurrentHandler() {
6 String classPath = getThreadLocalRequest().getRequestURI();
7 // /gsvc/com/xxxxx/bus/domain/service/LandmarkService => com.xxxxx.bus.domain.service.LandmarkService
8 String className = classPath.substring(beginIndexOfClassName);
9 if (className.endsWith("/")) {
10 className = className.substring(0, className.length() - 1);
11 }
12 className = className.replaceAll("/", ".");
13
14 Class<?> clazz = null;
15 try {
16 clazz = Class.forName(className);
17 } catch (ClassNotFoundException e) {
18 e.printStackTrace();
19 throw new IllegalStateException(e.getMessage());
20 }
21
22 return injector.getInstance(clazz);
23 }
当然我们需要重新定义RemoteServiceServlet的主处理方法:
1 // this is the main method of RemoteServiceServlet to process request
2 @Override
3 public String processCall(String payload) throws SerializationException {
4 Object serviceHandler = getCurrentHandler(); //get instance of RemoteService
5
6 try {
7 RPCRequest rpcRequest = RPC.decodeRequest(payload, serviceHandler.getClass(), this);
8 return RPC.invokeAndEncodeResponse(serviceHandler, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest
9 .getSerializationPolicy());
10 } catch (IncompatibleRemoteServiceException ex) {
11 getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
12 return RPC.encodeResponseForFailure(null, ex);
13 }
14 }
还要重新定义support方法:
1 // RemoteServiceServlet use this judge the instance
2 public boolean supports(Object handler) {
3 return handler instanceof RemoteService;
4 }
现在我们的RemoteService就成为了一个pojo如:
1 public interface LandmarkService extends RemoteService {
2 ...........
3 }
4
5 public class LandmarkServiceImpl implements LandmarkService {
6 ...........
7 }
2. Client code
gwt client这边需要用
1 ServiceHelper.registerServiceEntryPoint(instance);
获取访问URL.
why it works:
1 /**
2 * register service url
3 * @param svcObj service object
4 * com.xxxxx.bus.domain.service.LandmarkService => /gsvc/com/xxxxx/bus/domain/service/LandmarkService
5 */
6 public static void registerServiceEntryPoint(Object svcObj) {
7 ServiceDefTarget endpoint = (ServiceDefTarget) svcObj;
8 String endpointText = GWT.getTypeName(svcObj);
9 endpointText = endpointText.substring(0, endpointText.indexOf("_Proxy"));
10 endpointText = endpointText.replace('.', '/');
11 endpoint.setServiceEntryPoint("/gsvc/" + endpointText);
12 }
GWT.getTypeName can get the class name of service object
你可以使用如下代码的方式构造你的service
1 public interface LandmarkService extends RemoteService {
2 public static class Initer {
3 private static LandmarkServiceAsync instance;
4 public static LandmarkServiceAsync getInstance(){
5 if (instance == null) {
6 instance = (LandmarkServiceAsync) GWT.create(LandmarkService.class);
7 ServiceHelper.registerServiceEntryPoint(instance);
8 }
9
10 return instance;
11 }
12 }
13 ........
1. Server code
Configure web.xml like
<servlet>
<servlet-name>gwt-dispatch</servlet-name>
<servlet-class>
com.xxxxx.gwt.GwtRpcServiceDispatch
</servlet-class>
<init-param>
<param-name>prefix</param-name>
<param-value>/gsvc</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>gwt-dispatch</servlet-name>
<url-pattern>/gsvc/*</url-pattern>
</servlet-mapping>
prefix参数表示service访问url的根路径
Why it works: Let's see the code of GwtRpcServiceDispatch.java
1 /**
2 * @author xwang
3 * Dispatch the gwt services
4 */
5 public class GwtRpcServiceDispatch extends RemoteServiceServlet {
6 private static final long serialVersionUID = -2797202947611240618L;
7
8 private Injector injector;
9
10 private int beginIndexOfClassName;
11
12 @Override
13 public void init(ServletConfig config) throws ServletException {
14 super.init(config);
15 // get guice injector, it init by ServletContextListener
16 injector = InjectorHolder.getInjector();
17 if (injector == null) {
18 throw new UnavailableException("Guice Injector not found (did you forget to register a "
19 + this.getClass().getSimpleName() + "?)");
20 }
21
22 // set prefix of service url
23 String prefix = config.getInitParameter("prefix");
24 if (prefix == null || prefix.length() == 0) {
25 beginIndexOfClassName = 1;
26 } else if (prefix.startsWith("/")) {
27 beginIndexOfClassName = prefix.length() + 1;
28 } else {
29 beginIndexOfClassName = prefix.length() + 2;
30 }
31 }
这里先要设置Guice Injector, 应为我们的service中用到了guice. 其次设置prefix的长度.
接着就可以根据URL来实例化RomteService,如下:
1 /**
2 * get service implement class's instance
3 * @return service implement class's instance
4 */
5 protected Object getCurrentHandler() {
6 String classPath = getThreadLocalRequest().getRequestURI();
7 // /gsvc/com/xxxxx/bus/domain/service/LandmarkService => com.xxxxx.bus.domain.service.LandmarkService
8 String className = classPath.substring(beginIndexOfClassName);
9 if (className.endsWith("/")) {
10 className = className.substring(0, className.length() - 1);
11 }
12 className = className.replaceAll("/", ".");
13
14 Class<?> clazz = null;
15 try {
16 clazz = Class.forName(className);
17 } catch (ClassNotFoundException e) {
18 e.printStackTrace();
19 throw new IllegalStateException(e.getMessage());
20 }
21
22 return injector.getInstance(clazz);
23 }
当然我们需要重新定义RemoteServiceServlet的主处理方法:
1 // this is the main method of RemoteServiceServlet to process request
2 @Override
3 public String processCall(String payload) throws SerializationException {
4 Object serviceHandler = getCurrentHandler(); //get instance of RemoteService
5
6 try {
7 RPCRequest rpcRequest = RPC.decodeRequest(payload, serviceHandler.getClass(), this);
8 return RPC.invokeAndEncodeResponse(serviceHandler, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest
9 .getSerializationPolicy());
10 } catch (IncompatibleRemoteServiceException ex) {
11 getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
12 return RPC.encodeResponseForFailure(null, ex);
13 }
14 }
还要重新定义support方法:
1 // RemoteServiceServlet use this judge the instance
2 public boolean supports(Object handler) {
3 return handler instanceof RemoteService;
4 }
现在我们的RemoteService就成为了一个pojo如:
1 public interface LandmarkService extends RemoteService {
2 ...........
3 }
4
5 public class LandmarkServiceImpl implements LandmarkService {
6 ...........
7 }
2. Client code
gwt client这边需要用
1 ServiceHelper.registerServiceEntryPoint(instance);
获取访问URL.
why it works:
1 /**
2 * register service url
3 * @param svcObj service object
4 * com.xxxxx.bus.domain.service.LandmarkService => /gsvc/com/xxxxx/bus/domain/service/LandmarkService
5 */
6 public static void registerServiceEntryPoint(Object svcObj) {
7 ServiceDefTarget endpoint = (ServiceDefTarget) svcObj;
8 String endpointText = GWT.getTypeName(svcObj);
9 endpointText = endpointText.substring(0, endpointText.indexOf("_Proxy"));
10 endpointText = endpointText.replace('.', '/');
11 endpoint.setServiceEntryPoint("/gsvc/" + endpointText);
12 }
GWT.getTypeName can get the class name of service object
你可以使用如下代码的方式构造你的service
1 public interface LandmarkService extends RemoteService {
2 public static class Initer {
3 private static LandmarkServiceAsync instance;
4 public static LandmarkServiceAsync getInstance(){
5 if (instance == null) {
6 instance = (LandmarkServiceAsync) GWT.create(LandmarkService.class);
7 ServiceHelper.registerServiceEntryPoint(instance);
8 }
9
10 return instance;
11 }
12 }
13 ........
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 15257 次
- 性别:


- 详细资料
搜索本博客
我的相册
vmMap
共 6 张
共 6 张
最近加入圈子
最新评论
-
无意中网上看到一篇关于ge ...
姜太公 写道可惜它的给关键字等加的颜色太难看。还有很多重复的gedit失败的地方 ...
-- by seen -
无意中网上看到一篇关于ge ...
可惜它的给关键字等加的颜色太难看。还有很多重复的
-- by 姜太公 -
无意中网上看到一篇关于ge ...
看到了,真不错阿
-- by theone -
关于Python和Java结合的新 ...
认同楼主的意见。如果有遗留系统,将其功能封装起来对系统新的部分提供服务,是比较稳 ...
-- by cloudeye -
关于Python和Java结合的新 ...
就这么个简单的功能还搞上ICE了?管道,标准IO通讯也成
-- by dennis_zane






评论排行榜