{"id":2007,"date":"2025-09-10T14:14:43","date_gmt":"2025-09-10T12:14:43","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/?p=2007"},"modified":"2025-12-05T12:46:24","modified_gmt":"2025-12-05T11:46:24","slug":"characterescapes-jacksons-hidden-gem","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/characterescapes-la-perle-cachee-de-jackson\/","title":{"rendered":"CharacterEscapes: la perle cach\u00e9e de Jackson"},"content":{"rendered":"<p>A <a href=\"https:\/\/www.kestra.io\">Kestra<\/a>, la plateforme d&rsquo;orchestration de donn\u00e9es pour laquelle je travaille, on a eu une issue (<a href=\"https:\/\/github.com\/kestra-io\/kestra\/issues\/10326\">#10326<\/a>) ouverte d&rsquo;un utilisateur qui rapportait un probl\u00e8me avec la base PostgreSQL et le caract\u00e8re Unicode <code>\\u0000<\/code>. Une t\u00e2che de workflow qui retournait ce caract\u00e8re en outpout plantait.<\/p>\n<p>Apr\u00e8s investigation, PostgreSQL refuse de stocker une entr\u00e9e JSONB contenant ce caract\u00e8re, car il n&rsquo;a pas de repr\u00e9sentation textuelle. En effet, c&rsquo;est le caract\u00e8re null en Unicode, celui-ci n&rsquo;est pas autoris\u00e9 en JSON qui repr\u00e9sente null par la cha\u00eene de caract\u00e8res <code>null<\/code>.<\/p>\n<p>Entre en action une fonctionnalit\u00e9 cach\u00e9e de Jackson, que nous utilisons pour notre couche de s\u00e9rialisation JSON, <code>CharacterEscapes<\/code>.\nCette classe permet de configurer la fa\u00e7on donc Jackson va \u00e9chapper (<strong>escape<\/strong> en anglais) les caract\u00e8res sp\u00e9ciaux et nous permettre d&rsquo;\u00e9chapper le caract\u00e8re Unicode <code>\\u0000<\/code> et \u00e9viter de planter une t\u00e2che de workflow qui le retournerait en output.<\/p>\n<pre><code class=\"language-java\">public class SafeguardCharacterEscapes extends CharacterEscapes { \/\/ &lt;1&gt;\n    private static final SerializableString NULL = new SerializedString(&quot;null&quot;); \/\/ &lt;2&gt;\n\n    private final int[] asciiEscapes;\n\n    SafeguardCharacterEscapes() {\n        \/\/ &lt;3&gt; Start with the standard JSON escapes\n        asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON();\n        \/\/ &lt;4&gt; And then specify that the null character should be escaped\n        asciiEscapes[0] = CharacterEscapes.ESCAPE_CUSTOM;\n    }\n\n    @Override\n    public int[] getEscapeCodesForAscii() {\n        return asciiEscapes;\n    }\n\n    @Override\n    public SerializableString getEscapeSequence(int ch) {\n        if (ch == 0) {\n            return NULL; \/\/ &lt;5&gt;\n        }\n        return null; \/\/ &lt;6&gt;\n    }\n}\n<\/code><\/pre>\n<ol><li>On cr\u00e9\u00e9 notre propre impl\u00e9mentation de <code>CharacterEscapes<\/code>, elle sera utilis\u00e9e lors de la configuration de l&rsquo; <code>ObjectMapper<\/code> Jackson. Voir ci-dessous.<\/li>\n<li>On d\u00e9finit une String pr\u00e9-calcul\u00e9e qui sera utilis\u00e9 lors de la s\u00e9rialisation du caract\u00e8re, elle retournera la cha\u00eene de caract\u00e8re <code>null<\/code>.<\/li>\n<li>On pr\u00e9-calcul les codes d&rsquo;\u00e9chappements pour la plage de caract\u00e8res ASCII, comme ces caract\u00e8res sont les plus utilis\u00e9s, ils ont un chemin rapide via un tableau de correspondance qu&rsquo;on pr\u00e9-calcul ici en r\u00e9cup\u00e9rant les codes d&rsquo;\u00e9chappement standard.<\/li>\n<li>On remplace le code d&rsquo;\u00e9chappement standard du caract\u00e8re ASCII <code><\/code>, qui correspond au caract\u00e8re unicode <code>\\u0000<\/code>, car les 128 premiers caract\u00e8res unicodes coincident avec la place ASCII, par une s\u00e9quence d&rsquo;\u00e9chappement personnalis\u00e9e (<strong>custom<\/strong> en anglais). Les s\u00e9quences personnalis\u00e9es sont d\u00e9finies dynamiquement par la m\u00e9thode <code>getEscapeSequence(int)<\/code>.<\/li>\n<li>On retourne notre String pr\u00e9-calcul\u00e9e comme s\u00e9quence personnalis\u00e9e pour le caract\u00e8re qui correspond au <em>code point<\/em> 0.<\/li>\n<li>On retourne <code>null<\/code> pour toutes les autres indiquant qu&rsquo;il n&rsquo;y a pas d&rsquo;autre s\u00e9quence d&rsquo;\u00e9chappement personnalis\u00e9e.<\/li>\n<\/ol>\n<p>Derni\u00e8re \u00e9tape, on va configurer l&rsquo; <code>ObjectMapper<\/code> de Jackson pour utiliser notre <code>CharacterEscapes<\/code> personnalis\u00e9:<\/p>\n<pre><code class=\"language-java\">ObjectMapper objectMapper = new ObjectMapper();\nobjectMapper.getFactory().setCharacterEscapes(new SafeguardCharacterEscapes());\n<\/code><\/pre>\n<p>Et voil\u00e0, avec \u00e7a, plus de t\u00e2che qui plantent ! Merci Jackson et sa perle cach\u00e9e <code>CharacterEscapes<\/code>!<\/p>\n<p>Pour finir, apr\u00e8s discussion, nous avons d\u00e9cid\u00e9 de ne pas int\u00e9grer ce changement dans Kestra. Si le caract\u00e8re n&rsquo;est pas support\u00e9 par PostgreSQL, il y a une bonne raison. Un output de t\u00e2che doit \u00eatre repr\u00e9sentable en JSON et <code>\\0000<\/code> n&rsquo;est pas un JSON valide.\nMais m\u00eame si nous n&rsquo;avons pas int\u00e9gr\u00e9 ce changement, je trouvais la fonctionnalit\u00e9 suffisamment int\u00e9ressante pour vous la faire d\u00e9couvrir ;).<\/p>","protected":false},"excerpt":{"rendered":"<p>A Kestra, la plateforme d&rsquo;orchestration de donn\u00e9es pour laquelle je travaille, on a eu une issue (#10326) ouverte d&rsquo;un utilisateur qui rapportait un probl\u00e8me avec la base PostgreSQL et le caract\u00e8re Unicode \\u0000. Une t\u00e2che de workflow qui retournait ce caract\u00e8re en outpout plantait. Apr\u00e8s investigation, PostgreSQL refuse de stocker une entr\u00e9e JSONB contenant ce caract\u00e8re, car il n&rsquo;a pas de repr\u00e9sentation textuelle. En effet, c&rsquo;est le caract\u00e8re null en Unicode, celui-ci n&rsquo;est pas autoris\u00e9 en JSON qui repr\u00e9sente null&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/characterescapes-la-perle-cachee-de-jackson\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"federated","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[230,211],"class_list":["post-2007","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-jackson","tag-kestra"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1847,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/jooq-tip-ne-convertissez-pas-jsonb-en-string\/","url_meta":{"origin":2007,"position":0},"title":"jOOQ tip: ne convertissez pas JSONB en String","author":"admin","date":"mercredi 23 octobre 2024","format":false,"excerpt":"Il y a quelques semaines, en investiguant de possibles am\u00e9liorations de performance pour le backend JDBC de Kestra, j'ai remarqu\u00e9 qu'une m\u00e9thode qu'on utilisait pour mapper une entit\u00e9 \u00e0 persister en base de donn\u00e9es dans sa repr\u00e9sentation JSONB prenait beaucoup de temps dans nos profiles CPU. Dans le flame graph\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/366507373-c44206a5-0085-43cc-902e-97756319b0ea-1024x737.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/366507373-c44206a5-0085-43cc-902e-97756319b0ea-1024x737.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/366507373-c44206a5-0085-43cc-902e-97756319b0ea-1024x737.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1786,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/concevoir-un-saas-multitenant\/","url_meta":{"origin":2007,"position":1},"title":"Concevoir un SaaS multitenant","author":"admin","date":"mardi  5 mars 2024","format":false,"excerpt":"Cet article se repose sur mon talk Concevoir un SaaS multitenant fait \u00e0 Cloud Nord le 12 octobre 2023. Kestra est une plate-forme d\u2019orchestration et de scheduling de donn\u00e9e hautement scalabe, qui cr\u00e9e, ex\u00e9cute, planifie et surveille des millions de pipelines complexes. Pour une introduction \u00e0 Kestra, vous pouvez lire\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/kestra-software-architecture-1024x576.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/kestra-software-architecture-1024x576.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/kestra-software-architecture-1024x576.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1611,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/introduction-a-kestra\/","url_meta":{"origin":2007,"position":2},"title":"Introduction \u00e0 Kestra","author":"admin","date":"lundi  6 mars 2023","format":false,"excerpt":"Kestra est un orchestrateur et scheduler de donn\u00e9e open source. Avec Kestra, les workflows de donn\u00e9es, appel\u00e9s flows, utilisent le format YAML et sont ex\u00e9cut\u00e9s par son moteur via un appel API, l'interface utilisateur, ou un trigger (webhook, schedule, SQL query, Pub\/Sub message, \u2026). Les notions importantes de Kestra sont\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/kestra-01-1024x267.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/kestra-01-1024x267.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/kestra-01-1024x267.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1650,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/le-profiler-sql-de-visualvm\/","url_meta":{"origin":2007,"position":3},"title":"Le profiler SQL de VisualVM","author":"admin","date":"mardi  4 avril 2023","format":false,"excerpt":"Il y a peu, j'ai d\u00e9couvert le profiler SQL de VisualVM et je me suis dit que je devais aussi vous le faire d\u00e9couvrir ;). VisualVM est un outil qui fournit une interface visuelle pour afficher des informations d\u00e9taill\u00e9es sur les applications qui s'ex\u00e9cutent sur une machine virtuelle Java (JVM).\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2023-04-03-14-17-25-1024x624.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2023-04-03-14-17-25-1024x624.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2023-04-03-14-17-25-1024x624.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1606,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/au-revoir-zenika-bonjour-kestra\/","url_meta":{"origin":2007,"position":4},"title":"Au revoir Zenika, bonjour Kestra","author":"admin","date":"mardi 10 janvier 2023","format":false,"excerpt":"Apr\u00e8s 4 ans, 4 mois et 4 jours (ou presque), je quitte Zenika. Ces 4 ann\u00e9es et quelques auront \u00e9t\u00e9 parmi les plus passionnantes de ma vie professionnelle. Je suis triste de quitter cette super soci\u00e9t\u00e9 dans laquelle j'ai pu m'\u00e9panouir, grandir et apprendre plein de choses. Je suis s\u00fbr\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1731,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/optimisation-dindex-postgresql\/","url_meta":{"origin":2007,"position":5},"title":"Optimisation d&rsquo;index PostgreSQL","author":"admin","date":"mardi 22 ao\u00fbt 2023","format":false,"excerpt":"Il y a quelque temps, j\u2019avais travaill\u00e9 sur des optimisations de temps d'ex\u00e9cution de requ\u00eates pour PostgreSQL, j'en parle ici : LE PROFILER SQL DE VISUALVM. Kestra est une plate-forme d\u2019orchestration et de scheduling de donn\u00e9e hautement scalable, qui cr\u00e9e, ex\u00e9cute, planifie, et surveille des millions de pipelines complexes. C\u2019est\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/2007","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=2007"}],"version-history":[{"count":6,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/2007\/revisions"}],"predecessor-version":[{"id":2040,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/2007\/revisions\/2040"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=2007"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=2007"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=2007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}