mardi 9 août 2016

Utilisez des ressources avec spring

Afin d'utiliser les ressources dans une application Spring, il faut créer un répertoire i18n dans le répertoire ressources.

Créer un fichier pour la langue par défaut et ensuite un par langue qui sera supporté.

messages.properties
messages_fr.properties

Le contenu du premier fichier serait

paymentMode.CASH=Cash
paymentMode.DEBIT=Debit
paymentMode.CHECK=Check
paymentMode.CREDITCARD=Credit card
paymentMode.GIFTCARD=Gift card

et celui du deuxième

paymentMode.CASH=Comptant
paymentMode.DEBIT=D\u00e9bit
paymentMode.CHECK=Ch\u00c3\u00a8que
paymentMode.CREDITCARD=Carte de cr\u00e9dit
paymentMode.GIFTCARD=Carte cadeaux

J'avais mis directement les accents, mais il semble qu'il y est eu une conversion à l'unicode.

Dans la classe où vous désirer accéder la valeur, il faut ajouter une propriété

@Autowired
private MessageSource messageSource;

Ensuite pour accéder au message vous pouvez utiliser une de ces deux méthodes

getMessage(String code, Object[] args, Locale locale);
getMessage(String code, Object[] args, String defaultMessage, Locale locale);

Dans notre cas, pour avoir la valeur de CASH en français.
messageSource.getMessage("paymentMode." + CASH, null, Locale.FRENCH);

lundi 8 août 2016

Accélération du développement avec Spring Boot

Spring Boot est un framework créé pour simplifier le développement d'application java.Il permet d'utiliser les différentes briques Spring. Il est possible de l'utiliser via un serveur JEE ou même un serveur tomcat ou jetty directement embarqué.

La configuration est minimal et peut se faire via les annotations, programmation ou par des fichiers de propriété ou yml.

Par exemple, en ajoutant un fichier schema.sql, la base de donnée peut être créé, avec un fichier nommé data.sql des données peut être inséré dans la bd. Une panoplie de petite chose comme ça est mis en place pour accroître la productivité.

Une page web existe pour créer le squelette d'une application. Ce site est https://start.spring.io/. Après avoir spécifié le nom de nom application, module désiré, version de java... un projet compressé peut être téléchargé et être ouvert dans un EDI tel que Netbeans.

Il est possible de créer un projet via maven ou bien gradle. Nous utiliserons ce derniers pour cet article.

En moins de 2 minute, il est possible d'avoir un serveur web fonctionnel.

Première application

Spring Initializer est utilisé pour créer la base de l'application.



Nous allons utiliser les paramètres par défaut, il y aucune dépendance pour le moment. Cliquer sur Generate Project et télécharger le fichier. Le fichier généré est aussi disponible ici. J'ai opté pour gradle au lieu de maven.

Par défaut, il y a qu'un fichier servant à démarrer l’application et un fichier application.propertie vide.

L'exécution de l'application donnera cette trace

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.0.RELEASE)

2016-08-08 18:41:17.065  INFO 9267 --- [           main] com.example.DemoApplication              : Starting DemoApplication with PID 9267 (/home/collinm/Development/code/demo/build/classes/main started by collinm in /home/collinm/Development/code/demo)
2016-08-08 18:41:17.068  INFO 9267 --- [           main] com.example.DemoApplication              : No active profile set, falling back to default profiles: default
2016-08-08 18:41:17.159  INFO 9267 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@727803de: startup date [Mon Aug 08 18:41:17 EDT 2016]; root of context hierarchy
2016-08-08 18:41:18.067  INFO 9267 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-08-08 18:41:18.083  INFO 9267 --- [           main] com.example.DemoApplication              : Started DemoApplication in 1.421 seconds (JVM running for 1.796)
2016-08-08 18:41:18.093  INFO 9267 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@727803de: startup date [Mon Aug 08 18:41:17 EDT 2016]; root of context hierarchy
2016-08-08 18:41:18.108  INFO 9267 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

L'application ne fait rien. Nous allons maintenant ajouter des modules pour que l'application supporte Rest. Le service retournera un nombre aléatoire.

Dans le fichier build.gradle, nous allons renommer le module starter par starter-web ce qui donne.

dependencies {
        compile("org.springframework.boot:spring-boot-starter-web")
testCompile('org.springframework.boot:spring-boot-starter-test')
}

Nous allons créer un controleur

@RequestMapping(value="/rest")
@RestController
public class DemoController {
    private final DemoService demoService;
    
    @Autowired
    public DemoController(final DemoService demoService){
        this.demoService = demoService;
    }

    @GetMapping(value = "/random")
    public Integer getRandomNumber() {
        return demoService.getRandomNumber();
    }
    
    @GetMapping(value = "/random/{maxnumber}")
    public Integer getLimitRandomNumber(@PathVariable("maxnumber") int maxNumber) {
        return demoService.getLimitRandomNumber(maxNumber);
    }
    
}

Cette commande @RequestMapping(value="/rest") au niveau de la classe évite de devoir entrer rest dans chaque des méthodes.

La commande @RestController évite de devoir mettre ResponseBody avant chaque type de retour de fonction.

La commande @GetMapping est une nouveauté de Spring 4.3. C'est un raccourci pour

@RequestMapping(value = "/random", method = RequestMethod.GET)

L'équivalent existe pour post, put, delete et patch.

L'annotation @PathVariable indique que la variable fait partie de l'url.

Tomcat est embedded, pas besoin dans avoir un. Tomcat utlise par défaut le port 8080, il faudra donc l'ajouter à l'url appelé.

La première méthode pourra être appelé via l'ur http://localhost:8080/rest/random
alors qu'il que pour la seconde méthode il devra spécifier un nombre
http://localhost:8080/rest/random/20.

La couche de service retourne un nombre. Je m'attarderais pas dessus, vérifié les sources pour plus de détail.

L'application complète peut-être télécharger ici.

Si vous désirez démarrer l'application en dehors de environnement de travail. Générer une build. Un jar sera créé. Dans notre cas il se nommera: demo-0.0.1-SNAPSHOT.jar.

Pour lancer l'application: java -jar demo-0.0.1-SNAPSHOT.jar

Prenez note qu'il est possible d'utiliser d'autres serveurs tel que jetty, websphere et même le cloud.
Nous avons fait rapidement nos balbutiements avec Spring Boot.


jeudi 31 décembre 2015

Tiling sous Kde 5

Ceux qui cherche à faire du tiling, soit du positionnement de fenêtre automatique, sous Kde 5 il existe quelques solutions.

TIL3R

Installation

Dans l'outils de configuration du système, cliquer sur Gestion des fenêtres.


Cliquer sur Scripts de KWin et ensuite sur le bouton: Obtenir un nouveau script.


Chercher TIL3 et cliquer sur installer.

Configuration

Par défaut, les touches 

Meta+Alt+1: Left third, full height
Meta+Alt+2: Middle third, full height
Meta+Alt+3: Right third, full height

Meta+Alt+4: Left third, upper half 
Meta+Alt+5: Middle third, upper half
Meta+Alt+6: Right third, upper half
Meta+Alt+7: Left third, lower half 
Meta+Alt+8: Middle third, lower half
Meta+Alt+9: Right third, lower half


Meta+Ctrl+1: Left two thirds, full height
Meta+Ctrl+2: Right two thirds, full height

Meta+Ctrl+4: Left two thirds, upper half
Meta+Ctrl+5: Right two thirds, upper half
Meta+Ctrl+7: Left two thirds, lower half
Meta+Ctrl+8: Right two thirds, lower half

n'étaient pas fonctionnelles.

Il faut alors cliquer sur  Raccourcis dans Configuration du système. Cliquer sur Raccourcis globaux de clavier et sélectionner dans la section Composant KDE: Configuration du système.


On peut remarquer pour l'action: Mettre rapidement en mosaïque une fenêtre à droite, à gauche que des touches ont été affecté. La touche méta étant la touche Windows. J'ai opté pour les touches standard du créateur du logiciel.

Alternative

Il est possible d'utiliser kwin-tiling. L'installation peut se faire dans la fenêtre de configuration de script. J'ai eu une planoplie d'erreur en tentant de le faire fonctionner.

Une autre possibilité est de ne pas utiliser kwin et d'utiliser ainsi un autre gestionnaire de fenêtre (wm). Plusieurs existent sur cette page: https://wiki.archlinux.org/index.php/Comparison_of_tiling_window_managers. Cependant, il peut être difficile de configurer le tout.

vendredi 25 décembre 2015

Kde 5 vs Windows 10

Nous allons comparer l'environnement de bureau Kde 5 et celui de Windows 10.  Les deux ont optés pour un bureau sobre et léger.

Menu

Le menu de Windows ajoute des tuiles. Sous Kde, le groupement d'application se fait toujours via les catégories. Il y a cependant d'autre alternative de disponible.




Calculatrice





Configuration





Explorateur de fichier




Bureau

Le bureau est configurable à souhait via des composants graphiques (widtgets). Les activités sont toujours de la partie sans compté les bureaux virtuels.





Navigateur internet

Certaine distribution utilise Rekonq au lieu de Konqueror, malgré qu'il ne fasse pas partie du Kde Application officiellement.




Ressource système




Les deux environnements ont épuré leur environnement graphique. Les bureaux virtuels sont enfin accessibles sous Windows en natif. Un magasin d'application similaire au package logiciel est disponible. Cependant la musique y est ajouté.

jeudi 8 octobre 2015

Spring Rest et le jeton CSRF

Nous allons voir comment utiliser des jetons CSRF dans une application REST avec spring.
Dans ce type d'application, il n'y a pas de formulaire pour entrer un nom d'utilisateur et un mot de passe.

Lors de votre connexion au serveur, il est possible d'obtenir le jeton CSRF au lieu de faire une requête au serveur.

    var req = new XMLHttpRequest();
    req.open('GET', document.location, false);
    req.send(null);
    var csrf = req.getResponseHeader("x-csrf-token")

    var cookie = JSON.stringify({method: 'GET', url: '/', csrf: csrf});
    $.cookie('myWebApp', cookie);

Ensuite pour la connexion

    var cookie = JSON.parse($.cookie('myWebApp'));
    var data = 'username=' + $('#username').val() + '&password=' + $('#password').val();
    $.ajax({
        data: data,
        headers: {'X-CSRF-TOKEN': cookie.csrf},
        timeout: 1000,
        type: 'POST',
        url: '/login',
    }).done(function (data, textStatus, jqXHR) {
        var csrf = jqXHR.getResponseHeader("x-csrf-token")
        var cookie = JSON.stringify({method: 'GET', url: '/', csrf: csrf});
        $.cookie('chezlise', cookie);
        window.location = "main.html";
    })

A chaque requête vous devez vérifier si le jeton a changé et l'affecter à votre cookie au besoin.

Mis à part les requêtes de type GET, il faudra insérer le jeton dans vos requête ajax.

Au niveau du serveur, il faut créer une classe héritant de WebSecurityConfigurerAdapter

 @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class ServerApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Autowired
    private RESTAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private RESTAuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    private RESTAuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    private UserServiceImpl userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/rest/**").authenticated();
        //http.csrf().disable();
        http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
        http.formLogin().successHandler(authenticationSuccessHandler);
        http.formLogin().failureHandler(authenticationFailureHandler);
        http.logout().logoutUrl("/logout");
        http.logout().logoutSuccessUrl("/");
        
        // CSRF tokens handling
        http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);

    }
}

https://github.com/aditzel/spring-security-csrf-filter/blob/master/src/main/java/com/allanditzel/springframework/security/web/csrf/CsrfTokenResponseHeaderBindingFilter.java

Ensuite dans la classe de l'application

@EntityScan(basePackageClasses = {ServerApplication.class, Jsr310JpaConverters.class})
@SpringBootApplication
public class ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerApplication.class, args);
    }

    @Bean
    public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
        return new ServerApplicationSecurity();
    }

}

jeudi 1 octobre 2015

Mapping d'une date d'anniversaire en JPA.

La version 2.1 de JPA et la version 5 de MySQL ont été utilisé.

Une date d'anniversaire s'affiche sous le format: dd/MM/yyyy. Ce format varie d'une région à une autre. Une telle date ne possède pas d'heure.

Si vous ne spécifiez par le bon type dans votre entité, vos risques de ne pas obtenir le format désiré à l'affichage.

L'annotation Temporal offre 3 valeurs: Date, Time et Timestamp. Le time est inutile pour un anniversaire.

Selon l'annotation, voici le type de donnée et le type en bd..
@Temporal(javax.persistence.TemporalType.DATE)
Data type date
DB data type date

@Temporal(javax.persistence.TemporalType.TIMESTAMP)
Data type timestamp
DB data type datetime

Si vous n'en spécifiez aucun, vous obtiendrez ceux de TemporalType.TIMESTAMP.


@Entity
public class personne{
  @Temporal(javax.persistence.TemporalType.TIMESTAMP)
  private Date anniversaire;
  ...
}

Au niveau de votre DTO, vous devez spécifiez le format.

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
private Date birthdate;

La valeur qui sera transféré sera

"anniversaire":"17/06/1980" au lieu

"anniversaire":"1980-06-17"

Si vous utiliser l'annotation DateTimeFormat de spring

@DateTimeFormat(pattern = "dd/MM/yyyy") dans votre DTO, vous allez obtenir une valeur numérique similaire à  14360400000.       

Commande Mysql utile

Importer un script sql

mysql -p
use databasename
source nom_script.sql


Export du schéma de base de donnée


mysqldump -u root -p --no-data dbname > schema.sql
mysqldump -u root -p -d databasename > database.sql


Créer un utilisateur

CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';

Octroie des privilèges sur tout
GRANT ALL PRIVILEGES ON * . * TO 'newuser'@'localhost';

Active les privilèges immédiatement
FLUSH PRIVILEGES;