Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@JsonFormat (and other annotations) is ignored after adding custom serializer to specified type #4713

Open
1 task done
hetot opened this issue Sep 24, 2024 · 1 comment
Open
1 task done
Labels
need-test-case To work on issue, a reproduction (ideally unit test) needed

Comments

@hetot
Copy link

hetot commented Sep 24, 2024

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

Problem:
I wanted to change default pattern of formatting for OffsetDateTime (only if the field is not annotated with @JsonFormat)

Solution:
I realized custom serializer which extends JsonSerializer<OffsetDateTime>. I also implemented ContextualSerializer in order to define is field annotated or not, all annotated fields will be passed to default serializer. I made custom modifier (exteded BeanSerializerModifier) to get and pass default serializer to my custom serializer.

I tested my serializer with unannotated OffsetDateTime fields and default format is working. But when I tried fields with @JsonFormat(pattern=...), I realized that defaultSerializer has ignored the pattern and used its default one but I expected pattern which is defined in @JsonFormat

Version Information

2.15.4

Reproduction

Custom Serializer:

class CustomOffsetDateTimeSerializer(
    private val defaultSerializer: JsonSerializer<*>,
    private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern(defaultPattern),
) : JsonSerializer<OffsetDateTime>(), ContextualSerializer {
    companion object {
        private const val defaultPattern = "yyyy-MM-dd'T'HH:mm"
    }

    override fun serialize(
        value: OffsetDateTime,
        jsonGenerator: JsonGenerator,
        serializerProvider: SerializerProvider?,
    ) {
        jsonGenerator.writeString(formatter.format(value))
    }

    override fun createContextual(
        prov: SerializerProvider?,
        property: BeanProperty?,
    ): JsonSerializer<*> {
        if (property?.getAnnotation(JsonFormat::class.java) != null) {
            return defaultSerializer
        }

        return CustomOffsetDateTimeSerializer(defaultSerializer)
    }
}

Custom Modifier:

class CustomOffsetDateTimeModifier : BeanSerializerModifier() {
    override fun modifySerializer(
        config: SerializationConfig?,
        beanDesc: BeanDescription,
        serializer: JsonSerializer<*>,
    ): JsonSerializer<*> {
        if (beanDesc.beanClass == OffsetDateTime::class.java) {
            return CustomOffsetDateTimeSerializer(serializer)
        }
        return super.modifySerializer(config, beanDesc, serializer)
    }
}

Expected behavior

No response

Additional context

No response

@hetot hetot added the to-evaluate Issue that has been received but not yet evaluated label Sep 24, 2024
@cowtowncoder
Copy link
Member

cowtowncoder commented Sep 25, 2024

2.15.4 is not the latest so please make sure to verify with 2.17.2 or 2.18.0-rc1. Ideally before filing issue :)

Also looks like reproduction is in Kotlin so I may need to move to Kotlin module (although might be easy enough to translate to plain Java to keep here).

Also: code is not complete enough as reproduction: would need code to show configuration, calls to serialize.

@cowtowncoder cowtowncoder added need-test-case To work on issue, a reproduction (ideally unit test) needed and removed to-evaluate Issue that has been received but not yet evaluated labels Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need-test-case To work on issue, a reproduction (ideally unit test) needed
Projects
None yet
Development

No branches or pull requests

2 participants