[jackson-user] Re: Custom mapper for conditional map serialization
Is @JsonSerialize still around? You could annotate fields with that annotation and jackson would delegate serializing those fields to that particular serializer. But your code would remain largely the same - you'd still need to check what to write depending on the field. I suppose you could cheat by having that field be some value interface type Foo, and implementations assigned to that field be FooMap or FooString, where FooString would have dedicated to string serializer. Deserializing on the other hand of such structures is painful, but nothing you couldn't handle with @JsonDeserialize. On Saturday, April 27, 2024 at 2:08:47 AM UTC Viktor Remennik wrote: > Hi there! > > I hope it's a simple question but I cannot find an answer myself. So, > asking for help. > I need to implement custom map serializer when mam mets some condition. > the problem is, that I need to replace the map with a primitive type, e.g. > string. As a simple example - when map conforms to some rule I want to > replace it with, let's say, string value. I understand there could be at > least one case when primitive, like string, cannot be used witout a key. > It's probably if the map is the root node.Maybe I could generate a key for > such a case? > Anyways, I cannot achieve it in any way I tried. Here's the MVE for my > question. I want to make it producing this: > { > "Second" : "Two", > "Third" : "magic string", > "First" : 1 > } > > instead of default: > > { > "Second" : "Two", > "Third" : { > "Eleventh" : 11, > "Twelfth" : "12" > }, > "First" : 1 > } > > Here's the mve itself. Thank you! > > > public class MapParseTest > > { > > private final ObjectMapper mapper; > > > public MapParseTest() > > { > > mapper = new ObjectMapper(); > > SimpleModule module = new SimpleModule(); > > module.setSerializerModifier(new MyMapSerializerModifier()); > > mapper.registerModule(module); > > } > > > public void doTest() throws JsonProcessingException > > { > > MyMap map1 = new MyMap(); > > MyMap map2 = new MyMap(); > > > map1.setName("shtame"); > > map2.setName("magic name"); > > > map1.put("First", 1); > > map1.put("Second", "Two"); > > map1.put("Third", map2); > > > map2.put("Eleventh", 11); > > map2.put("Twelfth", "12"); > > > String result = > mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map1); > > System.*out*.println(result); > > } > > > public static void main(String[] args) throws JsonProcessingException > > { > > MapParseTest test = new MapParseTest(); > > test.doTest(); > > } > > > @Setter > > @Getter > > public static class MyMap extends HashMap > > { > > private String name; > > } > > > public static class MyMapSerializer extends JsonSerializer > > { > > private final JsonSerializer defaultSerializer; > > > public MyMapSerializer(JsonSerializer defaultSerializer) > > { > > this.defaultSerializer = defaultSerializer; > > } > > > @Override > > public void serialize(MyMap value, > > JsonGenerator gen, > > SerializerProvider provider) throws > IOException > > { > > String className = value.getName(); > > if (className.equalsIgnoreCase("magic name")) > > { > > gen.writeString("magic string"); > > } else > > { > > defaultSerializer.serialize(value, gen, provider); > > } > > } > > } > > > public static class MyMapSerializerModifier extends > BeanSerializerModifier > > { > > @Override > > public JsonSerializer modifyMapSerializer(SerializationConfig > config, > > MapType mapType, > > BeanDescription > beanDesc, > > JsonSerializer > serializer) > > { > > Class type = beanDesc.getBeanClass(); > > if (type.equals(MyMap.class)) > > { > > return new MyMapSerializer((JsonSerializer) > serializer); > > } > > return serializer; > > } > > } > > } > > > > > -- You received this message because you are subscribed to the Google Groups "jackson-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/c8ae5a12-a96c-4153-9dd8-460f8e2576f6n%40googlegroups.com.
[jackson-user] Re: Custom mapper for conditional map serialization
See the polymorphic handling documentation https://github.com/FasterXML/jackson-annotations?tab=readme-ov-file#handling-polymorphic-types On Saturday, April 27, 2024 at 3:27:30 PM UTC Mantas Gridinas wrote: Is @JsonSerialize still around? You could annotate fields with that annotation and jackson would delegate serializing those fields to that particular serializer. But your code would remain largely the same - you'd still need to check what to write depending on the field. I suppose you could cheat by having that field be some value interface type Foo, and implementations assigned to that field be FooMap or FooString, where FooString would have dedicated to string serializer. Deserializing on the other hand of such structures is painful, but nothing you couldn't handle with @JsonDeserialize. On Saturday, April 27, 2024 at 2:08:47 AM UTC Viktor Remennik wrote: Hi there! I hope it's a simple question but I cannot find an answer myself. So, asking for help. I need to implement custom map serializer when mam mets some condition. the problem is, that I need to replace the map with a primitive type, e.g. string. As a simple example - when map conforms to some rule I want to replace it with, let's say, string value. I understand there could be at least one case when primitive, like string, cannot be used witout a key. It's probably if the map is the root node.Maybe I could generate a key for such a case? Anyways, I cannot achieve it in any way I tried. Here's the MVE for my question. I want to make it producing this: { "Second" : "Two", "Third" : "magic string", "First" : 1 } instead of default: { "Second" : "Two", "Third" : { "Eleventh" : 11, "Twelfth" : "12" }, "First" : 1 } Here's the mve itself. Thank you! public class MapParseTest { private final ObjectMapper mapper; public MapParseTest() { mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.setSerializerModifier(new MyMapSerializerModifier()); mapper.registerModule(module); } public void doTest() throws JsonProcessingException { MyMap map1 = new MyMap(); MyMap map2 = new MyMap(); map1.setName("shtame"); map2.setName("magic name"); map1.put("First", 1); map1.put("Second", "Two"); map1.put("Third", map2); map2.put("Eleventh", 11); map2.put("Twelfth", "12"); String result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map1); System.*out*.println(result); } public static void main(String[] args) throws JsonProcessingException { MapParseTest test = new MapParseTest(); test.doTest(); } @Setter @Getter public static class MyMap extends HashMap { private String name; } public static class MyMapSerializer extends JsonSerializer { private final JsonSerializer defaultSerializer; public MyMapSerializer(JsonSerializer defaultSerializer) { this.defaultSerializer = defaultSerializer; } @Override public void serialize(MyMap value, JsonGenerator gen, SerializerProvider provider) throws IOException { String className = value.getName(); if (className.equalsIgnoreCase("magic name")) { gen.writeString("magic string"); } else { defaultSerializer.serialize(value, gen, provider); } } } public static class MyMapSerializerModifier extends BeanSerializerModifier { @Override public JsonSerializer modifyMapSerializer(SerializationConfig config, MapType mapType, BeanDescription beanDesc, JsonSerializer serializer) { Class type = beanDesc.getBeanClass(); if (type.equals(MyMap.class)) { return new MyMapSerializer((JsonSerializer) serializer); } return serializer; } } } -- You received this message because you are subscribed to the Google Groups "jackson-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/11650d10-27d3-4635-8af3-188de34e34b6n%40googlegroups.com.
[jackson-user] Re: Custom mapper for conditional map serialization
Thank you for your reply. Yep, my fault, it's just a mve, I actually receive an 'Object o' which I need to serialize, that's why i doubt i could annotate it as it is received from external source. I mean, i cannot annotate fields of this object and would like to avoid modifying it as it should be used further in the program. I don't need deserialization, just serialization. On Saturday, April 27, 2024 at 6:27:30 PM UTC+3 Mantas Gridinas wrote: > Is @JsonSerialize still around? You could annotate fields with that > annotation and jackson would delegate serializing those fields to that > particular serializer. But your code would remain largely the same - you'd > still need to check what to write depending on the field. I suppose you > could cheat by having that field be some value interface type Foo, and > implementations assigned to that field be FooMap or FooString, where > FooString would have dedicated to string serializer. Deserializing on the > other hand of such structures is painful, but nothing you couldn't handle > with @JsonDeserialize. > > On Saturday, April 27, 2024 at 2:08:47 AM UTC Viktor Remennik wrote: > >> Hi there! >> >> I hope it's a simple question but I cannot find an answer myself. So, >> asking for help. >> I need to implement custom map serializer when mam mets some condition. >> the problem is, that I need to replace the map with a primitive type, e.g. >> string. As a simple example - when map conforms to some rule I want to >> replace it with, let's say, string value. I understand there could be at >> least one case when primitive, like string, cannot be used witout a key. >> It's probably if the map is the root node.Maybe I could generate a key for >> such a case? >> Anyways, I cannot achieve it in any way I tried. Here's the MVE for my >> question. I want to make it producing this: >> { >> "Second" : "Two", >> "Third" : "magic string", >> "First" : 1 >> } >> >> instead of default: >> >> { >> "Second" : "Two", >> "Third" : { >> "Eleventh" : 11, >> "Twelfth" : "12" >> }, >> "First" : 1 >> } >> >> Here's the mve itself. Thank you! >> >> >> public class MapParseTest >> >> { >> >> private final ObjectMapper mapper; >> >> >> public MapParseTest() >> >> { >> >> mapper = new ObjectMapper(); >> >> SimpleModule module = new SimpleModule(); >> >> module.setSerializerModifier(new MyMapSerializerModifier()); >> >> mapper.registerModule(module); >> >> } >> >> >> public void doTest() throws JsonProcessingException >> >> { >> >> MyMap map1 = new MyMap(); >> >> MyMap map2 = new MyMap(); >> >> >> map1.setName("shtame"); >> >> map2.setName("magic name"); >> >> >> map1.put("First", 1); >> >> map1.put("Second", "Two"); >> >> map1.put("Third", map2); >> >> >> map2.put("Eleventh", 11); >> >> map2.put("Twelfth", "12"); >> >> >> String result = >> mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map1); >> >> System.*out*.println(result); >> >> } >> >> >> public static void main(String[] args) throws JsonProcessingException >> >> { >> >> MapParseTest test = new MapParseTest(); >> >> test.doTest(); >> >> } >> >> >> @Setter >> >> @Getter >> >> public static class MyMap extends HashMap >> >> { >> >> private String name; >> >> } >> >> >> public static class MyMapSerializer extends JsonSerializer >> >> { >> >> private final JsonSerializer defaultSerializer; >> >> >> public MyMapSerializer(JsonSerializer defaultSerializer) >> >> { >> >> this.defaultSerializer = defaultSerializer; >> >> } >> >> >> @Override >> >> public void serialize(MyMap value, >> >> JsonGenerator gen, >> >> SerializerProvider provider) throws >> IOException >> >> { >> >> String className = value.getName(); >> >> if (className.equalsIgnoreCase("magic name")) >> >> { >> >> gen.writeString("magic string"); >> >> } else >> >> { >> >> defaultSerializer.serialize(value, gen, provider); >> >> } >> >> } >> >> } >> >> >> public static class MyMapSerializerModifier extends >> BeanSerializerModifier >> >> { >> >> @Override >> >> public JsonSerializer modifyMapSerializer(SerializationConfig >> config, >> >> MapType mapType, >> >> BeanDescription >> beanDesc, >> >> JsonSerializer >> serializer) >> >> { >> >> Class type = beanDesc.getBeanClass(); >> >> if (type.equals(MyMap.class)) >> >> { >> >> return new M