我花了很多时间来搜索这个信息“如何使SuggestBox可靠地在GWTP(Gwt平台)框架中对服务器数据库进行RPC调用”,但找不到任何答案。
事实上,有一些答案,但它们适用于不使用GWTP的人。例如,我找到了一个网站(http://jagadesh4java.blogspot.com.au/2009/03/hi-every-one-this-is-my-first-blog.html),指导代码SuggestBox& RPC&它暗示了这些课程:
-Client Side: + interface SuggestService extends RemoteService + interface SuggestServiceAsync + class Suggestions implements IsSerializable, Suggestion + class SuggestionOracle extends SuggestOracle -Server Side: + class SuggestServiceImpl extends RemoteServiceServlet implements SuggestService
我试图跟进该网站,但我收到了错误:
[WARN] failed SelectChannelConnector@127.0.0.1:8888 java.net.BindException: Address already in use: bind..........
上述指南显然不适用于使用GWTP的用户。
我的任务是我有一个包含200k英文单词的词典&我想要一个建议框,当用户输入任何字符或单词时,它会查找到DB&因此建议。例如,当用户键入“c”时会显示“猫,车,切割等”,在输入“汽车”时会显示“汽车服务”,“碳”等。
所以我提出了自己的解决方案,即使它有效,但我觉得我做得不对。我的解决方案非常简单,我只需将数据从DB下载并放大。将它们添加到MultiWordSuggestOracle中。每当它在DB中找到一个单词列表时,它就不会清除旧数据,只是继续将新列表添加到MultiWordSuggestOracle中。但是,每次用户键入char时,我的程序都不会经常调用DB,但只有在wordInTheMultiWordSuggestOracleList.indexOf(suggestBox.getText(),0)>0
时才会调用DB。但是,无法在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”按钮时才显示建议。例如,当我输入单词“car”然后没有建议的列表弹出窗口时,它只会弹出“汽车服务,汽车销售等”,当我点击退格按钮时。
那么,你可以评估我的解决方案吗?我觉得我做得不对。如果我做得不对,你可以为GWTP框架提供一个SuggestBox PRC吗?
非常重要的注意事项:
如何构建可靠的SuggestBox PRC,以防止我们自己的服务器上的拒绝服务攻击?
如果许多人在快速输入建议框中产生了过多的电话怎么办?
其实我刚发现一个错误: SQL例外:数据源拒绝建立连接,来自服务器的消息:“连接太多” - &gt;所以我的解决方案一定有问题
我知道为什么我收到“Too many connections”错误。例如,当我在“建议”框中键入“ambassador”时,&amp;我看到我的服务器连续9次拨打Db。 第1次调用,它将搜索任何单词,如'a%' 在第二次通话时,它会搜索任何像'am%'这样的单词 -3,电话,它将搜索任何像'amb%'
这样的单词第一个问题是它一次创建了太多的调用,第二个问题是第一次调用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?spec=svn1310&r=1310)
如果您可以提供使用RPCSuggestOracle.java的示例,那将非常棒。 我希望你的回答能够帮助很多其他人。
答案 0 :(得分:0)
有一篇来自Lombardi Development的旧的鼓舞人心的博客文章,我记得几乎解决了你正在寻找的所有问题。我花了一段时间才找到它,但幸运的是,它已经被移动了!资料来源可用。 Have a look
虽然年纪不大,但该帖子中的内容仍然适用。特别是:
http
连接); 我想到的其他事情是:
Timer
来模拟快速写入器的一点延迟,所以你只需要稍微调用服务器(可能是过度优化,但仍然是个想法); SuggestionDisplay
,只显示第一个,比如50个建议,然后滚动,所有其他建议使用增量方式相同的输入字符串。无法从GWTP部分说出任何内容,我从未使用过它。但AFAICS似乎就像旧的gwt-dispatch一样,GWT-RPC +调度机制(命令模式)。不应该难以使用而不是香草GWT-RPC。
另请参阅上面其中的其他2篇文章。可能包含一些其他有用的提示。
答案 1 :(得分:0)
使用key Up处理程序代替按键处理程序可能会解决您的问题。 这是因为在渲染角色之前会触发keyDown事件。