zoukankan      html  css  js  c++  java
  • 通过GWT RPC实现客户端与服务器端的交互

    GWT有两种与服务端进行交互的技术:GWT RPC和基于普通AJAX的远程交互技术。这里只介绍GWT RPC技术。

    一个完整的RPC服务至少包含三个Java文件:

         1、客户端远程接口类,需要继承RemoteService类

         2、客户端远程接口类的异步类,异步类的名称格式是: 客户端远程接口类名 + Async 后缀

         3、服务器端的远程接口类,需要继承RemoteServiceServlet类和实现客户端远程接口类

        

         客户端相关的类必须位于client包及其子包下,服务器端相关的类必须位于server包及其子包下。

    1、客户端远程接口类 源码

    Java代码 复制代码 收藏代码
    1. /** 
    2.  * 客户端远程接口类需要继承RemoteService类 
    3.  */  
    4. public interface PersonService extends RemoteService {  
    5.     public Person getPerson(String name, int age) throws RuntimeException;  
    6.       
    7.     //使用内部类创建客户端远程接口类的异步类  
    8.     public static class Utils{  
    9.         private static PersonServiceAsync serviceAsync;  
    10.           
    11.         public static PersonServiceAsync getInstance(){  
    12.             if(serviceAsync==null){  
    13.                 serviceAsync = (PersonServiceAsync) GWT.create(PersonService.class);  
    14.             }  
    15.             return serviceAsync;  
    16.         }  
    17.     }  
    18. }  
    /**
     * 客户端远程接口类需要继承RemoteService类
     */
    public interface PersonService extends RemoteService {
    	public Person getPerson(String name, int age) throws RuntimeException;
    	
    	//使用内部类创建客户端远程接口类的异步类
    	public static class Utils{
    		private static PersonServiceAsync serviceAsync;
    		
    		public static PersonServiceAsync getInstance(){
    			if(serviceAsync==null){
    				serviceAsync = (PersonServiceAsync) GWT.create(PersonService.class);
    			}
    			return serviceAsync;
    		}
    	}
    }

    2、客户端远程接口类的异步类 源码

    Java代码 复制代码 收藏代码
    1. /** 
    2.  * 异步接口的方法返回值均为void,并且其对应的每个方法都比原接口多一个类型为AsyncCallback的参数 
    3.  */  
    4. public interface PersonServiceAsync {  
    5.     public void getPerson(String name, int age, AsyncCallback callback) throws RuntimeException;  
    6. }  
    /**
     * 异步接口的方法返回值均为void,并且其对应的每个方法都比原接口多一个类型为AsyncCallback的参数
     */
    public interface PersonServiceAsync {
    	public void getPerson(String name, int age, AsyncCallback callback) throws RuntimeException;
    }

    3、服务器端的远程接口类 源码

    Java代码 复制代码 收藏代码
    1. /** 
    2.  * 实现类要继承RemoteServiceServlet类 
    3.  */  
    4. public class PersonServiceImpl extends RemoteServiceServlet implements PersonService {  
    5.     public Person getPerson(String name, int age) throws RuntimeException {  
    6.         //与HTTP的交互  
    7.         HttpServletRequest request = this.getThreadLocalRequest();  
    8.         HttpServletResponse response = this.getThreadLocalResponse();  
    9.         HttpSession session = request.getSession();  
    10.           
    11.         return new Person(name, age);  
    12.     }  
    13. }  
    /**
     * 实现类要继承RemoteServiceServlet类
     */
    public class PersonServiceImpl extends RemoteServiceServlet implements PersonService {
    	public Person getPerson(String name, int age) throws RuntimeException {
    		//与HTTP的交互
    		HttpServletRequest request = this.getThreadLocalRequest();
    		HttpServletResponse response = this.getThreadLocalResponse();
    		HttpSession session = request.getSession();
    		
    		return new Person(name, age);
    	}
    }

    4、交互过程中传递的对象

    Java代码 复制代码 收藏代码
    1. /** 
    2.  * 在GWT RPC中,如果要交互的数据(方法的参数和返回值)是一个复杂类型的话, 
    3.  * 那么这个类要实现IsSerializable接口,来使该类能被正常序列化和反序列化。 
    4.  */  
    5. public class Person implements IsSerializable {  
    6.     private String name;  
    7.     private int age;  
    8.       
    9.     public Person(){  
    10.           
    11.     }  
    12.       
    13.     public Person(String name, int age){  
    14.         this.name = name;  
    15.         this.age = age;  
    16.     }  
    17.       
    18.     //省略getter、setter方法  
    19. }  
    /**
     * 在GWT RPC中,如果要交互的数据(方法的参数和返回值)是一个复杂类型的话,
     * 那么这个类要实现IsSerializable接口,来使该类能被正常序列化和反序列化。
     */
    public class Person implements IsSerializable {
    	private String name;
    	private int age;
    	
    	public Person(){
    		
    	}
    	
    	public Person(String name, int age){
    		this.name = name;
    		this.age = age;
    	}
    	
    	//省略getter、setter方法
    }

    5、GWT应用入口点类需要实现EntryPoint接口,其源码如下

    Java代码 复制代码 收藏代码
    1. public class Index implements EntryPoint {  
    2.     public void onModuleLoad() {  
    3.         Button button = new Button("Click me");  
    4.       
    5.         VerticalPanel vPanel = new VerticalPanel();  
    6.         vPanel.setWidth("100%");  
    7.         vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);  
    8.         vPanel.add(button);  
    9.   
    10.         RootPanel.get().add(vPanel);  
    11.           
    12.         //按钮的单击事件  
    13.         button.addClickListener(new ClickListener() {  
    14.             public void onClick(Widget sender) {  
    15.                 //初始化Service接口  
    16.                 PersonServiceAsync personService = PersonService.Utils.getInstance();  
    17.           
    18.                 //为Service代理描述Service接入点的URL  
    19.                 ServiceDefTarget target = (ServiceDefTarget)personService;  
    20.                 String path = GWT.getModuleBaseURL() + "PersonService";  
    21.                 target.setServiceEntryPoint(path);  
    22.           
    23.                 //发出RPC请求  
    24.                 personService.getPerson("cjm"100new AsyncCallback(){  
    25.                     public void onSuccess(Object result) {  
    26.                         Person person = (Person)result;  
    27.                         Window.alert(person.getName());  
    28.                     }  
    29.                       
    30.                     public void onFailure(Throwable caught) {  
    31.                         Window.alert(caught.getMessage());  
    32.                     }  
    33.                 });  
    34.           
    35.             }  
    36.         });  
    37.           
    38.     }  
    39. }  
    public class Index implements EntryPoint {
    	public void onModuleLoad() {
    		Button button = new Button("Click me");
        
    		VerticalPanel vPanel = new VerticalPanel();
    		vPanel.setWidth("100%");
    		vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
    		vPanel.add(button);
    
    		RootPanel.get().add(vPanel);
    		
    		//按钮的单击事件
    		button.addClickListener(new ClickListener() {
    			public void onClick(Widget sender) {
    				//初始化Service接口
    				PersonServiceAsync personService = PersonService.Utils.getInstance();
            
    				//为Service代理描述Service接入点的URL
    				ServiceDefTarget target = (ServiceDefTarget)personService;
    				String path = GWT.getModuleBaseURL() + "PersonService";
    				target.setServiceEntryPoint(path);
            
    				//发出RPC请求
    				personService.getPerson("cjm", 100, new AsyncCallback(){
    					public void onSuccess(Object result) {
    						Person person = (Person)result;
    						Window.alert(person.getName());
    					}
    					
    					public void onFailure(Throwable caught) {
    						Window.alert(caught.getMessage());
    					}
    				});
            
    			}
    		});
    		
    	}
    }

    6、在Index.gwt.xml文件中增加以下配置信息

        将RPC服务与GWT应用入口点类关联起来

    Xml代码 复制代码 收藏代码
    1. <servlet path="/PersonService" class="com.cjm.server.PersonServiceImpl"/>  
    <servlet path="/PersonService" class="com.cjm.server.PersonServiceImpl"/>

    7、在web.xml文件增加以下配置信息

    Xml代码 复制代码 收藏代码
    1. <!-- 在宿主模式下启动应用时,此servlet是必须的 -->  
    2. <servlet>  
    3.     <servlet-name>shell</servlet-name>  
    4.     <servlet-class>com.google.gwt.dev.shell.GWTShellServlet</servlet-class>  
    5. </servlet>  
    6. <servlet-mapping>  
    7.     <servlet-name>shell</servlet-name>  
    8.     <url-pattern>/*</url-pattern>  
    9. </servlet-mapping>  
    10.   
    11. <!-- RPC服务配置 -->  
    12. <servlet>  
    13.     <servlet-name>PersonService</servlet-name>  
    14.     <servlet-class>com.cjm.server.PersonServiceImpl</servlet-class>  
    15. </servlet>  
    16. <servlet-mapping>  
    17.     <servlet-name>PersonService</servlet-name>  
    18.     <url-pattern>/PersonService</url-pattern>  
    19. </servlet-mapping>
  • 相关阅读:
    kafka控制测试发送接收消息
    Kafka 启动报错java.io.IOException: Can't resolve address.
    java问题 2019
    java各种面试问题
    java 架构师
    开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽!
    Dubbo 18 问
    Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。
    XMind2TestCase 工具,提供了一个高效测试用例设计的解决方案(开源)
    windows下面安装Python和pip终极教程
  • 原文地址:https://www.cnblogs.com/zhwl/p/3600371.html
Copyright © 2011-2022 走看看