 
www.devcastzone.com
1
Z
AAWANSOWANE WYKORZYSTANIE BIBLIOTEKI
EXT
GWT
W APLIKACJACH OPARTYCH O
G
OOGLE
W
EB
T
OOLKIT
Moduł 5: Komunikacja aplikacji z serwerem
Ćwiczenie 1: Callback
Treść:
Stworzyd  funkcję  zwrotną,  która  będzie  reagowała  na  zwrot  listy  łaocuchów  tekstowych. 
Jeżeli lista zostanie zwrócona to należy każdy jej element wyświetlid w konsoli. Jeżeli lista nie 
została  poprawnie  zwrócona  należy  wydelegowad  go  do  nowo  rzucanego  wyjątku  klasy 
RunntimeException. 
Instrukcja rozwiązania:
1. Stworzyd funkcję zwrotną klasy asyncCallback wraz z typem generycznym
określającym listę ciągów tekstowych.
2. Zaimplementowad metodę onFailure, która rzuca nowy wyjątek klasy
RuntimeException, i przekazuje wyjątek z funkcji zwrotnej
3. Zaimplementowad metodę onSuccess, w której należy przeiterowad zwraaną listę a
następnie każdy element wyświetlid na ekranie.
Rozwiązanie: 
 
Ćwiczenie 2: Asynchronous interface
Treść:
Stworzyd interfejs asynchroniczny do serwisu posiadającego następujące metody:
interface
UserService {
AsyncCallback<List<String>> callback =
new
AsyncCallback<List<String>>() { 
       
      @Override 
      
public
void
onFailure(Throwable caught) {
throw
new
RuntimeException(caught);
      } 
       
      @Override 
      
public
void
onSuccess(List<String> result) {
for
(String row : result) {
System.out.println(
"Row: "
+ row);
        } 
      } 
    }; 
 
www.devcastzone.com
2
public
void
updateUserName(Long id, String userName);
 
    
public
String getUserName(Long id);
 
    
public
List getUserNamesListByFilter(String filter);
}
Instrukcja rozwiązania:
1.  Należy zdefiniowad nowy interfejs o nazwie UserListAsync 
2.  Należy  dodad  deklarację  nowej  metody  updateUserName,  która  nic  nie  zwraca,  z 
przyjmowanymi parametrami: identyfikator, funkcja zwrotna , nic nie zwracająca
3. Należy dodad deklarację nowej metody getUserName, która nic nie zwraca, z
przyjmowanymi  parametrami:  identyfikator,  funkcja  zwrotna  zwracająca  tekstowy 
typ danych 
4. Należy dodad deklarację nowej metody getUserNameListByFilter, która nic nie
zwraca, z przyjmowanymi parametrami: tekstowy filtr, funkcja zwrotna , zwracająca 
listę typów tekstowych 
Rozwiązanie: 
 
Ćwiczenie 3: GWT-RPC
Treść:
Stworzyd interfejs synchroniczny, asynchroniczy oraz implementację do komunikacji za 
pomocą GWT-RPC. Potencjalne wywołanie metody getFeedList serwisu powinno zwrócid 
listę łaocuchów tekstowych: (Blog BNSIT, Blog Xperios, Google, News). Serwis ma byd 
dostępny pod adresem "FeedList".
Instrukcja rozwiązania:
1. Należy stworzyd interfejs
FeedListService dziedziczący po RemoteService I
adnotacją RemoteServiceRelativePath ustawioną na FeedList
2.  Dodad do interfejsu metodę getFeedList, która zwraca listę typów tekstowych 
3.  Stworzyd  interfejs  o  nazwie  FeedListServiceAsync  z  metodą  o  nazwie  getFeedList, 
która  nie  zwraca  nic  i  przyjmuje  jedynie  jako  parametr  funkcję  zwrotną  listy  typów 
tekstowych 
interface
UserListAsync {
     
    
public
void
updateUserName(Long id, String user, AsyncCallback<Void>
callback); 
     
    
public
void getUserName(Long id, AsyncCallback<String> callback);
     
    
public
void getUserNameListByFilter(String filter, AsyncCallback<
List<String>> callback); 
  } 
 
www.devcastzone.com
3
4. Stworzyd klasę FeedService, która dziedziczy po RemoteServiceServlet i implementuje
FeedListService
5.  W stworzonej klasie należy zaimplementowad metodę getFeedList 
6.  W  implementacji  należy  stworzyd  obiekt  listy,  do  której  należy  dodad  kolejno  „Blog 
BNSIT”, „Blog Xperios”, „Google”, „News”, który następnie należy zwrócid.
Rozwiązanie: 
 
@RemoteServiceRelativePath(
"FeedList"
)
interface
FeedListService
extends
RemoteService {
     
    
public
List<String> getFeedList();
  } 
   
  
interface
FeedListServiceAsync {
     
    
public
void
getFeedList(AsyncCallback<List<String>> callback);
  } 
   
  
class
FeedService
extends
RemoteServiceServlet
implements
FeedListService { 
     
    @Override 
    
public
List<String> getFeedList() {
ArrayList<String> out =
new
ArrayList<String>();
out.add(
"Blog BNSIT"
);
out.add(
"Blog Xperios"
);
out.add(
"Google"
);
out.add(
"News"
);
return
out;
    } 
  } 
 
www.devcastzone.com
4
Ćwiczenie 4: DTO
Treść:
Stworzyd model persystencyjny, który za pomocą metody DTO pozwoli na wprowadzenie 
danych w części klienckiej, zapisanie ich w bazie danych oraz pobranie ich i wysłanie z 
powrotem. Należy stworzyd model persystencyjny Person, który będzie posiadał właściwości 
id, name i dateOfBirth oraz releatedList jako listę osób spokrewnionych. Obiekty tego 
modelu muszą byd zapisywalne w bazie danych za pomocą Hibernate a także z niej 
odczytywane. 
Należy opracowad metodę komunikacyjną, pozwoli na przesłanie danych z części klienckiej i 
zapisanie ich do bazy danych. Po poprawnym zapisie danych ma zostad pobrana lista 
wszystkich elementów modelu i odesłana do klienta. 
Instrukcja rozwiązania:
1. .Należy stworzyd model danych Person z adnotacją @Entity i nad właściwościami
pododawad  adnotacje:  @Id  nad  identyfikatorem,  @Temoral  nad  polem  daty, 
@OneToMany nad polem listy. 
2. Stworzyd model dto o nazwie PersonDTO, który posiada te same właściwości co do
typów i nazw bez żadnej adnotacji.
3. Do klasy Person dodad statyczne metody pozwalające na konwersję obiektów
PersonDTO do Person i na odwrót
4. Stworzyd plik konfiguracyjny Hibernate wraz z dodanym wpisem mapping class ze
wskazaniem na klasę Person
5. Stworzyd klasę pomocniczą HibernateUtil, która skonfiguruje Hibernate a także
pozwoli na pobranie obiektu sesji.
6. Stworzyd interfejs synchroniczny wraz z metodą: persistAndGetAllPerson, która
przyjmowad będzie obiekt PersonDTO, natomiast zwracad będzie List<PersonDTO>
7.  Stworzyd interfejs asynchroniczny 
8.  Dodad odpowiednie mapowanie w pliku web.xml 
9.  Stworzyd  implementację  serwisu,  która  pozwoli  na  zainicjonowanie  danych  w  bazie 
danych
10. Implementacja metody powinna umożliwiad konwersję obiektów PersonDTO na
obiekty  klasy  Person,  zapis  obiektu  Person  do  bazy,  odczyt  wszystkich  elementów 
Person  z  bazy,  konwersję  wszystkich  zwróconych  elementów  do  PersonDTO  oraz 
odesłanie danych do klienta. 
Rozwiązanie:
 
www.devcastzone.com
5
Model danych:
package
pl.bnsit.rpc.server;
import
java.util.ArrayList;
import
java.util.Date;
import
java.util.List;
import
javax.persistence.CascadeType;
import
javax.persistence.Entity;
import
javax.persistence.FetchType;
import
javax.persistence.GeneratedValue;
import
javax.persistence.GenerationType;
import
javax.persistence.Id;
import
javax.persistence.OneToMany;
import
javax.persistence.Temporal;
import
javax.persistence.TemporalType;
import
pl.bnsit.rpc.shared.PersonDTO;
 
@Entity 
public
class
Person {
 
  @Id 
  @GeneratedValue(strategy = GenerationType.AUTO) 
  Long id; 
  String name; 
  @Temporal(TemporalType.DATE) 
  Date dateOfBirth; 
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
  List<Person> relativeList; 
 
  
public
Person() {
  } 
 
  
public
Person(Long id, String name, Date dateOfBirth,
List<Person> relativeList) { 
    
this
.id = id;
this
.name = name;
this
.dateOfBirth = dateOfBirth;
this
.relativeList = relativeList;
  } 
 
 
//setters and getters 
 
  @Override 
  
public
String toString() {
return
"Person{"
+
"id="
+ id +
", name="
+ name +
",
dateOfBirth="
+ dateOfBirth +
", relativeList="
+ relativeList +
'}'
;
  } 
 
  
 
www.devcastzone.com
6
DTO:
Metody konwertujące zawarte w klasie Person.java:
package
pl.bnsit.rpc.shared;
import
java.util.Date;
import
java.util.List;
public
class
PersonDTO {
 
  Long id; 
  String name; 
  Date dateOfBirth; 
  List<PersonDTO> relativeList; 
 
  
public
PersonDTO() {
  } 
 
  
public
PersonDTO(Long id, String name, Date dateOfBirth,
List<PersonDTO> relativeList) { 
    
this
.id = id;
this
.name = name;
this
.dateOfBirth = dateOfBirth;
this
.relativeList = relativeList;
  } 
// getters and setters 
  @Override 
  
public
String toString() {
return
"PersonDTO{"
+
"id="
+ id +
", name="
+ name +
",
dateOfBirth="
+ dateOfBirth +
", relativeList="
+ relativeList +
'}'
;
  }  
}
public
static
PersonDTO convertToDto(Person object) {
if
(object ==
null
) {
return
null
;
    } 
    PersonDTO out = 
new
PersonDTO();
    out.setId(object.getId()); 
    out.setName(object.getName()); 
    out.setDateOfBirth(object.getDateOfBirth()); 
    out.setId(object.getId()); 
    List<Person> relativeListObject = object.getRelativeList(); 
    
if
(relativeListObject ==
null
) {
return
out;
    } 
    List<PersonDTO> relativeListDTO = 
new
ArrayList<PersonDTO>();
for
(Person person : relativeListObject) {
      relativeListDTO.add(convertToDto(person)); 
    } 
    out.setRelativeList(relativeListDTO); 
    
return
out;
  } 
} 
 
www.devcastzone.com
7
Przykładowy plik konfiguracyjny hibernate:
HibernateUtil:
public
static
Person convertFromDto(PersonDTO dto) {
if
(dto ==
null
) {
return
null
;
    } 
    Person out = 
new
Person();
    out.setId(dto.getId()); 
    out.setName(dto.getName()); 
    out.setDateOfBirth(dto.getDateOfBirth()); 
    out.setId(dto.getId()); 
    List<PersonDTO> relativeListDto = dto.getRelativeList(); 
    
if
(relativeListDto ==
null
) {
return
out;
    } 
    List<Person> relativeList = 
new
ArrayList<Person>();
for
(PersonDTO personDTO : relativeListDto) {
      relativeList.add(convertFromDto(personDTO)); 
    } 
    out.setRelativeList(relativeList); 
    
return
out;
  }   
} 
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<!
DOCTYPE
hibernate-configuration
PUBLIC
"-//Hibernate/Hibernate
Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-
3.0.dtd"
>
<
hibernate-configuration
>
<
session-factory
>
<
property
name=
"hibernate.dialect"
>
org.hibernate.dialect.DerbyDialect
</
prop
erty
>
<
property
name=
"hibernate.connection.driver_class"
>
org.apache.derby.jdbc.Cl
ientDriver
</
property
>
<
property
name=
"hibernate.connection.url"
>
jdbc:derby://localhost:1527/sampl
e
</
property
>
<
property
name=
"hibernate.connection.username"
>
app
</
property
>
<
property
name=
"hibernate.connection.password"
>
app
</
property
>
<
property
name=
"hibernate.current_session_context_class"
>
thread
</
property
>
<
property
name=
"hibernate.hbm2ddl.auto"
>
create-
drop
</
property
>
<
mapping
class=
"pl.bnsit.rpc.server.Person"
/>
</
session-factory
>
</
hibernate-configuration
>
 
www.devcastzone.com
8
Interfejs synchroniczny:
package
pl.bnsit.rpc.server;
import
org.hibernate.cfg.AnnotationConfiguration;
import
org.hibernate.SessionFactory;
/** 
 * Hibernate Utility class with a convenient method to get 
Session Factory 
 * object. 
 */
public
class
HibernateUtil {
 
  
private
static
final
SessionFactory sessionFactory;
   
  
static
{
try
{
// Create the SessionFactory from standard
(hibernate.cfg.xml)
// config file.
sessionFactory =
new
AnnotationConfiguration().configure().buildSessionFactory(); 
    } 
catch
(Throwable ex) {
// Log the exception.
System.err.println(
"Initial SessionFactory creation
failed."
+ ex);
throw
new
ExceptionInInitializerError(ex);
    } 
  } 
   
  
public
static
SessionFactory getSessionFactory() {
return
sessionFactory;
  } 
} 
package
pl.bnsit.rpc.client;
import
com.google.gwt.user.client.rpc.RemoteService;
import
com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import
java.util.List;
import
pl.bnsit.rpc.shared.PersonDTO;
 
@RemoteServiceRelativePath(
"PersonService"
)
public
interface
PersonListService
extends
RemoteService {
 
  
public
List<PersonDTO> persistAndGetAllPerson(PersonDTO
person); 
} 
 
www.devcastzone.com
9
Interfejs asynchroniczny:
Mapowanie serwletu:
Implementacja serwisu:
package
pl.bnsit.rpc.client;
import
com.google.gwt.user.client.rpc.AsyncCallback;
import
java.util.List;
import
pl.bnsit.rpc.shared.PersonDTO;
public
interface
PersonListServiceAsync {
 
  
public
void
persistAndGetAllPerson(PersonDTO person,
AsyncCallback<List<PersonDTO>> callback); 
   
} 
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
web-app
version
=
"2.4"
xmlns
=
"http://java.sun.com/xml/ns/j2ee"
xmlns:web
=
"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
<
servlet
>
<
servlet-name
>
PersonService
</
servlet-name
>
<
servlet-class
>
pl.bnsit.rssreader.server.FeedServiceImpl
</
servlet-
class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
PersonService
</
servlet-name
>
<
url-pattern
>
/MainModule/ PersonService
</
url-pattern
>
</
servlet-mapping
>
<
servlet
>
<
servlet-name
>
PersonService
</
servlet-name
>
<
servlet-class
>
pl.bnsit.rpc.server.PersonListServiceImpl
</
servlet-
class
>
</
servlet
>
<
welcome-file-list
>
<
welcome-file
>
MainModule.html
</
welcome-file
>
</
welcome-file-list
>
</
web-app
>
 
www.devcastzone.com
10
package
pl.bnsit.rpc.server;
import
com.google.gwt.user.server.rpc.RemoteServiceServlet;
import
pl.bnsit.rpc.client.PersonListService;
import
java.util.ArrayList;
import
java.util.Date;
import
java.util.List;
import
org.hibernate.Transaction;
import
org.hibernate.classic.Session;
import
pl.bnsit.rpc.shared.PersonDTO;
public
class
PersonListServiceImpl
extends
RemoteServiceServlet
implements
PersonListService {
static
{
System.out.println(
"Initializing person data"
);
    Session session = 
HibernateUtil.getSessionFactory().openSession(); 
    Transaction transaction = session.beginTransaction(); 
    transaction.begin(); 
    List<Person> personList = 
new
ArrayList<Person>();
personList.add(
new
Person(
null
,
"Sister"
,
new
Date(),
null
));
personList.add(
new
Person(
null
,
"Brother"
,
new
Date(),
null
));
personList.add(
new
Person(
null
,
"Me"
,
new
Date(),
null
));
session.save(
new
Person(
null
,
"Father"
,
new
Date(),
personList)); 
    transaction.commit(); 
  } 
  @Override 
  
public
List<PersonDTO> persistAndGetAllPerson(PersonDTO
person) { 
    Session session = 
HibernateUtil.getSessionFactory().openSession(); 
    Transaction transaction = session.beginTransaction(); 
    transaction.begin(); 
    session.save(Person.convertFromDto(person)); 
    transaction.commit(); 
    
return
getPersonDto();
  } 
  
public
static
List<Person> getPersonList() {
    Session session = 
HibernateUtil.getSessionFactory().openSession(); 
    
return
session.createCriteria(Person.
class
).list();
  } 
 
  
public
static
List<PersonDTO> getPersonDto() {
List<PersonDTO> out =
new
ArrayList<PersonDTO>();
for
(Person person : getPersonList()) {
      out.add(Person.convertToDto(person)); 
    } 
    
return
out;
  } 
} 
 
www.devcastzone.com
11
Częśd kliencka (wywołująca):
package
pl.bnsit.rpc.client;
import
com.google.gwt.core.client.EntryPoint;
import
com.google.gwt.core.client.GWT;
import
com.google.gwt.user.client.Window;
import
com.google.gwt.user.client.rpc.AsyncCallback;
import
com.sencha.gxt.widget.core.client.box.MessageBox;
import
java.util.Date;
import
java.util.List;
import
pl.bnsit.rpc.shared.PersonDTO;
public
class
MainModule
implements
EntryPoint{
 
  @Override 
  
public
void
onModuleLoad() {
    PersonListServiceAsync service = 
GWT.create(PersonListService.
class
);
PersonDTO person =
new
PersonDTO(
null
,
"Me"
,
new
Date(),
null
);
service.persistAndGetAllPerson(person,
new
AsyncCallback<List<PersonDTO>>() { 
 
      @Override 
      
public
void
onFailure(Throwable caught) {
Window.alert(
"error occured: "
+caught.getMessage());
      } 
 
      @Override 
      
public
void
onSuccess(List<PersonDTO> result) {
Window.alert(
"People in db: I"
+result.size()+
""
);
      } 
    }); 
  } 
   
}