Skip to content

Commit 8f841c5

Browse files
committed
update to spring boot 4 and fix update issues
1 parent 6ac1a28 commit 8f841c5

8 files changed

Lines changed: 147 additions & 97 deletions

File tree

pom.xml

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45

56
<parent>
67
<groupId>org.springframework.boot</groupId>
78
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>3.5.7</version>
9+
<version>4.0.0</version>
910
<relativePath/> <!-- lookup parent from repository -->
1011
</parent>
1112

@@ -52,7 +53,7 @@
5253
<dependency>
5354
<groupId>io.github.classgraph</groupId>
5455
<artifactId>classgraph</artifactId>
55-
<version>4.8.181</version>
56+
<version>4.8.184</version>
5657
</dependency>
5758

5859

@@ -61,7 +62,7 @@
6162
<dependency>
6263
<groupId>commons-validator</groupId>
6364
<artifactId>commons-validator</artifactId>
64-
<version>1.10.0</version>
65+
<version>1.10.1</version>
6566
<exclusions>
6667
<exclusion>
6768
<groupId>commons-collections</groupId>
@@ -78,7 +79,7 @@
7879
<dependency>
7980
<groupId>org.springdoc</groupId>
8081
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
81-
<version>2.8.14</version>
82+
<version>3.0.0</version>
8283
</dependency>
8384

8485
<!-- Testing -->
@@ -98,6 +99,16 @@
9899
<artifactId>spring-boot-starter-web</artifactId>
99100
<scope>test</scope>
100101
</dependency>
102+
<dependency>
103+
<groupId>org.springframework.boot</groupId>
104+
<artifactId>spring-boot-webmvc-test</artifactId>
105+
<scope>test</scope>
106+
</dependency>
107+
<dependency>
108+
<groupId>org.springframework.boot</groupId>
109+
<artifactId>spring-boot-starter-liquibase</artifactId>
110+
<scope>test</scope>
111+
</dependency>
101112

102113
<!-- Database -->
103114
<dependency>
@@ -117,22 +128,6 @@
117128
<artifactId>testcontainers</artifactId>
118129
<version>2.0.2</version>
119130
<scope>test</scope>
120-
<exclusions>
121-
<exclusion>
122-
<groupId>org.hamcrest</groupId>
123-
<artifactId>hamcrest-core</artifactId>
124-
</exclusion>
125-
<exclusion>
126-
<groupId>org.hamcrest</groupId>
127-
<artifactId>hamcrest-library</artifactId>
128-
</exclusion>
129-
<exclusion>
130-
<!-- see: https://github.com/testcontainers/testcontainers-java/issues/970#issuecomment-625044008 -->
131-
<!-- can be removed once testcontainers drop their dependency to junit4 -->
132-
<groupId>junit</groupId>
133-
<artifactId>junit</artifactId>
134-
</exclusion>
135-
</exclusions>
136131
</dependency>
137132
<dependency>
138133
<groupId>org.testcontainers</groupId>
@@ -195,12 +190,12 @@
195190
<dependency>
196191
<groupId>com.puppycrawl.tools</groupId>
197192
<artifactId>checkstyle</artifactId>
198-
<version>11.1.0</version>
193+
<version>12.3.0</version>
199194
</dependency>
200195
<dependency>
201196
<groupId>it.aboutbits</groupId>
202197
<artifactId>java-checkstyle-config</artifactId>
203-
<version>1.0.1</version>
198+
<version>1.1.0</version>
204199
</dependency>
205200
</dependencies>
206201
</plugin>

src/main/java/it/aboutbits/springboot/toolbox/autoconfiguration/web/CustomTypeConfiguration.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
import it.aboutbits.springboot.toolbox.type.identity.EntityId;
88
import it.aboutbits.springboot.toolbox.web.CustomTypePropertyEditor;
99
import it.aboutbits.springboot.toolbox.web.EntityIdPropertyEditor;
10-
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
10+
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
1111
import org.springframework.context.annotation.Bean;
1212
import org.springframework.context.annotation.Configuration;
1313
import org.springframework.web.bind.WebDataBinder;
1414
import org.springframework.web.bind.annotation.ControllerAdvice;
1515
import org.springframework.web.bind.annotation.InitBinder;
16+
import tools.jackson.databind.module.SimpleModule;
1617

1718
import java.util.Set;
1819

@@ -37,19 +38,23 @@ public void initBinder(WebDataBinder binder) {
3738
}
3839

3940
@Bean
40-
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer(CustomTypeScanner configuration) {
41-
var types = configuration.getRelevantTypes();
41+
public JsonMapperBuilderCustomizer jsonCustomizer(CustomTypeScanner configuration) {
42+
var module = new SimpleModule();
4243

43-
var deserializers = types.stream()
44-
.map(CustomTypeDeserializer::new)
45-
.toList()
46-
.toArray(new CustomTypeDeserializer[types.size()]);
44+
// serializers
45+
module.addSerializer(new CustomTypeSerializer());
4746

47+
// dynamic deserializers
48+
configuration.getRelevantTypes()
49+
.forEach(type ->
50+
module.addDeserializer(type, new CustomTypeDeserializer(type))
51+
);
52+
53+
// type-based deserializer
54+
module.addDeserializer(EntityId.class, new EntityIdDeserializer());
4855

4956
return builder -> builder
50-
.serializers(new CustomTypeSerializer())
51-
.deserializers(deserializers)
52-
.deserializerByType(EntityId.class, new EntityIdDeserializer());
57+
.addModule(module);
5358
}
5459

5560
}

src/main/java/it/aboutbits/springboot/toolbox/jackson/CustomTypeDeserializer.java

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package it.aboutbits.springboot.toolbox.jackson;
22

3-
import com.fasterxml.jackson.core.JsonParser;
4-
import com.fasterxml.jackson.databind.DeserializationContext;
5-
import com.fasterxml.jackson.databind.JsonDeserializer;
63
import it.aboutbits.springboot.toolbox.reflection.util.CustomTypeReflectionUtil;
74
import it.aboutbits.springboot.toolbox.type.CustomType;
85
import it.aboutbits.springboot.toolbox.type.ScaledBigDecimal;
6+
import tools.jackson.core.JacksonException;
7+
import tools.jackson.core.JsonParser;
8+
import tools.jackson.core.TokenStreamLocation;
9+
import tools.jackson.core.exc.InputCoercionException;
10+
import tools.jackson.databind.DeserializationContext;
11+
import tools.jackson.databind.ValueDeserializer;
912

10-
import java.io.IOException;
13+
import java.io.Closeable;
1114
import java.lang.reflect.Constructor;
1215
import java.lang.reflect.InvocationTargetException;
1316
import java.math.BigDecimal;
1417
import java.math.BigInteger;
1518
import java.util.UUID;
1619
import java.util.function.Function;
1720

18-
public class CustomTypeDeserializer<T extends CustomType<?>> extends JsonDeserializer<T> {
21+
public class CustomTypeDeserializer<T extends CustomType<?>> extends ValueDeserializer<T> {
1922
private final Class<T> customType;
2023
private final Constructor<T> constructor;
2124
private final Function<JsonParser, Object> typeConverter;
@@ -43,7 +46,7 @@ public Class<T> handledType() {
4346
}
4447

4548
@Override
46-
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
49+
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
4750
var value = typeConverter.apply(jsonParser);
4851

4952
try {
@@ -52,7 +55,46 @@ public T deserialize(JsonParser jsonParser, DeserializationContext deserializati
5255
IllegalAccessException
5356
| InvocationTargetException
5457
| InstantiationException e) {
55-
throw new IOException(e);
58+
throw new Ex(e);
59+
}
60+
}
61+
62+
public static class Ex extends JacksonException {
63+
64+
protected Ex(String msg) {
65+
super(msg);
66+
}
67+
68+
protected Ex(Throwable rootCause) {
69+
super(rootCause);
70+
}
71+
72+
protected Ex(String msg, Throwable rootCause) {
73+
super(msg, rootCause);
74+
}
75+
76+
protected Ex(String msg, TokenStreamLocation loc, Throwable rootCause) {
77+
super(msg, loc, rootCause);
78+
}
79+
80+
protected Ex(Closeable processor, Throwable rootCause) {
81+
super(processor, rootCause);
82+
}
83+
84+
protected Ex(Closeable processor, String msg, TokenStreamLocation loc, Throwable rootCause) {
85+
super(processor, msg, loc, rootCause);
86+
}
87+
88+
protected Ex(Closeable processor, String msg) {
89+
super(processor, msg);
90+
}
91+
92+
protected Ex(Closeable processor, String msg, Throwable problem) {
93+
super(processor, msg, problem);
94+
}
95+
96+
protected Ex(Closeable processor, String msg, TokenStreamLocation loc) {
97+
super(processor, msg, loc);
5698
}
5799
}
58100

@@ -106,7 +148,7 @@ private static Function<JsonParser, Object> getByteConverter() {
106148
return jsonParser -> {
107149
try {
108150
return jsonParser.getByteValue();
109-
} catch (IOException e) {
151+
} catch (InputCoercionException e) {
110152
throw new CustomTypeDeserializerException("Failed to read value as Byte.", e);
111153
}
112154
};
@@ -116,7 +158,7 @@ private static Function<JsonParser, Object> getBooleanConverter() {
116158
return jsonParser -> {
117159
try {
118160
return jsonParser.getBooleanValue();
119-
} catch (IOException e) {
161+
} catch (InputCoercionException e) {
120162
throw new CustomTypeDeserializerException("Failed to read value as Boolean.", e);
121163
}
122164
};
@@ -126,7 +168,7 @@ private static Function<JsonParser, Object> getScaledBigDecimalConverter() {
126168
return jsonParser -> {
127169
try {
128170
return new ScaledBigDecimal(jsonParser.getDecimalValue());
129-
} catch (IOException e) {
171+
} catch (InputCoercionException e) {
130172
throw new CustomTypeDeserializerException("Failed to read value as ScaledBigDecimal.", e);
131173
}
132174
};
@@ -136,7 +178,7 @@ private static Function<JsonParser, Object> getBigDecimalConverter() {
136178
return jsonParser -> {
137179
try {
138180
return jsonParser.getDecimalValue();
139-
} catch (IOException e) {
181+
} catch (InputCoercionException e) {
140182
throw new CustomTypeDeserializerException("Failed to read value as BigDecimal.", e);
141183
}
142184
};
@@ -146,7 +188,7 @@ private static Function<JsonParser, Object> getDoubleConverter() {
146188
return jsonParser -> {
147189
try {
148190
return jsonParser.getDoubleValue();
149-
} catch (IOException e) {
191+
} catch (InputCoercionException e) {
150192
throw new CustomTypeDeserializerException("Failed to read value as Double.", e);
151193
}
152194
};
@@ -156,7 +198,7 @@ private static Function<JsonParser, Object> getFloatConverter() {
156198
return jsonParser -> {
157199
try {
158200
return jsonParser.getFloatValue();
159-
} catch (IOException e) {
201+
} catch (InputCoercionException e) {
160202
throw new CustomTypeDeserializerException("Failed to read value as Float.", e);
161203
}
162204
};
@@ -166,7 +208,7 @@ private static Function<JsonParser, Object> getBigIntegerConverter() {
166208
return jsonParser -> {
167209
try {
168210
return jsonParser.getBigIntegerValue();
169-
} catch (IOException e) {
211+
} catch (InputCoercionException e) {
170212
throw new CustomTypeDeserializerException("Failed to read value as BigInteger.", e);
171213
}
172214
};
@@ -176,7 +218,7 @@ private static Function<JsonParser, Object> getLongConverter() {
176218
return jsonParser -> {
177219
try {
178220
return jsonParser.getLongValue();
179-
} catch (IOException e) {
221+
} catch (InputCoercionException e) {
180222
throw new CustomTypeDeserializerException("Failed to read value as Long.", e);
181223
}
182224
};
@@ -186,7 +228,7 @@ private static Function<JsonParser, Object> getIntegerConverter() {
186228
return jsonParser -> {
187229
try {
188230
return jsonParser.getIntValue();
189-
} catch (IOException e) {
231+
} catch (InputCoercionException e) {
190232
throw new CustomTypeDeserializerException("Failed to read value as Integer.", e);
191233
}
192234
};
@@ -196,7 +238,7 @@ private static Function<JsonParser, Object> getShortConverter() {
196238
return jsonParser -> {
197239
try {
198240
return jsonParser.getShortValue();
199-
} catch (IOException e) {
241+
} catch (InputCoercionException e) {
200242
throw new CustomTypeDeserializerException("Failed to read value as Short.", e);
201243
}
202244
};
@@ -206,7 +248,7 @@ private static Function<JsonParser, Object> getStringConverter() {
206248
return jsonParser -> {
207249
try {
208250
return jsonParser.getValueAsString();
209-
} catch (IOException e) {
251+
} catch (InputCoercionException e) {
210252
throw new CustomTypeDeserializerException("Failed to read value as String.", e);
211253
}
212254
};
@@ -217,10 +259,15 @@ private static Function<JsonParser, Object> getCharConverter() {
217259
try {
218260
var value = jsonParser.getValueAsString();
219261
if (value == null || value.length() != 1) {
220-
throw new IOException();
262+
throw new InputCoercionException(
263+
jsonParser,
264+
"Not a Char.",
265+
jsonParser.currentToken(),
266+
String.class
267+
);
221268
}
222269
return value.charAt(0);
223-
} catch (IOException e) {
270+
} catch (InputCoercionException e) {
224271
throw new CustomTypeDeserializerException("Failed to read value as Char.", e);
225272
}
226273
};
@@ -231,10 +278,15 @@ private static Function<JsonParser, Object> getUUIDConverter() {
231278
try {
232279
var value = jsonParser.getValueAsString();
233280
if (value == null || value.length() != 36) {
234-
throw new IOException();
281+
throw new InputCoercionException(
282+
jsonParser,
283+
"Not a UUID.",
284+
jsonParser.currentToken(),
285+
String.class
286+
);
235287
}
236288
return UUID.fromString(value);
237-
} catch (IOException e) {
289+
} catch (InputCoercionException e) {
238290
throw new CustomTypeDeserializerException("Failed to read value as UUID.", e);
239291
}
240292
};
@@ -255,7 +307,7 @@ private static Function<JsonParser, Object> getEnumConverter(Class<?> wrappedTyp
255307
"Failed to read value as Enum: " + enumClass.getName(),
256308
e
257309
);
258-
} catch (IOException e) {
310+
} catch (InputCoercionException e) {
259311
throw new CustomTypeDeserializerException("Failed to read value as Enum.", e);
260312
}
261313
};

0 commit comments

Comments
 (0)