Glyn
Glyn

Reputation: 1995

GWT Java rpc call working; however, replacement GWTBootstrap - rpc call not working

I am just starting to use bootstrap to convert an existing GWT project. The original rpc call works in the following code. However, the replacement is placed straight after the original code and "Connection failed - please retry." is displayed on the screen as a pop-up when triggered. There is nothing in the log. The window displays return the correct values. I will replace the original code when I get the bootstrap working.

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.");
        }
    }

}

I have found that on the server side when I check the password using:

    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;

If the account is incorrect (i.e., BCrypt is not used) then there is no error returned. However, when BCrypt is used (i.e., the account is correct whether or not the password is correct) then an error code is returned (Throwable value = com.google.gwt.user.client.rpc.StatusCodeException: 0)

I then found Getting com.google.gwt.user.client.rpc.StatusCodeException: 0 in GWT:

I have found that if you hang an rpc call on the server (Thread.wait()) and the browser is refreshed then on the client side just before it loads the page again it will call the onFailure method of the waiting callback with the above mentioned status code which suggests it orginates in the client or that it is a generic error code for non-specific caught exceptions.

My browser is refreshing! So the question now is how to stop it refreshing?

Upvotes: 0

Views: 171

Answers (1)

Glyn
Glyn

Reputation: 1995

After much investigation I found that the issue is not with the Java code. When you return data from a form in gwtBootstrap if refreshes and returns "Throwable value = com.google.gwt.user.client.rpc.StatusCodeException: 0" which is picked up as an error code in GWTJava. So do not use a form use div in the HTML. The full explanation and resolution is at How to stop GWTBootstrap3 from refreshing and loosing my input and returning an error code

Upvotes: 0

Related Questions