@@ -94,6 +94,40 @@ public java.time.Duration deserialize(JsonParser p, DeserializationContext ctxt)
9494 }
9595 }
9696
97+ /** Custom Jackson serializer for {@code byte[]} to output standard base64 without linefeeds. */
98+ static class CustomByteArraySerializer extends JsonSerializer <byte []> {
99+ @ Override
100+ public void serialize (byte [] value , JsonGenerator gen , SerializerProvider serializers )
101+ throws java .io .IOException {
102+ if (value == null ) {
103+ gen .writeNull ();
104+ } else {
105+ gen .writeString (java .util .Base64 .getEncoder ().encodeToString (value ));
106+ }
107+ }
108+ }
109+
110+ /** Custom Jackson deserializer for {@code byte[]} to support URL-safe base64 strings. */
111+ static class CustomByteArrayDeserializer extends JsonDeserializer <byte []> {
112+ @ Override
113+ public byte [] deserialize (JsonParser p , DeserializationContext ctxt )
114+ throws java .io .IOException , JsonProcessingException {
115+ String value = p .getValueAsString ();
116+ if (value == null ) {
117+ return null ;
118+ }
119+ try {
120+ if (value .contains ("-" ) || value .contains ("_" )) {
121+ return java .util .Base64 .getUrlDecoder ().decode (value );
122+ } else {
123+ return java .util .Base64 .getDecoder ().decode (value );
124+ }
125+ } catch (IllegalArgumentException e ) {
126+ throw ctxt .weirdStringException (value , byte [].class , "Failed to decode base64 string" );
127+ }
128+ }
129+ }
130+
97131 /** Configures the stream read constraints for the JSON parser. */
98132 private static void configureStreamReadConstraints (int maxReadLength ) {
99133 if (maxReadLength <= 0 ) {
@@ -116,6 +150,8 @@ private static void configureStreamReadConstraints(int maxReadLength) {
116150 SimpleModule customModule = new SimpleModule ();
117151 customModule .addSerializer (java .time .Duration .class , new CustomDurationSerializer ());
118152 customModule .addDeserializer (java .time .Duration .class , new CustomDurationDeserializer ());
153+ customModule .addSerializer (byte [].class , new CustomByteArraySerializer ());
154+ customModule .addDeserializer (byte [].class , new CustomByteArrayDeserializer ());
119155
120156 // Register JavaTimeModule for other java.time types *before* the custom module
121157 // This ensures our custom Duration handling takes precedence over the default one
0 commit comments