Thanks a lot for the response. As mentioned I have created an issue against
`Jackson-Databind`. Please find the link for the
same: https://github.com/FasterXML/jackson-databind/issues/3206
I used following work around to fix in my application:
`Customer.class` added the `@Extensions` on required fields:
```
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =
JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
public class Customer {
private String isA;
private String name;
@JsonSerialize(using = CustomSerializer.class)
@Extensions(extension = "extensions")
private Map<String, Object> extensions = new HashMap<>();
private Map<String, Object> withoutExtensions = new HashMap<>();
@JsonAnyGetter
@JsonSerialize(using = CustomSerializer.class)
@Extensions(extension = "withoutExtensions")
public Map<String, Object> getWithoutExtensions() {
return withoutExtensions;
}
}
```
`CustomSerializer`:
```
@NoArgsConstructor
public class CustomSerializer extends JsonSerializer<Map<String, Object>>
implements ContextualSerializer {
private String context = "";
public CustomSerializer(String context) {
this.context = context;
}
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen,
SerializerProvider serializers) {
if (this.context.equals("extensions")) {
System.out.println("Extensions : " + this.context);
} else if (this.context.equals("withoutExtensions")) {
System.out.println("Without Extensions : " + this.context);
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider
serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
Extensions extensions =
beanProperty.getAnnotation(Extensions.class);
if (extensions != null) {
return new CustomSerializer(extensions.extension());
}
return this;
}
}
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Extensions {
String extension();
}
```
On Monday, 12 July 2021 at 01:57:39 UTC+5:30 [email protected] wrote:
> On Sat, Jul 10, 2021 at 9:18 AM Aravinda Baliga B <[email protected]>
> wrote:
>
>> I am trying to create a JSON based on my Object class POJO. For some
>> fields, I would like to use the CustomSerializer as I would like to create
>> the fields according to my requirement. Hence, I have created the
>> `CustomSerializer.class`.
>>
>> The `CustomSerializer` will be called by 2 different fields in my `POJO`
>> and I would like to handle the things differently based on which field is
>> making the call. For one of the fields (`extensions`) I would like to have
>> the `fieldName` and for other field (`withoutExtensions`) I do not wish to
>> have the `fieldname` in my JSON.
>>
>> The problem I am facing is that when `CustomSerializer` is called then I
>> am getting the same `fieldname` for both the calls due to which I am unable
>> to make a differentiation which field is currently calling the
>> `CustomSerializer`.
>>
>> Following code samples will provide more clarity on the issue I am facing:
>>
>> `Customer` POJO class used for serializing the JSON:
>> ```
>> @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =
>> JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
>> @JsonInclude(JsonInclude.Include.NON_NULL)
>> @JsonIgnoreProperties(ignoreUnknown = true)
>> @Data
>> @NoArgsConstructor
>> public class Customer {
>> private String isA;
>> private String name;
>>
>> @JsonSerialize(using = CustomSerializer.class)
>> private Map<String, Object> extensions = new HashMap<>();
>>
>> private Map<String, Object> withoutExtensions = new HashMap<>();
>>
>> @JsonAnyGetter
>> @JsonSerialize(using = CustomSerializer.class)
>> public Map<String, Object> getWithoutExtensions() {
>> return withoutExtensions;
>> }
>>
>> }
>> ```
>>
>> Following is my `CustomSerializer` which will be called by 2 fields
>> (extensions and withoutExtensions) during the creation of JSON:
>> ```
>> public class CustomSerializer extends JsonSerializer<Map<String, Object>>
>> {
>>
>> @Override
>> public void serialize(Map<String, Object> value, JsonGenerator gen,
>> SerializerProvider serializers) {
>> //I would like to create the outer object for "Extensions" but do
>> not want to create outer object for "WithoutExtensions"
>>
>> System.out.println(gen.getOutputContext().getCurrentName());
>>
>> //In my case for both "Extensions" and "WithoutExtensions" i get
>> the "currentName" as "Extensions" how can I ensure which field is calling
>> this sealizer at
>> // present
>> }
>> }
>> ```
>>
>> Following is my `Main` class which will create a JSON:
>> ```
>> public class Main {
>> public static void main(String[] args) throws JsonProcessingException
>> {
>> final ObjectMapper objectMapper = new ObjectMapper();
>> objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
>> final Customer customer = new Customer();
>>
>> customer.setName("Jackson");
>>
>> Map<String, Object> extensions = new HashMap<>();
>> extensions.put("WithObject", "With");
>> customer.setExtensions(extensions);
>>
>> Map<String, Object> withoutExtensions = new HashMap<>();
>> extensions.put("WithoutObject", "Without");
>> customer.setWithoutExtensions(withoutExtensions);
>>
>> final String eventAsJson =
>> objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(customer);
>> System.out.println(eventAsJson);
>> }
>> }
>> ```
>>
>> As we can see when I run the application the `CustomSerializer` would
>> print `extensions` in both cases. I believe it should print `extensions`
>> only once and in the next case either it should provide `withoutExtensions`
>> or empty string.
>>
>> I just wanted to know if this an bug on the Jackson part or is there any
>> work-around that I can try to differentiate which field is making a call to
>> my `CustomSerializer`.
>>
>> Any help would be really appreciated. Thanks.
>>
>
> Ok, so the problem here is, I think, that the second call is for
> so-called "any getter":
>
> @JsonAnyGetter
> @JsonSerialize(using = CustomSerializer.class)
> public Map<String, Object> getWithoutExtensions() {
> return withoutExtensions;
> }
>
> which does not have a logical property name associated with it. I am
> guessing that "current name" is then just leftover from the previous
> property. This sounds like a bug, I think -- while I am not 100% sure what
> value should be used, it should probably be cleared.
> Maybe empty String would make most sense.
> Similarly I wonder if any property name is associated with individual "any
> properties".
>
> Would you be so kind as to file an issue against jackson-databind,
> outlining what you wrote above?
> I think this is worth addressing for 2.13 or later versions.
>
> -+ Tatu +-
>
>
> --
>> 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 [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/jackson-user/b493e599-9ac4-43c2-a520-3d74729ea44dn%40googlegroups.com
>>
>> <https://groups.google.com/d/msgid/jackson-user/b493e599-9ac4-43c2-a520-3d74729ea44dn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>
--
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jackson-user/9651957e-e3c2-4bef-9698-b26ecf93089en%40googlegroups.com.