GWT Java rpc 调用工作;但是,替换 GWTBootstrap - rpc 调用不起作用
Posted
技术标签:
【中文标题】GWT Java rpc 调用工作;但是,替换 GWTBootstrap - rpc 调用不起作用【英文标题】:GWT Java rpc call working; however, replacement GWTBootstrap - rpc call not working 【发布时间】:2017-04-16 00:37:39 【问题描述】:我刚刚开始使用引导程序来转换现有的 GWT 项目。原始 rpc 调用在以下代码中工作。但是,替换直接放在原始代码和“连接失败 - 请重试”之后。触发时在屏幕上显示为弹出窗口。日志中没有任何内容。窗口显示返回正确的值。当我启动引导程序时,我将替换原始代码。
package org.AwardTracker.client;
/**
* The purpose of this View is to allow the account holder
* to login to their account using an Account Name and password.
*/
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.event.logical.shared.AttachEvent.Handler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
public class LoginView extends Composite
private DBConnectionAsync rpc;
final VerticalPanel verticalPanel = new VerticalPanel();
final HorizontalPanel horizontalPanel = new HorizontalPanel();
final Label lblWelcomeToThe = new Label("Welcome to the Award Tracker login page.\r\n\r\nPlease Sign into your account.");
final FlexTable flexTable = new FlexTable();
final Label lblAccountName = new Label("*Account name:");
final Label lblAccountName2 = new Label("(username (e.g., email))");
final Label lblPassword = new Label("*Password:");
private PasswordTextBox passwordTextBox;
private TextBox textBoxAccountName;
int loginAttempt = 0;
public String youthMemberID = null;
int youthMembersLinked = 0;
public String accountID = null;
public String accountLevel = null;
public String scoutGroup = null;
public String scoutGroupSection = null;
public LoginView()
verticalPanel.addAttachHandler(new Handler()
public void onAttachOrDetach(AttachEvent event)
if (event.isAttached())
rpc = (DBConnectionAsync) GWT.create(DBConnection.class);
ServiceDefTarget target = (ServiceDefTarget) rpc;
String moduleRelativeURL = GWT.getModuleBaseURL() + "mysqlConnection";
target.setServiceEntryPoint(moduleRelativeURL);
//Display the login page
//This is the nice green background with the small Scout logo
verticalPanel.setStyleName("gwt-Scout-Background");
verticalPanel.setWidth("100%");
verticalPanel.setHeight("100%");
verticalPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
verticalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
verticalPanel.setBorderWidth(0);
//This is the nice green background with the small Scout logo
horizontalPanel.setStyleName("gwt-Scout-Background");
horizontalPanel.setWidth("100%");
horizontalPanel.setHeight("100%");
horizontalPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
horizontalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
verticalPanel.add(horizontalPanel);
//Display the welcome message
lblWelcomeToThe.setStyleName("gwt-Label-Login");
verticalPanel.add(lblWelcomeToThe);
lblWelcomeToThe.setWidth("321px");
verticalPanel.add(flexTable);
verticalPanel.setCellHorizontalAlignment(flexTable, HasHorizontalAlignment.ALIGN_CENTER);
//Display the Account Name text and text box
lblAccountName.setStyleName("gwt-Label-Login");
flexTable.setWidget(0, 0, lblAccountName);
//lblAccountName.setSize("110px", "16px");
flexTable.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_RIGHT);
textBoxAccountName = new TextBox();
flexTable.setWidget(0, 1, textBoxAccountName);
textBoxAccountName.setSize("155px", "20px");
//Display the Account Name hint
lblAccountName2.setStyleName("gwt-Label-Login");
flexTable.setWidget(0, 2, lblAccountName2);
//lblAccountName2.setSize("200px", "16px");
flexTable.getCellFormatter().setHorizontalAlignment(0, 2, HasHorizontalAlignment.ALIGN_LEFT);
//Display the password text and text box.
lblPassword.setStyleName("gwt-Label-Login");
flexTable.setWidget(1, 0, lblPassword);
//lblPassword.setSize("73px", "16px");
flexTable.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
passwordTextBox = new PasswordTextBox();
flexTable.setWidget(1, 1, passwordTextBox);
passwordTextBox.setSize("155px", "20px");
//The following code will be replaced when the bootstrap code is working
//Display the sign in button and handle the click event
Button btnSignIn2 = new Button("Sign In");
btnSignIn2.addClickHandler(new ClickHandler()
public void onClick(ClickEvent event)
//Store whether details have been entered for error handling
//textBoxAccountName.setText("accountName");
Integer tracker = 0;
if (textBoxAccountName.getText().length() == 0)
tracker = tracker + 1;
if (passwordTextBox.getText().length() == 0)
tracker = tracker + 2;
//Check if details have been entered and display an error if
//they have not been entered.
if (tracker == 1)
textBoxAccountName.setStyleName("gwt-TextBox-Error");
passwordTextBox.setStyleName("gwt-TextBox");
Window.alert("Please enter your Account name.");
else if (tracker == 2)
textBoxAccountName.setStyleName("gwt-TextBox");
passwordTextBox.setStyleName("gwt-TextBox-Error");
Window.alert("Please enter your Password.");
else if (tracker == 3)
textBoxAccountName.setStyleName("gwt-TextBox-Error");
passwordTextBox.setStyleName("gwt-TextBox-Error");
Window.alert("Please enter your Account name and Password.");
else
//If the required details have been entered then search the database for a match
textBoxAccountName.setStyleName("gwt-TextBox");
passwordTextBox.setStyleName("gwt-TextBox");
AsyncCallback<AccountGroup> callback = new AuthenticationHandler<AccountGroup>();
rpc.authenticateAccountGroup(textBoxAccountName.getText(), passwordTextBox.getText(), callback);
);
flexTable.setWidget(3, 1, btnSignIn2);
//The following code is for bootstrap
RootPanel.get("payPalDonate");
RootPanel.get("payPalDonate").setVisible(true);
RootPanel.get("login"); //From bootstrap
RootPanel.get("login").setVisible(true);
Button btnSignIn = Button.wrap(Document.get().getElementById("submit")); //From bootstrap
final TextBox textBoxAccountName = TextBox.wrap(Document.get().getElementById("accountName")); //From bootstrap
final PasswordTextBox passwordTextBox = PasswordTextBox.wrap(Document.get().getElementById("enterPassword")); //From bootstrap
//Display the sign in button and handle the click event
btnSignIn.addClickHandler(new ClickHandler()
public void onClick(ClickEvent event)
//Store whether details have been entered for error handling
Integer tracker = 0;
if (textBoxAccountName.getText().length() == 0)
tracker = tracker + 1;
if (passwordTextBox.getText().length() == 0)
tracker = tracker + 2;
//Check if details have been entered and display an error if
//they have not been entered.
if (tracker == 1)
textBoxAccountName.setStyleName("gwt-TextBox-Error");
passwordTextBox.setStyleName("gwt-TextBox");
Window.alert("Please enter your Account name.");
else if (tracker == 2)
textBoxAccountName.setStyleName("gwt-TextBox");
passwordTextBox.setStyleName("gwt-TextBox-Error");
Window.alert("Please enter your Password.");
else if (tracker == 3)
textBoxAccountName.setStyleName("gwt-TextBox-Error");
passwordTextBox.setStyleName("gwt-TextBox-Error");
Window.alert("Please enter your Account name and Password.");
else
//If the required details have been entered then search the database for a match
textBoxAccountName.setStyleName("gwt-TextBox");
passwordTextBox.setStyleName("gwt-TextBox");
Window.alert("textBoxAccountName.getText() = " + textBoxAccountName.getText());
Window.alert("passwordTextBox.getText() = " + passwordTextBox.getText());
AsyncCallback<AccountGroup> callback = new AuthenticationHandler<AccountGroup>();
rpc.authenticateAccountGroup(textBoxAccountName.getText(), passwordTextBox.getText(), callback);
);
);
initWidget(verticalPanel);
class AuthenticationHandler<T> implements AsyncCallback<AccountGroup>
public void onFailure(Throwable ex)
System.out.println("RPC call failed - AuthenticationHandler - Notify Administrator.");
Window.alert("Connection failed - please retry.");
public void onSuccess(AccountGroup result)
AccountGroup account = result;
if (account == null)
//Only three invalid login attempts are allowed. Disable the account after
//three invalid login attempts.
if (loginAttempt > 2)
AsyncCallback<Void> callback = new DisableHandler<Void>();
rpc.disableAccount(textBoxAccountName.getText(), 0, callback);
else
Window.alert("Incorrect Account name or Password entered. Please try again.");
else
if (account.getLevel() == null)
Window.alert("Your account has not yet been set up. Please contact your administrator.");
else
if (account.getArchived() != null)
Window.alert("Your account has been archived. Please contact your administrator.");
else
if (account.getEnabled() == 1)
accountLevel = account.getLevel();
accountID = account.getAccountId();
scoutGroup = account.getScoutGroupId();
scoutGroupSection = account.getGroupSection();
//Is a Leader or Administrator.
//Store the LoginView data for use in subsequent Views.
AsyncCallback<ViewData> callback2 = new ViewDataStoreHandler<ViewData>();
rpc.setViewData(account.getAccountId(), account.getLevel(), null, null, null,
scoutGroup, null, 0, scoutGroupSection, null, null, callback2);
else
//The account has had three or more invalid passwords entered and has been disabled.
Window.alert("Account is disabled. Please contact your administrator.");
class ViewDataStoreHandler<T> implements AsyncCallback<ViewData>
public void onFailure(Throwable ex)
System.out.println("RPC call failed - ViewDataStoreHandler - Notify Administrator.");
Window.alert("Connection failed - please retry.");
public void onSuccess(ViewData result)
//The details have been stored
RootPanel.get("payPalDonate").setVisible(false);
RootPanel.get("payPalDonate").clear();
RootPanel.get("login").setVisible(false);
RootPanel.get("login").clear();
History.newItem("selectPerson", true);
class DisableHandler<T> implements AsyncCallback<Void>
public void onFailure(Throwable ex)
System.out.println("RPC call failed - DisableHandler - Notify Administrator.");
Window.alert("Connection failed - please retry.");
public void onSuccess(Void result)
Window.alert("You have exceeded your password tries and your Account has been disabled. Please contact your administrator.");
当我使用以下方法检查密码时,我发现在服务器端:
if (stored_hash == null)
System.out.println("Incorrect account.");
account = null;
else
//Check that the hashed value of the password equals the stored hashed value
//If it does not then account will be set to null.
if (BCrypt.checkpw(pass, stored_hash))
System.out.println("Success!");
else
System.out.println("Incorrect password.");
account = null;
//Done
return account;
如果帐户不正确(即未使用 BCrypt),则不会返回错误。但是,当使用 BCrypt 时(即无论密码是否正确,帐户都是正确的)则返回错误代码(Throwable value = com.google.gwt.user.client.rpc.StatusCodeException: 0)
然后我找到Getting com.google.gwt.user.client.rpc.StatusCodeException: 0 in GWT:
我发现如果你在服务器上挂起一个 rpc 调用 (Thread.wait()) 并且浏览器被刷新然后在客户端再次加载页面之前它会调用等待回调的 onFailure 方法上面提到的状态代码表明它起源于客户端,或者它是非特定捕获异常的通用错误代码。
我的浏览器正在刷新!那么现在的问题是如何阻止它刷新?
【问题讨论】:
嗨 Glyn,我相信Connection failed - please retry.
消息显示在 AuthenticationHandler
回调中,但您没有显示其代码。也不清楚哪些元素来自引导程序。你能提供一个Minimal, Complete, and Verifiable example吗?
OK,所以代码在onFailure()
方法中命中Window.alert("Connection failed - please retry.");
行。它位于AuthenticationHandler
、ViewDataStoreHandler
或DisableHandler
中。你能检查Throwable
的值吗?
嗨 Adam,它在 AuthenticationHandler 中。我添加了 "Window.alert("Throwable value = " + ex);"在“public void onFailure(Throwable ex) ”下,结果为“Throwable value = com.google.gwt.user.client.rpc.StatusCodeException: 0”
嗨,亚当,我读到:***.com/questions/12624320/…。我认为这可能与最后一条评论有关“我发现如果你在服务器上挂起一个 rpc 调用 (Thread.wait()) 并且浏览器在客户端刷新之前就在它再次加载页面之前它将调用 onFailure 方法”,因为页面确实刷新并且我输入的数据不显示。我接下来要解决这个问题。听起来我可能需要先处理刷新。
顺序是:我输入详细信息;点击“登录”;详细信息由 Window.alert 显示;异常由 Window.alert 显示;屏幕刷新(我输入的详细信息不再显示)。
【参考方案1】:
经过大量调查,我发现问题不在于 Java 代码。当您从 gwtBootstrap 中的表单返回数据时,如果刷新并返回“Throwable value = com.google.gwt.user.client.rpc.StatusCodeException: 0”,在 GWTJava 中将其作为错误代码拾取。所以不要在 html 中使用表单使用 div。完整的解释和解析在How to stop GWTBootstrap3 from refreshing and loosing my input and returning an error code
【讨论】:
以上是关于GWT Java rpc 调用工作;但是,替换 GWTBootstrap - rpc 调用不起作用的主要内容,如果未能解决你的问题,请参考以下文章
分派传入 RPC 调用时出现异常 java.lang.NoSuchMethodError: com.google.gwt.user.server.rpc.RPCRequest