Skip to content

Commit d4ba034

Browse files
committed
Refine RedisSerializer implementations.
This commit polishes up method ordering, introduces Javadoc where missing and updates nullability annotations and argument names. Closes #1097
1 parent 468254d commit d4ba034

13 files changed

+154
-134
lines changed

src/main/java/org/springframework/data/redis/serializer/ByteArrayRedisSerializer.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ enum ByteArrayRedisSerializer implements RedisSerializer<byte[]> {
2929

3030
@Nullable
3131
@Override
32-
public byte[] serialize(@Nullable byte[] bytes) throws SerializationException {
33-
return bytes;
32+
public byte[] serialize(@Nullable byte[] value) throws SerializationException {
33+
return value;
3434
}
3535

3636
@Nullable

src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementReader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class DefaultRedisElementReader<T> implements RedisElementReader<T> {
3131

3232
private final @Nullable RedisSerializer<T> serializer;
3333

34-
DefaultRedisElementReader(RedisSerializer<T> serializer) {
34+
DefaultRedisElementReader(@Nullable RedisSerializer<T> serializer) {
3535
this.serializer = serializer;
3636
}
3737

src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementWriter.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class DefaultRedisElementWriter<T> implements RedisElementWriter<T> {
3535
}
3636

3737
@Override
38-
public ByteBuffer write(T value) {
38+
public ByteBuffer write(@Nullable T value) {
3939

4040
if (serializer != null && (value == null || serializer.canSerialize(value.getClass()))) {
4141
return ByteBuffer.wrap(serializer.serialize(value));
@@ -51,6 +51,5 @@ public ByteBuffer write(T value) {
5151

5252
throw new IllegalStateException(
5353
String.format("Cannot serialize value of type %s without a serializer", value.getClass()));
54-
5554
}
5655
}

src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java

+19-18
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,6 @@
6666
*/
6767
public class GenericJackson2JsonRedisSerializer implements RedisSerializer<Object> {
6868

69-
/**
70-
* Register {@link NullValueSerializer} in the given {@link ObjectMapper} with an optional
71-
* {@code classPropertyTypeName}. This method should be called by code that customizes
72-
* {@link GenericJackson2JsonRedisSerializer} by providing an external {@link ObjectMapper}.
73-
*
74-
* @param objectMapper the object mapper to customize.
75-
* @param classPropertyTypeName name of the type property. Defaults to {@code @class} if {@literal null}/empty.
76-
* @since 2.2
77-
*/
78-
public static void registerNullValueSerializer(ObjectMapper objectMapper, @Nullable String classPropertyTypeName) {
79-
80-
// Simply setting {@code mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)} does not help here
81-
// since we need the type hint embedded for deserialization using the default typing feature.
82-
objectMapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer(classPropertyTypeName)));
83-
}
8469

8570
private final JacksonObjectReader reader;
8671

@@ -203,6 +188,22 @@ private Supplier<String> newTypeHintPropertyNameSupplier(ObjectMapper mapper, @N
203188
.or("@class");
204189
}
205190

191+
/**
192+
* Register {@link NullValueSerializer} in the given {@link ObjectMapper} with an optional
193+
* {@code classPropertyTypeName}. This method should be called by code that customizes
194+
* {@link GenericJackson2JsonRedisSerializer} by providing an external {@link ObjectMapper}.
195+
*
196+
* @param objectMapper the object mapper to customize.
197+
* @param classPropertyTypeName name of the type property. Defaults to {@code @class} if {@literal null}/empty.
198+
* @since 2.2
199+
*/
200+
public static void registerNullValueSerializer(ObjectMapper objectMapper, @Nullable String classPropertyTypeName) {
201+
202+
// Simply setting {@code mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)} does not help here
203+
// since we need the type hint embedded for deserialization using the default typing feature.
204+
objectMapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer(classPropertyTypeName)));
205+
}
206+
206207
/**
207208
* Gets the configured {@link ObjectMapper} used internally by this {@link GenericJackson2JsonRedisSerializer}
208209
* to de/serialize {@link Object objects} as {@literal JSON}.
@@ -214,14 +215,14 @@ protected ObjectMapper getObjectMapper() {
214215
}
215216

216217
@Override
217-
public byte[] serialize(@Nullable Object source) throws SerializationException {
218+
public byte[] serialize(@Nullable Object value) throws SerializationException {
218219

219-
if (source == null) {
220+
if (value == null) {
220221
return SerializationUtils.EMPTY_ARRAY;
221222
}
222223

223224
try {
224-
return writer.write(mapper, source);
225+
return writer.write(mapper, value);
225226
} catch (IOException cause) {
226227
String message = String.format("Could not write JSON: %s", cause.getMessage());
227228
throw new SerializationException(message, cause);

src/main/java/org/springframework/data/redis/serializer/GenericToStringSerializer.java

+36-29
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.springframework.beans.TypeConverter;
2323
import org.springframework.beans.factory.BeanFactory;
2424
import org.springframework.beans.factory.BeanFactoryAware;
25-
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
2625
import org.springframework.core.convert.ConversionService;
2726
import org.springframework.core.convert.support.DefaultConversionService;
2827
import org.springframework.lang.Nullable;
@@ -42,8 +41,7 @@ public class GenericToStringSerializer<T> implements RedisSerializer<T>, BeanFac
4241

4342
private final Class<T> type;
4443
private final Charset charset;
45-
46-
private Converter converter = new Converter(new DefaultConversionService());
44+
private Converter converter;
4745

4846
public GenericToStringSerializer(Class<T> type) {
4947
this(type, StandardCharsets.UTF_8);
@@ -55,55 +53,64 @@ public GenericToStringSerializer(Class<T> type, Charset charset) {
5553

5654
this.type = type;
5755
this.charset = charset;
56+
this.converter = new Converter(DefaultConversionService.getSharedInstance());
5857
}
5958

59+
/**
60+
* Set the {@link ConversionService} to be used.
61+
*
62+
* @param conversionService the conversion service to be used, must not be {@literal null}.
63+
*/
6064
public void setConversionService(ConversionService conversionService) {
6165

62-
Assert.notNull(conversionService, "non null conversion service required");
66+
Assert.notNull(conversionService, "ConversionService must not be null");
67+
6368
converter = new Converter(conversionService);
6469
}
6570

71+
/**
72+
* Set the {@link TypeConverter} to be used.
73+
*
74+
* @param typeConverter the conversion service to be used, must not be {@literal null}.
75+
*/
6676
public void setTypeConverter(TypeConverter typeConverter) {
6777

68-
Assert.notNull(typeConverter, "non null type converter required");
78+
Assert.notNull(typeConverter, "TypeConverter must not be null");
79+
6980
converter = new Converter(typeConverter);
7081
}
7182

7283
@Override
73-
public T deserialize(@Nullable byte[] bytes) {
84+
public byte[] serialize(@Nullable T value) {
7485

75-
if (bytes == null) {
86+
if (value == null) {
7687
return null;
7788
}
7889

79-
String string = new String(bytes, charset);
80-
return converter.convert(string, type);
90+
String string = converter.convert(value, String.class);
91+
return string.getBytes(charset);
8192
}
8293

8394
@Override
84-
public byte[] serialize(@Nullable T object) {
85-
if (object == null) {
95+
public T deserialize(@Nullable byte[] bytes) {
96+
97+
if (bytes == null) {
8698
return null;
8799
}
88-
String string = converter.convert(object, String.class);
89-
return string.getBytes(charset);
100+
101+
String string = new String(bytes, charset);
102+
return converter.convert(string, type);
90103
}
91104

105+
@Override
92106
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
93-
94-
// TODO: This code can never happen...
95-
if (converter == null && beanFactory instanceof ConfigurableBeanFactory) {
96-
ConfigurableBeanFactory cFB = (ConfigurableBeanFactory) beanFactory;
97-
ConversionService conversionService = cFB.getConversionService();
98-
99-
converter = (conversionService != null ? new Converter(conversionService)
100-
: new Converter(cFB.getTypeConverter()));
101-
}
107+
// no-op
102108
}
103109

104-
private class Converter {
105-
private final ConversionService conversionService;
106-
private final TypeConverter typeConverter;
110+
private final static class Converter {
111+
112+
private final @Nullable ConversionService conversionService;
113+
private final @Nullable TypeConverter typeConverter;
107114

108115
public Converter(ConversionService conversionService) {
109116
this.conversionService = conversionService;
@@ -115,11 +122,11 @@ public Converter(TypeConverter typeConverter) {
115122
this.typeConverter = typeConverter;
116123
}
117124

125+
@Nullable
118126
<E> E convert(Object value, Class<E> targetType) {
119-
if (conversionService != null) {
120-
return conversionService.convert(value, targetType);
121-
}
122-
return typeConverter.convertIfNecessary(value, targetType);
127+
128+
return conversionService != null ? conversionService.convert(value, targetType)
129+
: typeConverter.convertIfNecessary(value, targetType);
123130
}
124131
}
125132
}

src/main/java/org/springframework/data/redis/serializer/Jackson2JsonRedisSerializer.java

+27-26
Original file line numberDiff line numberDiff line change
@@ -126,32 +126,6 @@ public Jackson2JsonRedisSerializer(ObjectMapper mapper, JavaType javaType, Jacks
126126
this.javaType = javaType;
127127
}
128128

129-
@SuppressWarnings("unchecked")
130-
public T deserialize(@Nullable byte[] bytes) throws SerializationException {
131-
132-
if (SerializationUtils.isEmpty(bytes)) {
133-
return null;
134-
}
135-
try {
136-
return (T) this.reader.read(this.mapper, bytes, javaType);
137-
} catch (Exception ex) {
138-
throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
139-
}
140-
}
141-
142-
@Override
143-
public byte[] serialize(@Nullable Object t) throws SerializationException {
144-
145-
if (t == null) {
146-
return SerializationUtils.EMPTY_ARRAY;
147-
}
148-
try {
149-
return this.writer.write(this.mapper, t);
150-
} catch (Exception ex) {
151-
throw new SerializationException("Could not write JSON: " + ex.getMessage(), ex);
152-
}
153-
}
154-
155129
/**
156130
* Sets the {@code ObjectMapper} for this view. If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper}
157131
* is used.
@@ -171,6 +145,33 @@ public void setObjectMapper(ObjectMapper mapper) {
171145
this.mapper = mapper;
172146
}
173147

148+
@Override
149+
public byte[] serialize(@Nullable T value) throws SerializationException {
150+
151+
if (value == null) {
152+
return SerializationUtils.EMPTY_ARRAY;
153+
}
154+
try {
155+
return this.writer.write(this.mapper, value);
156+
} catch (Exception ex) {
157+
throw new SerializationException("Could not write JSON: " + ex.getMessage(), ex);
158+
}
159+
}
160+
161+
@Override
162+
@SuppressWarnings("unchecked")
163+
public T deserialize(@Nullable byte[] bytes) throws SerializationException {
164+
165+
if (SerializationUtils.isEmpty(bytes)) {
166+
return null;
167+
}
168+
try {
169+
return (T) this.reader.read(this.mapper, bytes, javaType);
170+
} catch (Exception ex) {
171+
throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
172+
}
173+
}
174+
174175
/**
175176
* Returns the Jackson {@link JavaType} for the specific class.
176177
* <p>

src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -82,30 +82,30 @@ public JdkSerializationRedisSerializer(Converter<Object, byte[]> serializer,
8282
}
8383

8484
@Override
85-
public Object deserialize(@Nullable byte[] bytes) {
85+
public byte[] serialize(@Nullable Object value) {
8686

87-
if (SerializationUtils.isEmpty(bytes)) {
88-
return null;
87+
if (value == null) {
88+
return SerializationUtils.EMPTY_ARRAY;
8989
}
9090

9191
try {
92-
return deserializer.convert(bytes);
92+
return serializer.convert(value);
9393
} catch (Exception cause) {
94-
throw new SerializationException("Cannot deserialize", cause);
94+
throw new SerializationException("Cannot serialize", cause);
9595
}
9696
}
9797

9898
@Override
99-
public byte[] serialize(@Nullable Object object) {
99+
public Object deserialize(@Nullable byte[] bytes) {
100100

101-
if (object == null) {
102-
return SerializationUtils.EMPTY_ARRAY;
101+
if (SerializationUtils.isEmpty(bytes)) {
102+
return null;
103103
}
104104

105105
try {
106-
return serializer.convert(object);
106+
return deserializer.convert(bytes);
107107
} catch (Exception cause) {
108-
throw new SerializationException("Cannot serialize", cause);
108+
throw new SerializationException("Cannot deserialize", cause);
109109
}
110110
}
111111
}

src/main/java/org/springframework/data/redis/serializer/OxmSerializer.java

+14-14
Original file line numberDiff line numberDiff line change
@@ -85,34 +85,34 @@ public void afterPropertiesSet() {
8585
}
8686

8787
@Override
88-
public Object deserialize(@Nullable byte[] bytes) throws SerializationException {
88+
public byte[] serialize(@Nullable Object value) throws SerializationException {
8989

90-
if (SerializationUtils.isEmpty(bytes)) {
91-
return null;
90+
if (value == null) {
91+
return SerializationUtils.EMPTY_ARRAY;
9292
}
9393

94+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
95+
StreamResult result = new StreamResult(stream);
96+
9497
try {
95-
return unmarshaller.unmarshal(new StreamSource(new ByteArrayInputStream(bytes)));
98+
marshaller.marshal(value, result);
9699
} catch (Exception ex) {
97-
throw new SerializationException("Cannot deserialize bytes", ex);
100+
throw new SerializationException("Cannot serialize object", ex);
98101
}
102+
return stream.toByteArray();
99103
}
100104

101105
@Override
102-
public byte[] serialize(@Nullable Object t) throws SerializationException {
106+
public Object deserialize(@Nullable byte[] bytes) throws SerializationException {
103107

104-
if (t == null) {
105-
return SerializationUtils.EMPTY_ARRAY;
108+
if (SerializationUtils.isEmpty(bytes)) {
109+
return null;
106110
}
107111

108-
ByteArrayOutputStream stream = new ByteArrayOutputStream();
109-
StreamResult result = new StreamResult(stream);
110-
111112
try {
112-
marshaller.marshal(t, result);
113+
return unmarshaller.unmarshal(new StreamSource(new ByteArrayInputStream(bytes)));
113114
} catch (Exception ex) {
114-
throw new SerializationException("Cannot serialize object", ex);
115+
throw new SerializationException("Cannot deserialize bytes", ex);
115116
}
116-
return stream.toByteArray();
117117
}
118118
}

src/main/java/org/springframework/data/redis/serializer/RedisElementWriter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.nio.ByteBuffer;
1919

20+
import org.springframework.lang.Nullable;
2021
import org.springframework.util.Assert;
2122

2223
/**
@@ -36,7 +37,7 @@ public interface RedisElementWriter<T> {
3637
* @param element can be {@literal null}.
3738
* @return the {@link ByteBuffer} representing {@code element} in its binary form.
3839
*/
39-
ByteBuffer write(T element);
40+
ByteBuffer write(@Nullable T element);
4041

4142
/**
4243
* Create new {@link RedisElementWriter} using given {@link RedisSerializer}.

0 commit comments

Comments
 (0)