Avant la version 2.1, il n'y avait que les RPC pour communiquer avec le serveur en Gwt.
Depuis cette version, un nouveau api est disponible, Request Factory.
Cet api permet de n'envoyer que les informations nécessaires au client et au serveur. Il y a économie de bande passante.
Au niveau du code, beaucoup de changement sont à prévoir. J'ai passé beaucoup de temps à essayer d'utiliser cet api avec Spring.
La base de donnée h2, spring 3.1 ainsi que gwt 2.4 ont été utilisé pour cet exemple.
L'interface graphique comporte deux boutons, un pour charger toutes les données de la base de donnée et l'autre pour y ajouter un élément.
Le fichier web.xml
<web -app="-app" version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context -param="-param">
<param -name="-name" />contextConfigLocation
<param -value="-value" />/WEB-INF/applicationContext.xml
</context>
<listener>
<listener -class="-class">org.springframework.web.context.ContextLoaderListener</listener>
</listener>
<servlet>
<servlet -name="-name">requestFactoryServlet</servlet>
<servlet -class="-class">com.google.web.bindery.requestfactory.server.RequestFactoryServlet</servlet>
</servlet>
<servlet -mapping="-mapping">
<servlet -name="-name">requestFactoryServlet</servlet>
<url -pattern="-pattern">/gwtRequest</url>
</servlet>
<welcome -file-list="-file-list">
<welcome -file="-file">welcomeGWT.html</welcome>
</welcome>
</web>
Dans le fichier applicationContext.xml, je n'ai que
<context:annotation -config="-config">
<context:component -scan="-scan" base-package="org.calibra">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
Dans le fichier Main.gwt.xml, il faut ajouter
<inherits name="javax.validation.Validation"/>
<inherits name='com.google.web.bindery.requestfactory.RequestFactory'/>
Dans le package Domain
public class Account {
private Long id;
private String username;
private Integer version;
....
}
Dans le package server
La classe AccountLocator est nécessaire afin de ne pas mettre ces opérations directement dans la classe Account.
public class AccountLocator extends Locator<Account, Long> {
@Autowired
private AccountDAO accountDAO;
@Override
public Account create(Class<? extends Account> clazz) {
return new Account();
}
@Override
public Account find(Class<? extends Account> clazz, Long id) {
if (accountDAO == null) {
HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
accountDAO =context.getBean(AccountDAO.class);
}
return accountDAO.findAccount(id);
}
@Override
public Class<Account> getDomainType() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Long getId(Account domainObject) {
return domainObject.getId();
}
@Override
public Class<Long> getIdType() {
return Long.class;
}
@Override
public Object getVersion(Account domainObject) {
return domainObject.getVersion();
}
La classe SpringServiceLocator est nécessaire afin d'avoir accès au bean.
public class SpringServiceLocator implements ServiceLocator {
@Override
public Object getInstance(Class<?> clazz) {
HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
return context.getBean(clazz);
}
}
Dans le package server.service
public interface AccountService {
public Account findAccount(Long id);
public List<Account> loadAllAccounts();
public void save(Account account);
public void delete(Account account);
}
@Service
public class AccountServiceImpl implements AccountService{
@Autowired
private AccountDAO accountDAO;
@Override
public void save(Account account){
accountDAO.save(account);
}
@Override
public List<Account> loadAllAccounts() {
return accountDAO.loadAllAccounts();
}
@Override
public Account findAccount(Long id) {
return accountDAO.findAccount(id);
}
@Override
public void delete(Account account) {
accountDAO.delete(account);
}
}
Dans le package server.dao
@Repository
public class AccountDAOImpl implements AccountDAO {
protected JdbcTemplate jdbcTemplate;
@Override
public Account findAccount(Long id) {
StringBuffer sb = new StringBuffer();
sb.append("select id, username, version from account where id = ?");
List<Account> accountList = jdbcTemplate.query(sb.toString(),
new Object[]{id}, mapper);
if (accountList != null && accountList.size() > 0) {
return accountList.get(0);
}
return null;
}
@Override
public List<Account> loadAllAccounts() {
StringBuffer sb = new StringBuffer();
sb.append("select id, username, version from account");
List<Account> accountList = jdbcTemplate.query(sb.toString(), mapper);
return accountList;
}
@Override
public void save(Account account) {
if (account.getVersion() == null) {
account.setVersion(0);
jdbcTemplate.update("insert into account(username, version) values(?, ?)",
account.getUsername(), account.getVersion());
} else {
account.setVersion(account.getVersion() + 1);
jdbcTemplate.update("update account(username, version) set username=?, version=? where id=?",
account.getUsername(), account.getVersion(), account.getId());
}
}
@Override
public void delete(Account account) {
jdbcTemplate.update("delete from account where id = ?", account.getId());
}
@Autowired
public void setDataSource(DataSource datasource) {
this.jdbcTemplate = new JdbcTemplate(datasource);
}
private static ParameterizedRowMapper<Account> mapper = new ParameterizedRowMapper<Account>() {
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account = new Account();
account.setId(rs.getLong("id"));
account.setUsername(rs.getString("username"));
account.setVersion(rs.getInt("version"));
return account;
}
};
}
public interface AccountDAO {
public Account findAccount(Long id);
public List<Account> loadAllAccounts();
public void save(Account account);
public void delete(Account account);
}
Dans le package shared
public interface AccountRequestFactory extends RequestFactory {
AccountRequest accountRequest();
}
@Service(locator = SpringServiceLocator.class, value =AccountService.class)
public interface AccountRequest extends RequestContext {
Request<AccountProxy> findAccount(Long id);
Request<List<AccountProxy>> loadAllAccounts();
Request<Void> save(AccountProxy accountProxy);
Request<Void> delete(AccountProxy accountProxy);
}
@ProxyFor(value=Account.class, locator = AccountLocator.class)
public interface AccountProxy extends EntityProxy{
public Long getId();
public String getUsername();
public Integer getVersion();
public void setUsername(String userName);
public void setId(Long id);
public void setVersion(Integer version);
}
Dans le package client
public class MainEntryPoint implements IsWidget, EntryPoint {
private final AccountRequestFactory requestFactory = GWT.create(AccountRequestFactory.class);
AccountRequest request;
AccountProxy newAccount;
@Override
public Widget asWidget() {
Button loadAllButton = new Button("Load all Account");
final ValueListBox<AccountProxy> accountListBox = new ValueListBox<AccountProxy>(new Renderer<AccountProxy>() {
@Override
public String render(AccountProxy object) {
return object.getUsername();
}
@Override
public void render(AccountProxy object, Appendable appendable) throws IOException {
appendable.append(object.getUsername());
}
});
loadAllButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
request = requestFactory.accountRequest();
Request<List<AccountProxy>> loadAllAccounts = request.loadAllAccounts();
loadAllAccounts.fire(new Receiver<List<AccountProxy>>() {
@Override
public void onSuccess(List<AccountProxy> response) {
accountListBox.setAcceptableValues(response);
Window.alert("account ajouté");
}
});
}
});
Button addButton = new Button("Add account");
addButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
request = requestFactory.accountRequest();
AccountProxy accountProxy = request.create(AccountProxy.class);
accountProxy.setUsername("joe");
request.save(accountProxy).fire(new Receiver<Void>() {
@Override
public void onSuccess(Void response) {
Window.alert("account ajouté");
}
});
}
});
VerticalPanel vp = new VerticalPanel();
vp.setSpacing(10);
vp.add(loadAllButton);
vp.add(accountListBox);
vp.add(addButton);
return vp;
}
@Override
public void onModuleLoad() {
requestFactory.initialize(new SimpleEventBus());
RootPanel.get().add(asWidget());
}
}
Liste de jar présent dans WEB-INF/lib/
Les sources de cet exemples est disponible ici.
Ces jar ne sont pas inclus dans les sources.
Blog sur la conception, développement et le génie logiciel. Divers langages et systèmes d'exploitations sont traités.
dimanche 23 septembre 2012
samedi 22 septembre 2012
Design Pattern Tête la première
Ce livre présente les patrons suivants
- Observateur
- Décorateur
- Fabriques
- Singleton
- Commande
- Adaptateur, Façade
- Patron de méthode
- Itérateur, composite
- État
- Proxy
- Composés
Au lieu d'aborder une approche théorique comme de nombreux livres, ils ont opté pour une approche pratique.
Il utilise des techniques afin de rendre plus aisé l'apprentissage. Les informations sont expliquées de diverses façons.
Les images sont abondamment utilisées. Il y a des mini-jeux ainsi que des questions afin de faire réfléchir le lecteur sur la matière vue.
Des conseils sont données tout au long du livre. Des dialogues ainsi que des histoires sont employés afin d'emmener le lecteur à se forger une idée sur les points clés.
Les moyens pédagogiques employés rend la lecture du livre beaucoup plus agréable, sans compté que ça simplifie la compréhension et la mémorisation des patrons.
Les exemples de code utilisent le langage Java, cependant il devrait être compris sans difficulté par ceux utilisant c#.
Cette approche est employée pour chaque patron. Cette stratégie devrait être employée dans plus de bouquins.
À ce jour, c'est le meilleur livre sur les patrons que j'ai pu lire. Si vous devez en lire qu'un seul, pensez à celui-ci.
Certes seuls les patrons les plus populaires sont présentés, mais vous obtiendrez une base solide afin de les utiliser dans vos développements.
dimanche 16 septembre 2012
Netbeans
Netbeans
Chaque nouvelle version de netbeans apporte un nombre grandissant d'amélioration. Il a quelques années, Eclipse a su s'accaparer une grande part du marché des ide en Java.
Depuis, Oracle travaille d'arrache pied pour remonter la pente. Leur effort semble récompensé, les réactions dans les forums et sondage sont très positif. La facilité de créer des interfaces graphiques depuis la version 5x à peu aider à contribuer à ce renversement.
Une panoplie de module peuvent être installé à la demande: C/C++, java mobile, php, ruby, grail, groovy. De plus le profiler ainsi le créateur de gui installé par défaut permette de faciliter le développement.
Hudson, Ant, Maven, Bugzilla sont bien intégré à l'outil.
Netbeans possède un éditeur graphique qui utilise le groupLayout. Il permet en quelques cliques de créer des interfaces très complexe.
Il y a certe moins de plugin qu'Eclipse, mais les meilleurs existent aussi pour cet ide.
De multiple wizard existe pour créer les fonctionnalités CRUD.
JavaFX est supporté.
La plateforme Netbeans peut être utilisé afin de créer des applications Swing. Il pousse à utiliser divers principe du génie logiciel tel que les modules, les plugins et les services. Il standardise les tâches courantes de création d'application graphiques: gestion des fenêtres, menu, mise à jour, gestion des langues. La gestion des modèles des composants graphiques est générique. Le même modèle peut être utilisé pour un jtree, jtable...
Si vous n'avez jamais utilisé Netbeans, essaye le, votre expérience de développement en sera grandissante. Autrement, faite la mise à jour.
Chaque nouvelle version de netbeans apporte un nombre grandissant d'amélioration. Il a quelques années, Eclipse a su s'accaparer une grande part du marché des ide en Java.
Depuis, Oracle travaille d'arrache pied pour remonter la pente. Leur effort semble récompensé, les réactions dans les forums et sondage sont très positif. La facilité de créer des interfaces graphiques depuis la version 5x à peu aider à contribuer à ce renversement.
Une panoplie de module peuvent être installé à la demande: C/C++, java mobile, php, ruby, grail, groovy. De plus le profiler ainsi le créateur de gui installé par défaut permette de faciliter le développement.
Hudson, Ant, Maven, Bugzilla sont bien intégré à l'outil.
Netbeans possède un éditeur graphique qui utilise le groupLayout. Il permet en quelques cliques de créer des interfaces très complexe.
Il y a certe moins de plugin qu'Eclipse, mais les meilleurs existent aussi pour cet ide.
De multiple wizard existe pour créer les fonctionnalités CRUD.
JavaFX est supporté.
La plateforme Netbeans peut être utilisé afin de créer des applications Swing. Il pousse à utiliser divers principe du génie logiciel tel que les modules, les plugins et les services. Il standardise les tâches courantes de création d'application graphiques: gestion des fenêtres, menu, mise à jour, gestion des langues. La gestion des modèles des composants graphiques est générique. Le même modèle peut être utilisé pour un jtree, jtable...
Si vous n'avez jamais utilisé Netbeans, essaye le, votre expérience de développement en sera grandissante. Autrement, faite la mise à jour.
samedi 30 juin 2012
Programming Language Processors
Programming Language Processors in Java fournie diverses techniques pour concevoir un langage de programmation. Ce livre comporte moins de 450 pages et comporte de multiple exemples pratiques.
Des exemples concrets pour les différentes sections du livre
- Langage processeur
- Compilation
- Analyse synxtaxique
- Analyse contextuel
- Géneration de code
- Interpretation
sont présentés et les liens avec la théorie sont très claire. Les différents chapitres peuvent être lu de façon indépendant ce qui permet d'alléger la lecture et de la rendre plus accesible. Les auteurs ne tombent pas dans le piège d'être trop théorique. Les exemples permettent de mieux comprendre l'aspect théorique et de se faire de meilleur idée sur d'autre approche d'implémentation possible.
Les analyses de type LL, LR sont présentés et permettent d'avoir une meilleure idées de laquelle employés selon le langage qu'on cherche à créer ou bien à analyser.
Une étude de cas est utilisé en employant le langage Triangle. Il est ainsi possible de comprendre les différentes parties du compilateur qui est fait en Java pour ce langage. Le tout en employant de bonne pratiques du génie logiciel.Ce langague est utilisé pour tous les chapitres.
Divers algorithmes sont présentés pour chaque section du livre.
Le code java employé n'est pas parfait mais il reste de très bonne augure.
Un chapitre peut s'avérer intéressant pour ceux qui n'ont pas de connaissance sur l'architecture de base des cpu. Il permet en autre de comprendre les variables sont mis sur la pile, comment les paramètres sont envoyés au fonction. Ce chapitre est très instructif pour la création d'une machine virtuelle.
L'auteur a su bien dosé chaque aspect, il n'a pas entré dans des détails trop futile.
Après avoir lu le livre, le lecteur pourra être en mesure de créer son propre langage de programmation ou de faire un interpréteur de commande. Surement le livre idéal si on veut apprendre en codant.
vendredi 15 juin 2012
Specification By Example
Ce livre explique l'importance d'insérer le client dans le processus du développement logiciel. Les bénéfices ainsi que les bonnes pratiques sont définis. Le plus intéressant du livre est de mon point de vue les études de cas. Diverses entreprises donnent leur commentaire, comment elle était avant l'emploi de cette méthode et les résultats de son usage.
Des concepts clés tel que définir les spécifications en groupe, mettre des exemples dans les spécifications, valider fréquemment les spécifications ainsi que plusieurs autres bonnes pratique sont élaborés dans ce livre.
Je crois qu'avoir vécu quelques projets informatiques peut contribuer à mieux apprécier ce livre et ainsi remarquer qu'on est pas les seul à avoir des problèmes similaires et à vouloir les fixer.Oui la documentation est importante, mais une image peur remplacer beaucoup de mot et éviter des erreurs.
Les cas concrets ne font que renforcer que les méthodologies agiles peuvent vraiment être un avantage dans la gestion d'un projet informatique. Les cas sont différents ainsi que la structure et la des équipes ce qui permet de mieux pouvoir se projeter dans un de ces exemples C'est un livre qui donne de précieux conseils.
mardi 2 août 2011
Language Implementation Patterns
Ce livre présente différents patrons utilisés pour l'interprétation, analyse et la traduction de langage de programmation. Le livre utiliser ANTLR afin d'aller à l'essentiel et réduire la complexité. Les différentes étapes de la syntaxe du langage à l'exécutable sont passées en revue.
La première partie est consacrer au parsing le langage différente technique sont présenté tel que "backtracking, memoizin, predicated"... La deuxième partie consiste à analyser ce qui a été lu. La troisième partie est liée à la création d'interpréteur (haut niveau et bytecode). La dernière partie consiste à traduire à un langage à un autre.
Ce livre permettra à celui qui veut créer un langage de mieux décerner le patron qu'il pourra utiliser. Certains patrons sont plus adaptés à certains types de syntaxe. Le lecteur pourra avoir une idée pour implémenter un interpréteur pour un langage dynamique.
La traduction d'un langage à un autre permet grâce à l'exemple d'avoir une meilleure idée de la façon de faire pour un langage plus complexe.
J'ai trouvé que les explications n'étaient pas toujours claires et manquaient d'exemple réellement concret. Néanmoins, il constitue une excellente entrée pour quiconque veut implémenter un langage de programmation.
Peu de livres présentent d'une façon si épurée autant de concept, ce livre fait moins de 400 pages. La concurrence fait souvent plus du double ou triple et est axé trop souvent sur la théorie.
C'est un livre à compléter par un livre plus axé sur la pratique.
jeudi 14 avril 2011
97 Things Every Programmer Should Know
Ce livre est composé de 97 bonnes pratiques que tout développeur devrait connaître. Les astuces sont présentées par des programmeurs expérimentés. Elles sont courtes, mais précises.
Ce n'est pas pas nécessairement des trucs sur la façon de coder, mais bien des idéologies à mettre en place afin d'arriver à produire du meilleur code, avoir un esprit plus rigoureux qui permettra de résoudre un problème donné de façon plus optimale.
Ce ramassis d'astuces permettra à quiconque du débutant à l'expert de parfaire ses connaissances dans l'art du développement. Au lieu de prendre des conseils à droite et à gauche et qui prendrait plusieurs années, ici on a l'essentiel qui est condensé.
Par exemple, on y dit qu'il est est important de bien maitriser son ide, savoir estimer, améliorer son code en enlevant le superflu. Ce livre présente plusieurs facettes du génie logiciel.
C'est un livre à posséder et à relire.
Inscription à :
Articles (Atom)
Quand JPA rencontre ses limites, pensez à jOOQ et au MULTISET
Une seule requête, un graphe d'objets complet — ce n'est pas de la magie, c'est du SQL. La base du problème Dans le monde JPA, q...
-
Toshiba AC100 est un smartbook. Toshiba est la seule grosse entreprise qui a commercialisé un smartbook, malgré que plusieurs autres en aie...
-
Nous verrons dans cet article comment corrigé le problème Hibernate’s Warning “firstResult/maxResults specified with collection fetch” qui ...
-
En 2019, nous avons développé une application métier basée sur : Java 8 Spring Boot 2.2.7 Gradle 6.6.1 Thymeleaf Boots...







