11
votes

Gestion des noms de propriété alternatif à Jackson Déserialization

Je travaille sur la conversion d'un service de repos / JSON de ColdFusion 9 en une application Spring-MVC 3.1. J'utilise Jackson (1.9.5) et le Mappingjacksonjsonconverter que Spring fournit et personnaliser l'ObjectMapper pour nommer des champs avec Camel_Case_To_Lower_case_with_underscores.

Le problème que je suis confronté est que notre service hérité produit 'cas de chameau en majuscule avec des sous-traitants' comme noms de propriété JSON. Les consommateurs de ce Json, également écrits à Coldfusion, se soucieraient de se soucier de celles-ci, mais Jackson se soucie de l'affaire, et jette des idées non reconnuesPropertyExceptions. P>

Après avoir examiné à peu près tous les paramètres de ObjectMapper - DesérializationConfig, DesérializerizerSprovider, etc., j'ai fini avec un piratage très désordonné dans lequel j'utilise un arbre JSON, de la sortie avec un jsongenerator personnalisé qui abaissent les noms de champs, puis la analyse sous forme d'objet. P>

public class JsonNamingTest {
    public static class CaseInsensitive extends LowerCaseWithUnderscoresStrategy {
        public String translate(String in) {
            return (in.toUpperCase().equals(in) ? in : super.translate(in));
        }
    }

    public static class A {
        private String testField;
        public String getTestField() {
            return testField;
        }
        public void setTestField(String field) {
            this.testField = field;
        }
        @JsonProperty("TEST_FIELD")
        public void setFieldAlternate(String field) {
            this.testField = field;
        }
    }

    @Test
    public void something() throws Exception {
        A test = new A();
        test.setTestField("test");
        ObjectMapper mapper = new ObjectMapper().setPropertyNamingStrategy(new CaseInsensitive());
        assertEquals("{\"test_field\":\"test\"}", mapper.writeValueAsString(test));
        assertEquals("test", mapper.readValue("{\"test_field\":\"test\"}", A.class).getTestField());
        assertEquals("test", mapper.readValue("{\"TEST_FIELD\":\"test\"}", A.class).getTestField());
    }
}


0 commentaires

4 Réponses :


6
votes

Vous pouvez utiliser la charte de la charte: xxx


2 commentaires

Merci pour la suggestion. Je l'ai essayé, mais cela ne résout pas le problème. Le problème semble être que la stratégie de dénomination est d'une manière. Compte tenu d'un pojo avec des champs, des setters, des getters et des constructeurs pouvant avoir des annotations sur eux, convertissez-les en noms de champ JSON. Un champ / méthode / constructeur ne peut que mapper un nom de champ JSON.


En outre, la charte de la propriété est appliquée après toutes les annotations. Donc, si je devais annoter deux setters, une @jsonProperty ("Test_field") et une autre @jsonProperty ("Test_field"), la conversion en minuscule provoquera la collision de ces deux régleurs, ce qui jette une exception.



5
votes

Depuis que vous utilisez Jackson 1.x et non Jackson 2.x, vous pouvez utiliser des mixines. D'après ce que je comprends, vous voulez que la désérialisation comprenne Upper_Case, mais vous voulez sérialiser dans BASTER_CASE. Ajoutez un mixin dans la configuration de désériorialisation mais pas dans la configuration de sérialisation, en tant que telle: xxx

Cependant, vous ne pouvez pas faire cela avec Jackson 2.x: Les mélanges sont partagés par la sérialisation et la désérialisation config. Je n'ai pas encore trouvé un moyen de gérer des alias avec Jackson 2.x: (


0 commentaires

13
votes

Ceci a été corrigé à partir de Jackson 2.5.0.

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);


1 commentaires

mapper.enable (mapperfeature.accept_case_insensitive_properti es); devrait également fonctionner.



1
votes

Lorsque vous utilisez un démarrage à ressort, il est également possible d'utiliser le Jackson2ObjectMapperBuilderCustomizer qui conserve la configuration automatique par défaut. Cela peut être fait en ajoutant un haricot: xxx


0 commentaires