Your message has been sent.
This article has been saved to your account.
Go to my account
This article has been emailed to your Kindle.
Send this article
Complete the form below to send this article, Working with Entities in Google Web Toolkit 2, to a friend (or to yourself). We will never share your details (or your friend's) with anyone. For more information, read our Privacy Policy.
GWT 2 radically improves the web experience for users by using the existing Java tools to build a no-compromise AJAX for any modern browser. It provides a solid platform so that the other great libraries can be built on top of the GWT. Creating web applications efficiently and making them impressive, however, is not as easy as it sounds. Writing web applications for multiple browsers can be quite tasking. In addition, building, reusing, and maintaining large JavaScript code bases and AJAX components can be difficult.
In the previous article, Communicating with Server using Google Web Toolkit RPC, we saw the communication between the server and the client in GWT RPC. In this article by Shamsuddin Ahammad, author of Google Web Toolkit 2 Application Development Cookbook, we will cover:
- Finding an entity
- Updating an entity
- Deleting an entity
- Managing a list for RPC
- Authenticating a user through username and password
| Read more about this book |
(For more resources on GWT, see here.)
Finding an entity
In this recipe, we are going to write the code to find an entity. From the client side, the ID of the entity will be passed to the server; the server will find the entity in the database using the JPA controller class, and then return the entity to the client in order to display it.
How to do it...
- Declare the following method in the GWTService interface:
public BranchDTO findBranch(int branchId);
- Declare the asynchronous version of the above method in GWTServiceAsync interface
public void findBranch(int branchId, AsyncCallback<BranchDTO>
asyncCallback); - Implement this method in GWTServiceImpl class
@Override
public BranchDTO findBranch(int branchId)
{
Branch branch=branchJpaController.findBranch(branchId);
BranchDTO branchDTO=null;
if(branch!=null)
{
branchDTO=new BranchDTO();
branchDTO.setBranchId(branch.getBranchId());
branchDTO.setName(branch.getName());
branchDTO.setLocation(branch.getLocation());
}
return branchDTO;
} - Create a callback instance in client side (BranchForm in this case) to call this method as shown in the following code:
final AsyncCallback<BranchDTO> callbackFind =
new AsyncCallback<BranchDTO>()
{
@Override
public void onFailure(Throwable caught)
{
MessageBox messageBox = new MessageBox();
messageBox.setMessage("An error occured!
Cannot complete the operation");
messageBox.show();
clear();
}
@Override
public void onSuccess(BranchDTO result)
{
branchDTO=result;
if(result!=null)
{
branchIdField.setValue(""+branchDTO.getBranchId());
nameField.setValue(branchDTO.getName());
locationField.setValue(branchDTO.getLocation());
}
else
{
MessageBox messageBox = new MessageBox();
messageBox.setMessage("No such Branch found");
messageBox.show();
clear();
}
}
}; - Write the event-handling code for the find button as follows:
findButton.addSelectionListener(new
SelectionListener<ButtonEvent>()
{
@Override
public void componentSelected(ButtonEvent ce)
{
MessageBox inputBox = MessageBox.prompt("Input",
"Enter the Branch ID");
inputBox.addCallback(new Listener<MessageBoxEvent>()
{
public void handleEvent(MessageBoxEvent be)
{
int branchId = Integer.parseInt(be.getValue());
((GWTServiceAsync)GWT.create(GWTService.class)).
findBranch(branchId,callbackFind);
}
});
}
});
How it works...
Here, the steps for calling the RPC method are the same as we had done for the add/save operation. The only difference is the type of the result we have received from the server. We have passed the int branch ID and have received the complete BrachDTO object, from which the values are shown in the branch form.
Updating an entity
In this recipe, we are going to write the code to update an entity. The client will transfer the DTO of updated object, and the server will update the entity in the database using the JPA controller class.
How to do it...
- Declare the following method in the GWTService interface:
public boolean updateBranch(BranchDTO branchDTO);
- Declare the asynchronous version of this method in the GWTServiceAsync interface:
public void updateBranch(BranchDTO branchDTO,
AsyncCallback<java.lang.Boolean> asyncCallback); - Implement the method in the GWTServiceImpl class:
@Override
public boolean updateBranch(BranchDTO branchDTO)
{
boolean updated=false;
try
{
branchJpaController.edit(new Branch(branchDTO));
updated=true;
}
catch (IllegalOrphanException ex)
{
Logger.getLogger(GWTServiceImpl.class.getName()).
log(Level.SEVERE, null, ex);
}
catch (NonexistentEntityException ex)
{
Logger.getLogger(GWTServiceImpl.class.getName()).
log(Level.SEVERE, null, ex);
}
catch (Exception ex)
{
Logger.getLogger(GWTServiceImpl.class.getName()).
log(Level.SEVERE, null, ex);
}
return updated;
} - Create a callback instance for this method in the client side (BranchForm in this case, if it is not created yet):
final AsyncCallback<Boolean> callback =
new AsyncCallback<Boolean>()
{
MessageBox messageBox = new MessageBox();
@Override
public void onFailure(Throwable caught)
{
messageBox.setMessage("An error occured!
Cannot complete the operation");
messageBox.show();
}
@Override
public void onSuccess(Boolean result)
{
if (result)
{
messageBox.setMessage("Operation completed successfully");
} else
{
messageBox.setMessage("An error occured!
Cannot complete the operation");
}
messageBox.show();
}
}; - Write the event handle code for the update button:
updateButton.addSelectionListener(new
SelectionListener<ButtonEvent>()
{
@Override
public void componentSelected(ButtonEvent ce)
{
branchDTO.setName(nameField.getValue());
branchDTO.setLocation(locationField.getValue());
((GWTServiceAsync)GWT.create(GWTService.class)).
updateBranch(branchDTO,callback);
clear();
}
});
How it works...
This operation is also almost the same as the add operation shown previously. The difference here is the method of controller class. The method edit of the controller class is used to update an entity.
Deleting an entity
In this recipe, we are going to write the code to delete an entity. The client will transfer the ID of the object, and the server will delete the entity from the database using the JPA controller class.
How to do it...
- Declare the following method in the GWTService interface
public boolean deleteBranch(int branchId);
- Declare the asynchronous version of this method in GWTServiceAsync interface
public void deleteBranch(int branchId,
AsyncCallback<java.lang.Boolean> asyncCallback); - Implement the method in GWTServiceImpl class
@Override
public boolean deleteBranch(int branchId)
{
boolean deleted=false;
try
{
branchJpaController.destroy(branchId);
deleted=true;
}
catch (IllegalOrphanException ex)
{
Logger.getLogger(GWTServiceImpl.class.getName()).
log(Level.SEVERE, null, ex);
}
catch (NonexistentEntityException ex)
{
Logger.getLogger(GWTServiceImpl.class.getName()).
log(Level.SEVERE, null, ex);
}
return deleted;
} - Create a callback instance for this method in the client side (BranchForm in this case, if it is not created yet):
final AsyncCallback<Boolean> callback = new
AsyncCallback<Boolean>()
{
MessageBox messageBox = new MessageBox();
@Override
public void onFailure(Throwable caught)
{
messageBox.setMessage("An error occured!
Cannot complete the operation");
messageBox.show();
}
@Override
public void onSuccess(Boolean result)
{
if (result)
{
messageBox.setMessage("Operation completed successfully");
} else
{
messageBox.setMessage("An error occured!
Cannot complete the operation");
}
messageBox.show();
}
}; - Write the event handling code for the delete button:
deleteButton.addSelectionListener(new
SelectionListener<ButtonEvent>()
{
@Override
public void componentSelected(ButtonEvent ce)
{
((GWTServiceAsync)GWT.create(GWTService.class)).
deleteBranch(branchDTO.getBranchId(),callback);
clear();
}
});
Managing a list for RPC
Sometimes, we need to transfer a list of objects as java.util.List (or a collection) back and forth between the server and the client. We already know from the preceding recipes that the JPA entity class objects are not transferable directly using RPC. Because of the same reason, any list of the JPA entity class is not transferable directly. To transfer java.util.List using RPC, the list must contain objects from DTO classes only. In this recipe, we will see how we can manage a list for RPC.
In our scenario, we can consider two classes—Customer and Sales. The association between these two classes is that one customer makes zero or more sales and one sale is made by one customer. Because of such an association, the customer class contains a list of sales, and the sales class contains a single instance of customer class. For example, we want to transfer the full customer object with the list of sales made by this customer. Let's see how we can make that possible.
How to do it...
- Create DTO classes for Customer and Sales (CustomerDTO and SalesDTO, respectively). In the following table, the required changes in data types are shown for the entity and DTO class attributes. The list in the DTO class contains objects of only the DTO class; on the other hand, the list of the entity class contains objects of entity class.

- Define the following constructor in the Customer entity class:
public Customer(CustomerDTO customerDTO)
{
setCustomerNo(customerDTO.getCustomerNo());
setName(customerDTO.getName());
setAddress(customerDTO.getAddress());
setContactNo(customerDTO.getContactNo());
List<SalesDTO> salesDTOList=customerDTO.getSalesList();
salesList = new ArrayList<Sales>();
for(int i=0;i<salesDTOList.size();i++)
{
SalesDTO salesDTO=salesDTOList.get(i);
Sales sales=new Sales(salesDTO);
salesList.add(sales);
}
} - Define the following constructor in the Sales entity class:
public Sales(SalesDTO salesDTO)
{
setSalesNo(salesDTO.getSalesNo());
setSalesDate(salesDTO.getSalesDate());
setCustomer(new Customer(salesDTO.getCustomer()));
// there's more but not relevant for this recipe
}
How it works...
Now in the server side, the entity classes, Customer and Sales, will be used, and in the client side, CustomerDTO and SalesDTO, will be used. Constructors with DTO class type argument are defined for the mapping between entity class and DTO class.
But here, the addition is the loop used for creating the list. From the CustomerDTO class, we get a list of SalesDTO. The loop gets one SalesDTO from the list, converts it to Sales, and adds it in the Sales list—that's all.
Authenticating a user through username and password
In this recipe, we are going to create the necessary methods to authenticate a user through a login process.
Getting ready
Create the DTO class for the entity class Users.
How to do it...
- Declare the following method in the GWTService interface:
public UsersDTO login(String username,String password);
- Declare the following method in the GWTServiceAsync interface:
public void login(String username, String password,
AsyncCallback<UsersDTO> asyncCallback); - Implement the method in the GWTServiceImpl class:
@Override
public UsersDTO login(String username, String password)
{
UsersDTO userDTO = null;
UsersJpaController usersJpaController =
new UsersJpaController();
Users user = (Users) usersJpaController.findUsers(username);
if (user != null)
{
if (user.getPassword().equals(password))
{
userDTO=new UsersDTO();
userDTO.setUserName(user.getUserName());
userDTO.setPassword(user.getPassword());
EmployeeDTO employeeDTO=
new EmployeeDTO(user.getEmployee().getEmployeeId());
employeeDTO.setName(user.getEmployee().getName());
userDTO.setEmployeeDTO(employeeDTO);
}
}
return userDTO;
}
How it works...
A username and password are passed to the method. An object of the UsersJpaController class is created to find the Users object based on the given username. If the find method returns null, it means that no such user exists. Otherwise, the password of the Users object is compared with the given password. If both the passwords match, a UsersDTO object is constructed and returned.
The client will call this method during the login process. If the client gets null, the client should handle it accordingly, as the username/password is not correct. If it is not null, the user is authenticated.
Summary
In this article we how we can manage entities in GWT RPC. Specifically, we covered the following:
- Finding an entity
- Updating an entity
- Deleting an entity
- Managing a list for RPC
- Authenticating a user through username and password
Further resources on this subject:
- Google Web Toolkit 2: Creating Page Layout [Article]
- Communicating with Server using Google Web Toolkit RPC [Article]
- Password Strength Checker in Google Web Toolkit and AJAX [Article]
- Google Web Toolkit GWT Java AJAX Programming [Book]
- Google Web Toolkit 2 Application Development Cookbook [Book]
About the Author :
Shamsuddin Ahammad
Shamsuddin Ahammad is a Senior Lecturer and the Course Coordinator at Daffodil Institute of IT, Bangladesh. He has been teaching Java, Programming Methods, and Database Systems since 2002. He has experience in supervising hundreds of academic projects. Shamsuddin has a Masters degree in Management Information Systems (MIS) from Daffodil International University, Dhaka. He obtained the BSc(Hons) degree in Computing & Information Systems (CIS) of NCC Education Ltd, UK and London Metropolitan University joint programme from Daffodil Institute of IT. Before that, he completed the IDCS & IADCS of NCC Education Ltd. He is an Additional Reviewer of Conference on Quality Engineering in Software Technology (CONQUEST) organized by International Software Quality Institute (iSQI) in Germany. He is the author of book titled iReport 3.7 published from PACKT Publishing in March 2010.




Post new comment