2

我花了很多时间搜索此信息“如何使 SuggestBox 在 GWTP(Gwt 平台)框架中可靠地对服务器数据库进行 RPC 调用”,但找不到任何答案。

事实上,有一些答案,但它们是针对不使用 GWTP 的人的。例如,我找到了一个网站 ( http://jagadesh4java.blogspot.com.au/2009/03/hi-every-one-this-is-my-first-blog.html ) 指导编码 SuggestBox & RPC &它建议这些课程:

    -客户端:
    + 接口 SuggestService 扩展 RemoteService
    + 接口 SuggestServiceAsync
    + 类 Suggestions 实现 IsSerializable、Suggestion
    + 类 SuggestionOracle 扩展了 SuggestOracle

    -服务器端:
    + 类 SuggestServiceImpl 扩展 RemoteServiceServlet 实现
    建议服务

我试图跟进该网站,但出现错误:

    [警告] SelectChannelConnector@127.0.0.1:8888 失败
    java.net.BindException:地址已在使用中:绑定............

上面的指南显然不适合使用 GWTP 的人。

我的任务是我有一本包含 200k 英语单词的字典,我想要一个建议框,当用户键入任何字符或单词时,它会查找 DB 并相应地提出建议。例如,当用户输入“c”时会提示“cat, car, cut, etc”,输入“car”时会提示“car service”、“carbon”等。

所以我想出了自己的解决方案,即使它有效,但我觉得我做的不对。我的解决方案非常简单,我只需将数据库中的数据下载下来并将它们添加到 MultiWordSuggestOracle 中。每当它在 DB 中找到一个单词列表时,它不会清除旧数据,而是继续将新列表添加到 MultiWordSuggestOracle 中。但是,我的程序不会在每次用户键入字符时不断调用 DB,但只有在wordInTheMultiWordSuggestOracleList.indexOf(suggestBox.getText(),0)>0. 但是,MultiWordSuggestOracle中没有办法循环每个字符串,所以我用来 List<String> accumulatedSuggestedWordsList=new ArrayList<String>()存储数据。请参阅前:

    private final MultiWordSuggestOracle mySuggestions = new MultiWordSuggestOracle();
    private List<String> accumulatedSuggestedWordsList=new ArrayList<String>();

    private void updateSuggestions(List<String> suggestedWordsList) {
        // call some service to load the suggestions
        for(int i=0;i<suggestedWordsList.size(); i++){
            mySuggestions.add(suggestedWordsList.get(i));
            accumulatedSuggestedWordsList.add(suggestedWordsList.get(i));
        }
    }

    @Override
    protected void onBind() {
        super.onBind();

        final SuggestBox suggestBox = new SuggestBox(mySuggestions);

        getView().getShowingTriplePanel().add(suggestBox);


        suggestBox.addKeyDownHandler(new KeyDownHandler(){

            @Override
            public void onKeyDown(KeyDownEvent event) {
                // TODO Auto-generated method stub
                String word=suggestBox.getText();
                int index=-1;
                for(int i=0; i<accumulatedSuggestedWordsList.size();i++){
                    String w=accumulatedSuggestedWordsList.get(i);
                    index=w.indexOf(word,0);
                    if(index>0)
                        break;
                }
                if(index==0 || index==-1){
                    GetWordFromDictionary action=new      tWordFromDictionary(suggestBox.getText());
                    action.setActionType("getSuggestedWords");
                    dispatchAsync.execute(action, getWordFromDictionaryCallback);
                }

            }


        });
    }
    private AsyncCallback<GetWordFromDictionaryResult> getWordFromDictionaryCallback=new AsyncCallback<GetWordFromDictionaryResult>(){

        @Override
        public void onFailure(Throwable caught) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onSuccess(GetWordFromDictionaryResult result) {
            // TODO Auto-generated method stub
            List<String> suggestedWordsFromDictionaryList=result.getSuggestedWordsFromDictionaryList();
            updateSuggestions(suggestedWordsFromDictionaryList);

        }

    };

结果:它有效,但只有在我键入“Backspace”按钮时才会显示建议。例如,当我输入“汽车”一词时,没有弹出建议列表,当我点击退格按钮时,它只会弹出“汽车服务、汽车销售等”。

那么,您可以评估我的解决方案吗?我觉得我做得不对。如果我没有做正确的事情,你可以为 GWTP 框架提供一个 SuggestBox PRC 吗?



非常重要的注意事项:

如何构建可靠的 SuggestBox PRC 以防止对我们自己的服务器进行拒绝服务攻击?

如果许多人在建议框中快速输入过多的电话怎么办?

其实我只是发现一个错误: SQL Exception: Data source denied setup of connection, message from server: "Too many connections" --> 所以我的解决方案一定有问题

我知道为什么会出现“连接太多”错误。例如,当我在建议框中键入“大使”时,我看到我的服务器连续调用 Db 9 次。-1st call,它会搜索任何像'a%'这样的词 -2nd call,它会搜索像'am%'这样的任何词 -3nd call,它会搜索像'amb%'这样的任何词

第一个问题是它在 1 次创建了太多调用,第二次调用无效,因为第一次调用like 'a%'可能已经包含将在第二次调用的单词like 'am%',因此它复制了数据。问题是如何编码来避免这种无效性。

有人建议使用 RPCSuggestOracle.java ( https://code.google.com/p/google-web-toolkit-incubator/source/browse/trunk/src/com/google/gwt/widgetideas/client/RPCSuggestOracle.java?规格=svn1310&r=1310 )

如果你能提供一个使用 RPCSuggestOracle.java 的例子,那就太好了。我希望你的回答能帮助很多其他人。

4

2 回答 2

0

使用 key Up 处理程序而不是 key down 处理程序可能会解决您的问题。这是因为在渲染字符之前触发了 keyDown 事件。

于 2013-07-02T11:05:29.567 回答
0

我记得有一篇来自 Lombardi Development 的鼓舞人心的旧博客文章,它几乎解决了您正在寻找的所有问题。我花了一段时间才发现这一点,但幸运的是,它只是被移动了!并且来源是可用的。看看

虽然已经老了,但那篇文章中的内容仍然适用。尤其是:

  • 使用单个连接来避免请求爆炸,并为其他任务留出其他连接(即避免使用所有 2 到 8 个最大并行浏览器http连接);
  • 重用来自先前请求的数据(即,如果您的请求是前一个请求的子字符串,您可能已经有了建议,因此只需在客户端过滤它们)。

我想到的其他事情是:

  • 在快速编写器的情况下使用 aTimer来模拟一点延迟,所以你只在一点之后调用服务器(可能是过度优化,但仍然是一个想法);
  • 允许仅在最小输入长度(例如,最少 3 个字符)上获取建议。如果您有很多可能的建议,则返回的数据即使解析也可能很昂贵,特别是如果 - 对于搜索 - 您决定采用contains而不是startswith策略;
  • 如果您仍然有大量建议,您可以尝试实现一个延迟加载SuggestionDisplay,它只是向您显示第一个,例如 50 条建议,然后在滚动时使用相同的输入字符串以增量方式显示所有其他建议。

不能从 GWTP 部分说什么,我从未使用过它。但是AFAICS看起来就像旧的 gwt-dispatch 一样的 GWT-RPC + 调度机制(命令模式)。代替普通的 GWT-RPC 应该不难使用。

还可以查看上面链接中的其他 2 篇之前的文章。可能包含其他一些有用的提示。

于 2013-06-28T09:51:38.903 回答