如何向 Jackson 全局添加自定义序列化器并默认使用

Hen*_*ung 6 java spring jackson spring-boot

假设我想默认Boolean序列化为.Number

我知道我可以逐个领域地做到

@JsonFormat(shape = Shape.NUMBER)
private Boolean success;
Run Code Online (Sandbox Code Playgroud)

但是我可以“注册”我的自定义序列化器,以便当我从 API 返回对象时,Boolean类中的 s 将被序列化到Numberjson 响应中。

我有以下序列化器

public class MyBooleanSerializer extends JsonSerializer<Boolean> {
    @Override
    public void serialize(
                    Boolean value, 
                    JsonGenerator gen, 
                    SerializerProvider serializers) throws IOException {

        gen.writeString(value ? "1" : "0");

    }
}
Run Code Online (Sandbox Code Playgroud)

我有以下课程

@Data
public class MyResponse {
    private Boolean success;
    private String message;
}
Run Code Online (Sandbox Code Playgroud)

它将像这样使用

@GetMapping("/hello")
public MyResponse hello() {
    Boolean success = true;
    String message = "Hi there";
    return new MyResponse(success, message);
}
Run Code Online (Sandbox Code Playgroud)

当我使用GET这个 API 时,我期待这个响应

{
  success: 1,
  message: "Hi there"
}
Run Code Online (Sandbox Code Playgroud)

我期待注入一些 Bean。我努力了

@Bean
@Primary
ObjectMapper objectMapper() {
    SimpleModule module = new SimpleModule();
    module.addSerializer(new MyBooleanSerializer());
    return new ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .registerModule(module);
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用。

我已阅读jsonMapper教程,似乎每次我想要序列化对象时都需要创建。我想要的只是每当我MyResponse从 API 返回时,Booleans 都会被序列化为Numbers。

Pan*_*kos 4

不需要全局序列化器

,只是为了@JsonFormat(shape = Shape.NUMBER)在全局范围内强制布尔字段的注释。

您可以覆盖适用于布尔字段的全局规则以使用您的自定义规则,Shape.NUMBER这样您就不必在每个类的每个布尔字段中执行此操作。

因此,不必serialization/deserialization在每个类的每个字段中都有 for

@JsonFormat(shape = Shape.NUMBER)
private Boolean success;
Run Code Online (Sandbox Code Playgroud)

您可以在全局范围内使用以下代码来完成此操作:

@Bean
public ObjectMapper registerObjectMapper(){
   ObjectMapper mapper = new ObjectMapper();            
   mapper.configOverride(Boolean.class)
         .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.NUMBER));
   mapper.configOverride(boolean.class)
         .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.NUMBER));
   return mapper;
 }
Run Code Online (Sandbox Code Playgroud)

如果有必要,如何应用全局序列化器

但是,如果您坚持注册全局序列化器,以便该格式仅用于序列化而不是反序列化,那么您可以这样做:

@Bean
public ObjectMapper registerObjectMapper(){
    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule("MyBooleanSerializer");
    module.addSerializer(Boolean.class, new MyBooleanSerializer());
    module.addSerializer(boolean.class, new MyBooleanSerializer());
    mapper.registerModule(module);
   
    return mapper;
}
Run Code Online (Sandbox Code Playgroud)

public class MyBooleanSerializer extends JsonSerializer<Boolean> {
    @Override
    public void serialize(
                    Boolean value, 
                    JsonGenerator gen, 
                    SerializerProvider serializers) throws IOException {

        gen.writeString(value ? "1" : "0");

    }
}
Run Code Online (Sandbox Code Playgroud)

有一个问题

仔细看看第二个解决方案

module.addSerializer(Boolean.class, new MyBooleanSerializer());
module.addSerializer(boolean.class, new MyBooleanSerializer());
Run Code Online (Sandbox Code Playgroud)

在第一个解决方案中

  .configOverride(Boolean.class)
  .configOverride(boolean.class)
Run Code Online (Sandbox Code Playgroud)

对于Jackson原语booleanas 字段和 WrapperBoolean类需要单独注册才能工作。