gwt-ext httpProxy

最近经朋友介绍了解了GWT-EXT,看到了网上的Demo,非常炫!对于不会美工或者对js敏感的Web开发人员来说这是一个非常有价值的技术,这是看了Demo后的第一感觉。但看代码之后却又发现,原来java Web开发人员不一定就能很快就掌握它,因为它的编程思想与java web开发是完全不同的,而更像java swing。因为这是一个Ajax技术,使用的是异步请求,不需要在一次请求后重绘页面,只需将返回的结果在UI中展示就行了,至于中间的细节还有很多地方需要进一步的学习,现在对于简单的返回结果处理还是很模糊的。至于表单提交还没有相关的编写,在这里就不分析了。

    GWT-EXT是将GWT和EXT整合起来的,就我现在的了解,GWT提供了RPC服务供client调用,而EXT是UI端的更多点,由于没有单独使用其中任何一种技术,所以各自的特性不了解。在RPC中,现在只会最简单的调用,就是在client端建一个需要服务(Service)接口和一个异步接口(Async Service),这两个接口的命名最好是规范的,如有UserService接口,那对应的异步就是AsyncUserService,看过文档好像不一致的话将不能正确调用,因为在获取异步服务时是:
    AsyncUserService userService = (AsyncUserService)GWT.create(UserService.class),它是通过GWT来获取异步服务GWT会根据传入的class来创建对应的服务,如传入UserService则GWT就创建一个AsyncUserService,如果命名不一致的话将会在类型转换的时候抛错的(没有验证过,不过应该是这样的)。至于GWT的底层怎么创建异步服务的还没有研究过^_^

    在RPC中最让我迷糊的地方是当获取到处理结构后该怎么进行下一步处理。在client端调用异步服务后有一个AsyncCallback,它有 onFailure()和onSuccess()方法,分别对应调用服务失败和成功后的相关处理。在onFailure中的参数是Throwable,是调用服务后的异常,如网络连接失败、服务无法调用以及定义的异常信息等等,在定义异常的时候需要注意的。在客户端不能获取如SQLException这样的异常,实质原因应该是GWT在将Java向js转换时支持的只是java.lang.*和java.util.*(这里有待确定)中部分类。其实在转换过程中有很多限制的,如java的反射机制就不能使用的。在捕获异常后可以进行相关处理了,如弹出一个消息框“保存失败”等,个人觉得失败的处理应该是比较简单的。麻烦就走onSuccess中。在处理成功后如果有很多的逻辑要处理,这里的思路很乱,还没有整理好,等清晰后再补上.........


    在任何系统中,信息的展示永远都是一个重要的部分,从某种意义上来说超过了数据的提交。而在GWT-EXT中的数据展示和普通的web网站展示是有这本质区别的。在传统的web中,每次请求都会重新加载页面展示逻辑,并且使用HttpRequest就完全能解决。而对gwt-ext来说就不是这样了,当然它也可以通过RPCManage来进行Http请求,由于还没有应用过,以后再说。这里主要说说使用HttpProxy来获取普通Servlet及其他任何能返回json、xml格式的(虽然在HttpProxy文档中只提了xml,但json也是支持的),如php,aspx等。

    HttpProxy是DataProxy的子类,DataProxy:This class is an abstract base class for implementations which provide retrieval of unformatted data objects.
 * DataProxy implementations are usually used in conjunction with an implementation of {@link com.gwtext.client.data.Reader}
 * (of the appropriate type which knows how to parse the data object) to provide a block of {@link com.gwtext.client.data.Record}'s
 * to a {@link Store}.
它们是在从服务器获取数据后怎么处理的就不知道了,因为每次追踪下去都到了navtive方法中去了,对js实在是有点敏感,所以其中的实现仍是一个很大的迷.......这里就讲讲怎么使用HttpProxy吧。


    由于是获取服务器上动态数据,因此参照了gwt-ext的showcase中的Grid With Remote Paging,但由于其是获取ext论坛的数据,因为跨域的原因使用的是ScriptProxy,而在同一域下请求则使用HttpProxy(为什么这样就要问问  Sanjiv  Jivan了)。服务器返回xml或者json数据就可以了,有几个要注意的地方:
    1.servlet中将response.setContentType("application/x-json"),编码而 UTF-8;
    2.在使用HttpProxy时指定请求GET方法:
       HttpProxy proxy = new HttpProxy(GWT.getModuleBaseURL()+"test",Connection.GET);
    3.正确处理获取后的数据。我就是将reader.setRoot()设置错误而没有数据显示。所以如果使用firebug看到             有返回数据却没有显示的时候请仔细检查代码,说不定就是哪个地方写错了。(我就在这上面花了4H),切记!

以下是我的相关代码:
servlet:
    .....
    List<User> list = new ArrayList<User>();
    list.add(new User("1","lkfsa", "12fsda3"));
    list.add(new User("2", "lk","123"));
    list.add(new User("3","lkfsda", "12fdsa3"));
    list.add(new User("4","lkfsaf", "123"));
    list.add(new User("5", "lk","sdfafsda"));
    list.add(new User("6","lk", "12fsda3"));
     response.setCharacterEncoding("UTF-8");
    response.setContentType("application/x-json");
    PrintWriter out = response.getWriter();
    out.write(JSONUtil.generate(list, 6).toString());
    out.flush();
    .....
说明:User实现了IsSerializable(GWT要求,不过好像1.5之后不需要了??)。SONUtil.generate(list, 6).toString()是使用了json-lib.jar中的java向json转换工具实现如下:
public static JSONObject generate(List<?> list, int count) {
    Map<String, Object> map = new Hashtable<String, Object>();
    map.put("totalCount", count);
    map.put("user", list);
    return JSONObject.fromObject(map);
}
totalCount和User分别是 JsonReader reader = new JsonReader(recordDef);中需要使用到的。


ui:
    HttpProxy proxy = new HttpProxy(GWT.getModuleBaseURL()+"test",com.gwtext.client.core.Connection.GET);
        final RecordDef recordDef = new RecordDef(new FieldDef[]{
                new StringFieldDef("name", "name"),
                new StringFieldDef("pass", "pass"),
        });
        JsonReader reader = new JsonReader(recordDef);
         reader.setRoot("user");
        reader.setId("id"); 
        reader.setTotalProperty(" totalCount");
        final Store store = new Store(proxy, reader,false);   
        store.load();
ColumnConfig topicColumn = new ColumnConfig("姓名", "name",
100);
topicColumn.setCss("white-space:normal;");

ColumnConfig authorColumn = new ColumnConfig("密码", "pass",
100);
ColumnConfig actionColumn = new ColumnConfig("操作", "action",
100);
actionColumn.setRenderer(new Renderer() {  
            public String render(Object value, CellMetadata cellMetadata, Record record,  
                                 int rowIndex, int colNum, Store store) {  
                return "<img class=\"delete\" src=\"js/resources/images/gray/window/icon-error.gif\"/>&nbsp;&nbsp;" +
                 "<img class=\"edit\" src=\"images/icons/fam/cross.gif\"/>";  
            }  
        });  
ColumnModel columnModel = new ColumnModel(
new ColumnConfig[] { topicColumn, authorColumn ,actionColumn});

grid = new GridPanel();
grid.setWidth(800);
grid.setHeight(300);
grid.setTitle("用户管理");
grid.setStore(store);
grid.setColumnModel(columnModel);
grid.setTrackMouseOver(true);
grid.setLoadMask(true);
grid.setSelectionModel(new RowSelectionModel());
grid.setFrame(true);
grid.setStripeRows(true);
grid.setIconCls("grid-icon");
grid.addListener(new PanelListenerAdapter() {
public void onRender(Component component) {
store.load(0, 5);
}
});
PagingToolbar pagingToolbar = new PagingToolbar(store);
        pagingToolbar.setPageSize(5);
        pagingToolbar.setDisplayInfo(true);
        pagingToolbar.setDisplayMsg("Displaying topics {0} - {1} of {2}");
        pagingToolbar.setEmptyMsg("No topics to display");

        pagingToolbar.addSeparator();
        ToolbarButton toolbarButton = new ToolbarButton("添加用户");
        toolbarButton.setStyle("");
        pagingToolbar.addButton(toolbarButton);
        toolbarButton.addListener(new ButtonListenerAdapter(){
         public void onClick(Button button, EventObject e) {
         addUser();
            }
        });
        
        
        grid.setBottomToolbar(pagingToolbar);

        grid.addListener(new PanelListenerAdapter() {
            public void onRender(Component component) {
                store.load(0, 5);
            }
        });
        
        grid.addGridCellListener(new GridCellListenerAdapter() {  
            public void onCellClick(GridPanel grid, int rowIndex, int colIndex, EventObject e) {  
                if (grid.getColumnModel().getDataIndex(colIndex).equals("action") &&  
                        e.getTarget(".delete", 1) != null) {  
                 window = new Window();
                 window.setTitle("删除用户");
                 window.setWidth(200);
                 window.setHeight(200);
                 window.show();
                }  else if (grid.getColumnModel().getDataIndex(colIndex).equals("action") &&  
                        e.getTarget(".edit", 1) != null){
                 Record r = grid.getStore().getRecordAt(rowIndex);
                 editUser(r);
                } 
            }  
        }); 


看到这个代码大家应该有点熟悉的,因为很多就是从showcase demo中copy的。红色字体的是我出过错的地方


OK,暂时写到这里吧!!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值