Utilisation de @JsonComponent dans Spring Boot
1. Vue d'ensemble
Cet article rapide est axé sur l'utilisation de l'annotation@JsonComponent dans Spring Boot.
L'annotation nous permet d'exposer une classe annotée en tant que sérialiseur et / ou désérialiseur Jackson sans avoir besoin de l'ajouter manuellement auxObjectMapper.
Cela fait partie du module principal Spring Boot, de sorte qu'aucune dépendance supplémentaire n'est requise dans une application Spring Boot standard.
2. La sérialisation
Commençons par l'objetUser suivant contenant une couleur préférée:
public class User {
private Color favoriteColor;
// standard getters/constructors
}
Si nous sérialisons cet objet en utilisant Jackson avec les paramètres par défaut, nous obtenons:
{ "favoriteColor": { "red": 0.9411764740943909, "green": 0.9725490212440491, "blue": 1.0, "opacity": 1.0, "opaque": true, "hue": 208.00000000000003, "saturation": 0.05882352590560913, "brightness": 1.0 } }
Nous pouvons rendre le JSON beaucoup plus condensé et lisible en imprimant simplement les valeurs RGB, par exemple, à utiliser en CSS.
Dans cette mesure, il suffit de créer une classe qui implémenteJsonSerializer:
@JsonComponent
public class UserJsonSerializer extends JsonSerializer {
@Override
public void serialize(User user, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException,
JsonProcessingException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(
"favoriteColor",
getColorAsWebColor(user.getFavoriteColor()));
jsonGenerator.writeEndObject();
}
private static String getColorAsWebColor(Color color) {
int r = (int) Math.round(color.getRed() * 255.0);
int g = (int) Math.round(color.getGreen() * 255.0);
int b = (int) Math.round(color.getBlue() * 255.0);
return String.format("#%02x%02x%02x", r, g, b);
}
}
Avec ce sérialiseur, le JSON résultant a été réduit à:
{"favoriteColor":"#f0f8ff"}
En raison de l'annotation@JsonComponent, le sérialiseur est enregistré dans les JacksonObjectMapper de l'application Spring Boot. Nous pouvons tester cela avec le test JUnit suivant:
@JsonTest
@RunWith(SpringRunner.class)
public class UserJsonSerializerTest {
@Autowired
private ObjectMapper objectMapper;
@Test
public void testSerialization() throws JsonProcessingException {
User user = new User(Color.ALICEBLUE);
String json = objectMapper.writeValueAsString(user);
assertEquals("{\"favoriteColor\":\"#f0f8ff\"}", json);
}
}
3. Désérialisation
En continuant avec le même exemple, nous pouvons écrire un désérialiseur qui transformera la couleur WebString en un objet JavaFX Color:
@JsonComponent
public class UserJsonDeserializer extends JsonDeserializer {
@Override
public User deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException,
JsonProcessingException {
TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
TextNode favoriteColor
= (TextNode) treeNode.get("favoriteColor");
return new User(Color.web(favoriteColor.asText()));
}
}
Testons le nouveau désérialiseur et assurez-vous que tout fonctionne comme prévu:
@JsonTest
@RunWith(SpringRunner.class)
public class UserJsonDeserializerTest {
@Autowired
private ObjectMapper objectMapper;
@Test
public void testDeserialize() throws IOException {
String json = "{\"favoriteColor\":\"#f0f8ff\"}"
User user = objectMapper.readValue(json, User.class);
assertEquals(Color.ALICEBLUE, user.getFavoriteColor());
}
}
4. Serializer etDeserializer dans une classe
Lorsque vous le souhaitez, nous pouvons connecter le sérialiseur et le désérialiseur dans une classe en utilisant deux classes internes et en ajoutant les@JsonComponent sur la classe englobante:
@JsonComponent
public class UserCombinedSerializer {
public static class UserJsonSerializer
extends JsonSerializer {
@Override
public void serialize(User user, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException,
JsonProcessingException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(
"favoriteColor", getColorAsWebColor(user.getFavoriteColor()));
jsonGenerator.writeEndObject();
}
private static String getColorAsWebColor(Color color) {
int r = (int) Math.round(color.getRed() * 255.0);
int g = (int) Math.round(color.getGreen() * 255.0);
int b = (int) Math.round(color.getBlue() * 255.0);
return String.format("#%02x%02x%02x", r, g, b);
}
}
public static class UserJsonDeserializer
extends JsonDeserializer {
@Override
public User deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
TextNode favoriteColor = (TextNode) treeNode.get(
"favoriteColor");
return new User(Color.web(favoriteColor.asText()));
}
}
}
5. Conclusion
Ce tutoriel rapide a montré comment ajouter rapidement un sérialiseur / désérialiseur Jackson dans une application Spring Boot en tirant parti de l'analyse des composants avec l'annotation@JsonComponent.
Les extraits de code peuvent être trouvésover on GitHub.