Spring MVC : Développer un convertisseur personnalisé

La modélisation d'une API REST permettant de gérer une ressource naturellement arborescente pose un problème technique intéressant.

Pour l'exemple, imaginons une API permettant de lire les métadonnées (taille, date d'accès...) d'un fichier sur disque, identifié par son chemin.
Selon la logique RESTful, l'URI associée au fichier foo/bar/baz.txt doit être http://<server:port>/file/foo/bar/baz.txt, et le endpoint Spring MVC associé mappé comme ceci :

@GetMapping("/file/{path}")
public HttpEntity<FileInfo> fileInfo(@PathVariable("path") String path) {
    return filesystemDao.getFileInfo(path);
}

Problème : Spring MVC ne sait pas capturer les fragments d'URL (@PathVariable) contenant des "slash" , même encodés en %2F.

En réfléchissant plus avant, on s'aperçoit que les "slash" ne sont pas les seuls caractères pouvant poser problème : les noms des répertoire et fichiers sont autorisés à contenir des caractères incompatibles avec les URLs. Il nous faut donc encoder tout le chemin, mais, à cause du bug indiqué plus haut, un simple "urlencode" ne suffit pas.
We need a bigger boat.

Lire la suite...

ExceptionContext : trying to improve business exceptions

In "corporate" projects, exceptions are often categorized as TechnicalExceptions and BusinessExceptions.

As technical exceptions usually have a wide application range (eg. DataAccessExceptions), their stacktraces help finding out the exact technical context in which they occurred.

However, for business exceptions, which are often more specific (eg. AuthenticationException) and whose origin in the code is well known, stacktraces are usually useless - but still expensive to generate. What would be more interesting though, is the _business context_ in which they occurred ; for example, knowing that the system failed while processing order #42's payment as part of the daily book-keeping batch is an important information.

Lire la suite...

Enigmatiques lambdas

Tout a commencé sur Twitter, lorsque Jean-Christophe Sirot (@jcsirot / Coding Stories) m'apostrophe à propos d'un étrange problème de compilation d'une lambda.

Pourquoi ce code compile-t-il...

public class Test {
    private final String s;
 
    public Test(String s) {
        this.s = s;
    }
 
    public Consumer<String> c = 
      (x) -> System.out.println(x + "/" + this.s);
}

...alors que celui-là refuse ?

public class Test {
    private final String s;
 
    public Test(String s) {
        this.s = s;
    }
 
    public Consumer<String> c = 
      (x) -> System.out.println(x + "/" + s);
}
Lire la suite...

C'est l'histoire d'une regex...

Si vous n'avez pas suivi le (micro-)feuilleton du moment sur Twitter, voici un résumé rapide.

Tout commence avec un tweet d'Emmanuel Lécharny :

Replacing a 5 lines method by a 140 lines one which is 15 times faster. Don't trust people who claim that less code is better.

Lire la suite...

Une astuce pour rendre la javadoc plus pratique

La Javadoc officielle est très bien faite, mais la présentation des packages sous la forme d'une interminable liste alphabétique n'est pas très ergonomique. En pratique, on se sert surtout de java.lang, java.util et ses sous-packages, un peu de java.io... et rarement des autres. Alors pourquoi ne pas les mettre en avant ?

En attendant qu'Oracle se décide à intégrer des fonctions de recherche ou un système de favoris au doclet standard, j'ai fini par hacker manuellement la javadoc afin de faciliter l'accès aux packages qui m'intéressent.

Lire la suite...

Lambdas et Underscores

Le saviez-vous ? Il est interdit d'utiliser un simple underscore (_) comme nom de paramètre de lambda. Cela a de quoi surprendre, étant donné que c'est un nom parfaitement valide pour un champ, un paramètre de méthode, ou une variable locale.

Lire la suite...

LP4J au Bordeaux JUG !

Tout d'abord, bonne année 2015 à tous et toutes !

Si vous êtes en manque de bonnes résolutions, permettez-moi de vous suggérer celles-ci, qui, à défaut de faire de vous un homme ou une femme meilleur(e), au cheveu brillant et au sourire #FFF, vous évitera au moins de finir découpé en rondelles par un collègue hystérique après un build rouge ou une mise en prod' ratée :

  • Arrêter de mettre des serialVersionUID dans toutes les classes pour faire plaisir à Eclipse ;
  • Traiter les "erreurs normales" visibles au lancement de l'application
  • Régler l'IDE en UTF8 dès le début du projet, pour ne pas vous faire appeler Martine
  • Arrêter de passer sournoisement les tests qui plantent en @Ignore
  • ... Je vous laisse compléter la liste, je suis sûr que vous avez des idées :)
Lire la suite...

Stream.distinct(), gare à la javadoc !

L'API Stream fournit une méthode distinct() permettant d'éliminer les éléments en doublon.
Sa Javadoc indique :

Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.

Cette description laisse penser qu'il suffit que nos objets implémentent equals() pour être correctement traités par distinct(), ce qui est faux (ou du moins incomplet).

Lire la suite...

Dernières nouvelles du front : MongoDB, Android et Java8

Je profite de la relative accalmie avant le cyclone DevoxxFR pour vous expliquer à quoi j'ai été occupé en ce début d'année, et pourquoi j'ai eu moins de temps - et j'en suis désolé - pour vous proposer des billets croustillants sur ce blog. Vous allez voir, c'était le rush !

Lire la suite...

Java 8 : petit exercice pour s'échauffer le neurone à lambda

A une semaine de Devoxx France 2014 qui risque d'être riche en sessions sur Java 8 et la programmation fonctionnelle, je vous propose un petit exercice pour vous dérouiller le neurone à lambdas.

Le but du jeu est d'écrire une fonction permettant de concaténer un certain nombre de listes, passées en paramètre sous forme de var-arg :

public <T> List<T> concatLists(List<T>... lists);

Evidemment, on essaiera d'utiliser le plus possible de nouvelles fonctionnalités de Java 8 - le but est de s'amuser et de tordre un peu Java, et pas forcément de respecter les bonnes pratiques industrielles.

Allez hop, en route !

Lire la suite...

- page 1 de 11