Quiero añadir un envoltorio que nombró se determina en tiempo de ejecución, ya que depende del nombre de la clase (que podría utilizar @JsonRootName pero yo no quiero porque me gustaría tener que usarlo en cada subclase, que no es eficiente) .
Supongo que debería utilizar @JsonSerialize
para anular el serializador predeterminado, pero quiero que se acaba de crear la envoltura; No quiero serializar los campos del objeto mismo (también yo estoy en una clase abstracta, por lo que no sé ni por los campos de la clase sub!). No me importa acerca de ellos, sólo importa el envoltorio! Así que me gustaría que el serializador predeterminado para manejar esos campos para mí, o algo por el estilo.
@JsonSerialize(using = CustomSerializer.class)
public abstract class Request {
public static class CustomSerializer extends JsonSerializer<Request > {
@Override
public void serialize(Request request, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// Doing my stuff to determine the wrapper name based on request.class.getSimpleName()
// Then what should I wright to serialize the fields?
// Basically I just want a function to generate the same json that the default serializer would generate!
// I tried the following, but obviously it gives a com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion
jgen.writeObject(value);
// Same error for the function below
provider.defaultSerializeValue(value, jgen);
}
}
Para crear serializador envoltorio que necesita para su uso com.fasterxml.jackson.databind.ser.BeanSerializerModifier
clase. Puede registrarlo usando com.fasterxml.jackson.databind.module.SimpleModule
. A continuación ejemplo muestra de extremo a extremo solución de cómo hacerlo:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.databind.util.NameTransformer;
import java.io.IOException;
import java.util.UUID;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
SimpleModule wrappersModule = new SimpleModule("requestWrapper");
wrappersModule.setSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if (Request.class.isAssignableFrom(beanDesc.getBeanClass())) {
return new RequestWrapperJsonSerializer(serializer);
}
return serializer;
}
});
ObjectMapper mapper = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.addModule(wrappersModule)
.build();
System.out.println(mapper.writeValueAsString(new Request1(1, "POST")));
System.out.println(mapper.writeValueAsString(new Request2(2, UUID.randomUUID())));
}
}
class RequestWrapperJsonSerializer extends JsonSerializer<Request> {
private final JsonSerializer baseSerializer;
public RequestWrapperJsonSerializer(JsonSerializer baseSerializer) {
this.baseSerializer = baseSerializer;
}
@Override
public void serialize(Request value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
gen.writeFieldName(value.getClass().getSimpleName() + "Wrapper");
gen.writeStartObject();
baseSerializer.unwrappingSerializer(NameTransformer.NOP).serialize(value, gen, serializers);
gen.writeEndObject();
gen.writeEndObject();
}
}
abstract class Request {
private int id;
//constructor, getters, setters, toString
}
class Request1 extends Request {
private String body;
//constructor, getters, setters, toString
}
class Request2 extends Request {
private UUID uuid;
//constructor, getters, setters, toString
}
imprime el código de seguridad:
{
"Request1Wrapper" : {
"id" : 1,
"body" : "POST"
}
}
{
"Request2Wrapper" : {
"id" : 2,
"uuid" : "dd4cccb5-1cf5-4dd4-8bc7-97cb101e5d7d"
}
}
En lugar unwrappingSerializer
método que puede utilizar serialize
el método de embalaje y retire las invocaciones adicionales.