Vincent Lecomte
[Java] Filtre sur liste avec les streams

[Java] Filtre sur liste avec les streams

L’une des grosses améliorations de Java 8, c’est ce qu’on appelle les streams. C’est un nouveau pattern de manipulation de données et cela permet de se passer notamment des itérateurs que l’on connait. On peut les utiliser sur des collections ou même des tableaux.

On prend la classe suivante comme exemple :

public class MyObject
{
 private String sId;
 private String sName;
 
 // ...
}

Une méthode nous retourne alors une liste qui reprend des objets caractérisés par leur nom et un identifiant. On voudrait filtrer la liste pour ne récupérer que les objets nommés “chair” par exemple.

Stream<MyObject> lo_s = lo_listObj.stream().filter(
 myObj -> myObj.getName().equals("chair")
);

Le paramètre de la méthode filter() est un prédicat (type Predicate). Le code ci-dessus renvoie un stream que l’on peut ensuite manipuler pour retourner une collection ou bien un seul objet. Par exemple on pourrait utiliser la méthode collect() pour renvoyer une nouvelle liste.

List<Myobject> lo_list = lo_s.collect(Collectors.toList());

On peut aussi retourner le premier objet qui correspond au filtre, avec findFirst(). Cela retourne un objet de type Optional.

Optional<MyObject> lo_opt = lo_s.findFirst();

Plusieurs opérations sont possibles sur cet objet. On peut savoir s’il y a bien un résultat avec la méthode isPresent(), ou bien retourner directement le résultat ou une autre valeur si aucun objet n’avait été trouvé lors du filtre.

MyObject lo_result = lo_opt.orElse(lo_defaultObject);

La méthode orElse() renvoie la valeur qui avait été trouvée et si elle n’est pas présente, alors elle renvoie un autre objet du même type.

if (lo_opt.isPresent())
{
 MyObject lo_result = lo_opt.get();
}

L’exemple ci-dessus montre comment récupérer l’objet uniquement s’il est présent et pour également éviter l’exception NoSuchElementException. Cela peut être un raccourci à la méthode orElse(), tout dépend de quoi on a besoin en retour et ce qu’on va en faire.

[Java] Mémo – Validation de beans

[Java] Mémo – Validation de beans

En Java, il est possible d’utiliser la validation de beans pour permettre d’en valider son contenu, donc les différents membres de la classe. Par exemple, si on a une classe “Personne“, qui contient un nom et un prénom, on voudrait valider que ceux-ci ne dépassent pas une certaine taille ou même qu’ils respectent une expression régulière. Plutôt que de créer des méthodes visant à vérifier chaque élément un à un, on va se baser sur des annotations.

Prenons la classe suivante comme référence pour ce 1er exemple :

public class Person
{
    @Size(min = 1, max = 5, message = "cod: btw. 1 and 5")
    private String      cod;
 
    @Size(max = 60, message = "firstName: Length max 60")
    private String      firstName;

    @NotNull(message = "birthdate: mandatory")
    private LocalDate   birthdate;
 
    // ...
}

On utilise l’annotation Size pour définir la taille maximum qu’une chaine peut avoir. Si on ne spécifie pas de minimum, cela veut dire que la chaine peut être vide. A chaque fois on spécifie le paramètre “message” pour indiquer quel sera le message retourné lors de la validation.

Pour récupérer les erreurs sous forme de chaine :

Person lo_p = new Person();
Set<ConstraintViolation<T>> lo_violations = 
 Validation.buildDefaultValidatorFactory()
  .getValidator()
  .validate(lo_p);
for (ConstraintViolation<T> lo_violation : lo_violations)
{
    System.out.println(lo_violation.getMessage());
}

Ce code affiche les messages en fonction des champs qui sont en erreur par rapport à l’objet qu’on donne en paramètre de la méthode validate().

Si notre classe contient une liste d’objets que l’on veut aussi valider, ou un objet d’une autre classe, il faut rajouter une annotation Valid pour qu’il soit pris en compte lors de la validation.

public class PremObj
{
    @Size(min = 1, max = 20, message = "id: btw. 1 and 20")
    private String                  id;
 
    @Valid
    @NotNull(message = "liste_sousobj: Mandatory")
    private List<UnSousObj>  liste_sousobj;
 
    // ...
}

Chaque objet de la liste sera donc analysé. C’est aussi valable si on avait mis un seul objet de type “UnSousObj“. La classe que l’on référence doit évidemment posséder diverses annotations de validation.

Un champ peut également être validé sur base de valeurs d’une énumération. On peut ainsi utiliser l’annotation Enum (sur une variable de type String). Le paramètre obligatoire “enumClass” permet de spécifier la classe qui servira à la validation.

D’autres annotations utiles :

  • Pattern : sur une chaine, permet de faire en sorte qu’elle respecte une expression régulière.
  • Min : indique la valeur minimale d’un nombre.
  • Max : indique la valeur maximale d’un nombre.

Liens

Liste des annotations disponibles

[Windows 7] Impossible d’éteindre le PC

[Windows 7] Impossible d’éteindre le PC

Après les récents problèmes de moteur de recherche sous Windows 10, qui étaient en fait dus à une indisponibilité de Bing, les utilisateurs de Windows 7 rencontrent également des difficultés… pour éteindre leur PC. Soudainement le système d’exploitation les informe qu’ils n’ont pas les droits pour réaliser l’opération d’extinction. Le site Bleeping Computer explique que cela pourrait provenir d’une corruption des policies, – donc des stratégies de groupe, – ou des récentes mises à jour.

(image: hothardware.com)

Plusieurs utilisateurs indiquent avoir créé un nouveau compte administrateur sur lequel ils se sont connectés pour ensuite revenir sur leur compte habituel afin de retrouver les droits. Microsoft est au courant des soucis rencontrés. Cela pourrait également provenir d’une mise à jour problématique d’Adobe et des services liés… Tout cela reste donc à confirmer.

Sources

Bleeping Computer

[Utilitaires] Plugin Compare pour Notepad++

[Utilitaires] Plugin Compare pour Notepad++

Si vous cherchez un plugin de comparaison pour la version 64 bits de Notepad++, vous pouvez télécharger celui proposé par le développeur Pavel Nedev. Il vous permettra de mettre en évidence les différences dans deux fichiers texte, et si ceux-ci correspondent vous serez directement notifié par l’outil.

Téléchargez donc la version 64 bits. Pour l’installer:

  • Depuis Notepad++ cliquez sur le menu Compléments puis sur Open plugins folder…
  • Par défaut cela ouvre C:\Program Files\Notepad++\plugins
  • Créez un sous-dossier “ComparePlugin“.
  • Décompressez le contenu de l’archive dans ce nouveau dossier.

Vous devriez donc obtenir quelque chose de similaire à la capture d’écran ci-dessous.

Fermez Notepad++ puis relancez-le. Vous devriez donc avoir le menu

[SQL] Rechercher du texte dans un BLOB

[SQL] Rechercher du texte dans un BLOB

En SQL il est possible de rechercher du texte dans une colonne de type BLOB. Attention que cette méthode s’applique à la base de données Oracle. On utilise des méthodes internes qui permettent de convertir le terme cherché en données brutes et effectuer une recherche de caractères dans la colonne.

Voici le code à utiliser :

SELECT *
FROM t1
WHERE DBMS_LOB.INSTR (
   t1.champ_blob, 
   UTL_RAW.cast_to_raw (
     'Search text'
   ), 1, 1 
) > 0

Explications:

  • Le premier paramètre de la méthode “instr” est le champ BLOB dans lequel on veut effectuer la recherche.
  • L’appel à UTL_RAW.cast_to_raw en tant que second paramètre, permet de convertir la chaine de recherche en données brutes (RAW)
  • Le troisième paramètre de la méthode est l’indice à partir du quel on cherche.
  • Le quatrième paramètre indique quelle occurrence on souhaite (dans l’exemple on récupère la première)
  • Enfin le résultat est un la position de l’occurrence trouvée. Dans notre cas on vérifie qu’elle est supérieure à 0 juste pour récupérer tout ce qui correspond au terme de recherche

C’est plutôt pratique quand on stocke par exemple du XML ou du JSON dans un champ de type BLOB.

[JS] Prism, une alternative à SyntaxHighlighter

[JS] Prism, une alternative à SyntaxHighlighter

En guise d’alternative au très bon SyntaxHighlighter développé par Alex Gorbatchev (voir le site ici) mais qui n’est malheureusement plus mis à jour, on peut utiliser Prism.js.

Il offre la coloration syntaxique pour afficher du code de manière à ce qu’il soit lisible par les utilisateurs. Il se veut intuitif et extensible car il est possible d’ajouter assez facilement des langages à ceux déjà pris en charge. On peut même basculer entre différents thèmes. La librairie est utilisée par de nombreux sites tels que React ou même Drupal.

Pour l’utiliser sur Blogger comme c’est mon cas, il faut importer les scripts et styles de base. Et pour cela il faut modifier le thème du blog. Depuis le tableau de bord de votre blog choisissez Thème puis cliquez sur Modifier le code HTML.

Juste avant l’élément fermant head du thème, il faut inclure les feuilles de style.

<link href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism.css' rel='stylesheet'/>
<link href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/line-numbers/prism-line-numbers.css' rel='stylesheet'/>

De même qu’il faut inclure le script et l’autoloader avant la fermeture de l’élément body. On y ajoute aussi les différents plugins que l’on veut utiliser. Les éléments obligatoires sont prism-core et prism-autoloader.

<script src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/components/prism-core.min.js'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/autoloader/prism-autoloader.min.js'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/plugins/line-numbers/prism-line-numbers.min.js'/>

Ensuite on peut commencer à utiliser les blocs de code. Il faut utiliser les balises pre et code. La seconde prendra une classe qui sera le langage du code que l’on veut formater. La liste complète est disponible sur le site officiel. La classe peut être language-* ou lang-*, l’astérisque étant remplacée par le bon code pioché dans la liste.

<pre>
<code class="lang-html">
<!-- Code qu'on veut formater -->
</code>
</pre>

Il faut faire attention car il faut échapper les caractères du code à formater, sinon il sera évidemment interprété (très important donc si on veut afficher du HTML au lecteur).

Pour éviter de le faire à la main utilisez plutôt l’outil en ligne Quick Escape Tool.Petit truc supplémentaire avant de nous quitter : afin d’utiliser le plugin line-numbers (destiné à afficher les numéros de ligne) que nous avons importé dans le second exemple ci-dessus, il vous suffira d’ajouter la classe “line-numbers” à l’élément ouvrant pre. N’hésitez pas à consulter le site officiel : vous y découvrirez de nombreux plugins ainsi que des tutoriels.

Bon développement !

Prismjs.com

[Info] Changement des blocs de code

[Info] Changement des blocs de code

Retour après un temps d’inactivité assez prolongé pour annoncer quelques nouveautés sur le blog. Je me suis mis à la recherche d’un autre script pour générer les blocs de code et en ai trouvé un plutôt sympathique. Il s’agit de Prism.js. Il propose de nombreux plugins et supporte de nombreux langages.

Avec ce changement le blog est également passé en HTTPS : malgré qu’il n’y ait pas spécialement d’échanges de données sensibles ce n’est pas plus mal.

Si vous voyez des articles où des blocs de code auraient été oubliés, n’hésitez pas à me le signaler en commentaire. Ils sont assez faciles à repérer car ils ne seront tout simplement pas formatés correctement (pas de cadre, pas d’affichage des numéros de ligne, pas de coloration syntaxique, etc).

[Windows] Bug de Cortana après la KB4512941

[Windows] Bug de Cortana après la KB4512941

Après application de la mise à jour KB4512941 sur la build 1903 de Windows 10, certains utilisateurs – dont je fais partie – ont remonté un bug plutôt gênant. En effet, si la recherche via Bing a été désactivée par le registre ou par la gestion des stratégies de groupes, cela va provoquer une utilisation élevée du CPU par le processus Cortana. En ouvrant le gestionnaire de tâches, on peut constater que l’utilisation varie entre 35 et 40%.

Divers témoignages rapportent que la recherche est alors indisponible lors d’un clic sur l’icône dans la barre de tâches et ce même après de longues minutes d’attente. Sur la page listant les changements de la mise à jour, Microsoft dit ne pas avoir connaissance d’éventuels problèmes.

Rassurez-vous! Il existe une solution pour corriger ce problème. Une petite manipulation de rien du tout. Voyez donc ci-dessous…

En attendant un correctif officiel il faut donc aller bidouiller dans la base de registre. Pour cela, effectuez les manipulations suivantes:

  • Appuyez sur les touches Windows+R de votre clavier pour ouvrir la boite de dialogue “Exécuter“.
  • Saisissez “regedit” puis confirmez par la touche Entrée ou le bouton OK.
  • Le contrôle de comptes utilisateurs vous demandera de confirmer l’action, ce que vous devrez évidemment faire en répondant Oui.
  • Dans la barre de recherche, saisissez la clé suivante : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search – et appuyez sur Entrée pour l’afficher.
  • Double-cliquez sur la valeur “BingSearchEnabled” et indiquez la valeur “1”. Confirmez par OK.
  • Forcez la fermeture du processus de Cortana ou redémarrez l’ordinateur.

Notez qu’après avoir effectué cette modification, les requêtes saisies dans la recherche seront envoyées au moteur de recherche Bing quoiqu’il arrive.

Sources

BleepingComputer
Phonandroid

[Jeux vidéo] Now playing… #2

[Jeux vidéo] Now playing… #2

Vous jouez à la console ou sur PC ? Parce que moi oui, et même si je n’y consacre pas ma vie entière, c’est tout de même l’un de mes principaux hobbies. Alors si vous cherchez de l’inspiration vous êtes tombés au bon endroit. Un petit conseil… attachez vos ceintures, ça pourrait vous être utile pour la suite !

Après la réédition des trois premiers titres de Crash Bandicoot, le marsupial fait son retour avec son kart. Le jeu est actuellement disponible sur Nintendo Switch, PS4 et Xbox One. Rappelez-vous le bon vieux temps où vous jetiez missiles, bombes et fioles sur vos adversaires pour gagner la course. Et ce fameux Nitros Oxide qui explosait tous les records du Contre-la-montre… Et bien, tout est là et c’est tant mieux. Le jeu remis au goût du jour, propose du challenge et trois modes de difficulté de l’IA pour permettre à tout public de le prendre en main.

Il n’empêche qu’il faudra s’entrainer à maitriser la poussée turbo pour gagner l’ensemble des épreuves, notamment pour débloquer N.Tropy. Visuellement parlant, le jeu est coloré, vivant, les graphismes plutôt soignés même si on regrette l’absence des 60 images par seconde, vraiment un plus dans un jeu où la vitesse est présente… et surtout que l’ensemble des consoles actuelles le permettraient très facilement. On apprécie évidemment les suppléments tels que le Grand Prix ou le multijoueur (même si le mode en ligne a eu quelques débuts difficiles). Beenox cherche à s’assurer que les joueurs ne s’ennuieront pas trop vite ! Et selon moi le pari est plutôt réussi. Les nostalgiques aimeront !

S’il y a bien un jeu qu’il n’est plus trop nécessaire de présenter, c’est bien Assassin’s Creed. Dans ce nouvel opus, nommé “Odyssey“, vous explorerez la Grèce antique. Vous choisissez votre héro, homme ou femme, et partez donc à l’aventure pour faire tomber les plus grands mercenaires mais aussi les adeptes du Culte de Kosmos. Il vous faudra affronter toutes sortes de dangers, que ce soit sur la terre ou en mer, puisque les navires font leur grand retour.

On pourrait reprocher énormément de choses à Ubisoft par rapport aux précédents opus, mais le travail réalisé sur ce dernier épisode est plutôt incroyable. Le jeu ne manque pas de contenu, et les zones à explorer sont nombreuses. Le système d’évolution du personnage est plutôt bien pensé et permet au joueur d’adapter son style de combat en diversifiant les aptitudes. Tir de 3 flèches, percée de bouclier, les attaques peuvent être variées que ce soit au corps-à-corps ou à distance. Il faudra également penser à bien faire évoluer son armure. Différents sets peuvent être trouvés et ceux-ci apportent des bonus supplémentaires lorsqu’ils sont complets et/ou utilisés avec certaines aptitudes.

Bref, ce n’est pas le fun qui manque et les accros de l’exploration n’hésiteront pas à visiter tous les points d’intérêt, ne serait-ce que pour découvrir les différentes régions “redessinées” par le studio. Ce qui est sûr, c’est que l’on s’y croirait…

[Java] Gestion des erreurs à l’aide d’une servlet

[Java] Gestion des erreurs à l’aide d’une servlet

Dans votre application web, il est possible de réaliser une gestion d’exceptions – notamment pour intercepter ServletException – en passant par une servlet. Par défaut, les erreurs telles que le code HTTP 500 sont gérées par le serveur et renvoient vers une page par défaut. L’idée est donc de changer ce comportement en renvoyant par exemple une information en JSON ou en redirigeant vers une JSP.

On va donc créer une classe qui hérite de HttpServlet. Celle-ci devra implémenter des fonctions pour gérer les différentes méthodes HTTP (exemple : PUT, GET, POST…).

public class MaServletHttp extends HttpServlet 
{
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) throws IOException 
    {
        // On gère l'erreur...
    }
}

Comme on peut le constater on a donc créé une fonction qui sera exécutée lorsque la méthode GET est utilisée. Typiquement lorsqu’on appelle une URL et qu’on spécifie un ensemble de paramètres dans celle-ci. Il faudra donc ajouter les autres fonctions comme doPost() – généralement appelée lors d’un envoi de formulaire – ou doPut().On remarque aussi l’annotation @WebServlet qui permet de définir tout un ensemble d’informations utiles, notamment l’ “URL pattern”. On peut soit spécifier cette valeur directement comme dans l’exemple ci-dessus, soit en spécifiant les attributs de la manière suivante.

@WebServlet(
        name = "maBelleServlet",
        description = "Gestion d'exceptions",
        urlPatterns = "/maServletHttp"
)
public class MaServletHttp extends HttpServlet 
{
    // Code de la servlet...
}

Certains attributs de la servlet ne sont utiles que pour les outils utilisés lors du développement (par exemple, description ou encore smallIcon). Ces attributs sont décrits dans la documentation de JavaEE 7.Il faut ensuite modifier le fichier web.xml pour spécifier dans quels cas la servlet doit être appelée pour gérer les exceptions ou les différents code d’erreur. Dans l’exemple ci-dessous on va faire en sorte que la servlet soit appelée en cas d’erreur HTTP 500.

<web-app ... >
    <error-page> 
        <error-code>500</error-code> 
        <location>/maServletHttp</location> 
    </error-page>
</web-app>

On a donc ajouté un élément “error-page” dans le fichier descriptif de l’application. Pour cet élément on a spécifié le code d’erreur grâce à l’élément “error-code” et l’emplacement de la servlet (qui correspond au URL pattern défini précédemment dans l’annotation de la classe Java) représenté par l’élément “location“.

A la place de l’élément “error-code” on peut aussi spécifier “exception-type” et indiquer les erreurs que la servlet devra intercepter. On y spécifie alors le canonical name de la classe d’exception visée (ex : java.lang.NullPointerException).

Une fois le fichier de configuration XML modifié, on peut s’attaquer au code de la servlet. Aussi bien lorsqu’on redirige vers une JSP qu’une servlet, des attributs contenant des informations à propos de l’erreur qui se produit, sont définis au niveau de la requête et peuvent donc être rapatriés dans le code.

@WebServlet("/maServletHttp")
public class MaServletHttp extends HttpServlet 
{
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) throws IOException 
    {
        Integer li_st = (Integer) request.getAttribute(
                "javax.servlet.error.status_code"
        );

        Throwable lo_e = (Throwable) request.getAttribute(
                "javax.servlet.error.exception"
        );

        String ls_svlt = (String) request.getAttribute(
                "javax.servlet.error.servlet_name"
        );
        
        // Envoi de la réponse après.
        // Voir ci-dessous.
    }
}

Voici le tableau des attributs disponibles (source : tutorialspoint).

L’attribut qui contient le nom de la servlet est intéressant car il s’agit de la source, là où l’erreur s’est produite. Cela signifie qu’en fonction du nom on peut imaginer un traitement différent en retour.L’exemple ci-dessous renvoie simplement du JSON au client après une erreur dans un Web Service.

@WebServlet("/maServletHttp")
public class MaServletHttp extends HttpServlet 
{
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) throws IOException 
    {
        // Récupération des attributs avant.
        // Voir ci-dessus.
        if (ls_svlt.equals("webserviceServlet"))
        {
            response.setContentType("application/json");
            response.getWriter().print(
                "{ key1: 'val1', key2: 'val2' }"
            );

            response.getWriter().flush();
        }
    }
}

On peut également modifier le code de retour (par exemple, si le code était 500, on peut le redéfinir au niveau de l’objet HttpServletResponse).

Sources

Baeldung
CodeJava.net
LogicBig
Oracle
Tutorialspoint

Copy link