📜  在 Spring Boot 的 REST API 实现中使用 Jackson 的 JSON

📅  最后修改于: 2022-05-13 01:54:41.783000             🧑  作者: Mango

在 Spring Boot 的 REST API 实现中使用 Jackson 的 JSON

每当我们使用 Spring (Spring Boot) 实现 REST API 时,我们都会遇到在 API 的 JSON 响应中排除 NULL 的要求。此外,可能需要外部化打开/关闭此功能:在 JSON 响应中排除 NULLS ,从而允许 API 的使用者根据需要进行自定义。

在本文中,我们总结了使用Jackson 实现上述功能的 ON/OFF 外部化的方法 - 一个基于 Java 的库,用于将Java对象序列化或映射到 JSON,反之亦然。

不成功的方法:

最初,我们尝试使用 Spring Boot 的现成方法,但并不成功,例如:

  • application.properties中有spring.jackson.default-property-inclusion属性。此属性采用以下值: always / non_null / non_absent / non_default / non_empty
  • 扩展WebMvcConfigurationSupport类并自定义 Spring Boot 配置,见下文。
Java
@Configuration
class WebMvcConfiguration extends WebMvcConfiguration{
    @Override
    protected void extendsMessageConverters
      (List> converters)
    {
        for(HttpMessageConverter converter: converters)
        {
            if(converter instnceof MappingJackson2HttpMessageConverter)
            {
                ObjectMapper mapper = 
                  ((MappingJackson2HttpMessageConverter)converter)
                  .getObjectMapper();
                mapper.setSerializationInclusion(Include.NON_NULL);
                }
            }
        }


Java
@Bean
Public Jackson2ObjectMapperBuilderCustomizer customJackson(){
    return new Jackson2ObjectMapperBuilderCustomizer(){
    @Override
    public void customize(Jackson2ObjectMapperBuilder builder){
        builder.serializationInclusion(Include.NON_NULL);
        builder.failonUnknownProperties(false);
        }
    };
}


Java
public class RegistrationResponse{
  
    @JsonProperty("success")
    private Boolean success = null;
      
    @JsonProperty("message")
    private String message = null;
      
    @JsonProperty("data")
    private String data = null;
      
    @JsonProperty("error_code")
    private Integer errorCode = null;
      
    public RegistrationResponse success(Boolean success){
        this.success = success;
        return this;
        }
          
        @NotNull
        public Boolean isSuccess(){
            return success;
            }
        public void setSuccess(Boolean success){
            this.success = success;
        }
          
        public RegistrationResponse message(String message){
            this.message = message;
            return this;
            }
              
        @NotNull
        public String getMessage(){
            return message;
        }
          
        public void setMessage(String message){
            this.message = message;
        }


Java
RegistrationResponse regResp = new RegistrationResponse();
  
regResp.setSuccess(true);
regResp.setErrorCode(null);
regResp.setData("testdata");
regResp.setMessage("success");
  
ObjectMapper mapper = new ObjectMapper()
mapper.enable(SerializationFeature.INDENT_OUTPUT);
  
if(toExcludeNull) mapper.setSerializationInclusion(Include.NON_NULL);
else mapper.serializationInclusion(Include.ALWAYS);
  
String regRespStr = null;
try{
  
    regRespStr = mapper.writeValueAsString(regResp);
    }
    catch(JsonProcessingException e)
        e.printStackTrace();
        }
    System.out.println("Formatted JSON Response:" + regRespStr);


现在,创建org.springframework.http.converter.json.Jackson2ObjectMapperBuilderCustomizer的实例,下面给出的代码供您参考。

Java

@Bean
Public Jackson2ObjectMapperBuilderCustomizer customJackson(){
    return new Jackson2ObjectMapperBuilderCustomizer(){
    @Override
    public void customize(Jackson2ObjectMapperBuilder builder){
        builder.serializationInclusion(Include.NON_NULL);
        builder.failonUnknownProperties(false);
        }
    };
}

成功的方法:

如果未创建,则创建 JSON 响应对象。这是在序列化为 JSON 时您希望基于application.properties中的属性“排除/包含空字段”功能的对象。您可以在 Response 对象下方看到供您参考。

Java

public class RegistrationResponse{
  
    @JsonProperty("success")
    private Boolean success = null;
      
    @JsonProperty("message")
    private String message = null;
      
    @JsonProperty("data")
    private String data = null;
      
    @JsonProperty("error_code")
    private Integer errorCode = null;
      
    public RegistrationResponse success(Boolean success){
        this.success = success;
        return this;
        }
          
        @NotNull
        public Boolean isSuccess(){
            return success;
            }
        public void setSuccess(Boolean success){
            this.success = success;
        }
          
        public RegistrationResponse message(String message){
            this.message = message;
            return this;
            }
              
        @NotNull
        public String getMessage(){
            return message;
        }
          
        public void setMessage(String message){
            this.message = message;
        }

创建名为“ config.response.json.format.exclude_null ”的属性,其值可以为“ true ”或“ false ”。值 ' true ' 表示排除 JSON 响应中的空字段,值 ' false ' 表示不排除空字段。另外,将此属性绑定到类级别的属性,以便可以读取该值,下面给出的代码供您参考。

config.response.json.format.exclude_null = false
@Value("${config.response.json.format.exclude_null}")
private boolean toExcludeNull;

通过创建com.fasterxml.jackson.databind.ObjectMapper的实例,实现基于全局属性值排除空值的实际逻辑。

  • 如果全局属性值为 true,则将创建的映射器的SerializationInclusion属性设置为Include.NON_NULL ,否则设置为Include.ALWAYS
  • 使用映射器将响应对象序列化为字符串并返回字符串。确保处理 JsonProcessingException

下面让我们看看在构建 JSON 响应作为 API 实现的一部分时要添加的实际代码片段。

Java

RegistrationResponse regResp = new RegistrationResponse();
  
regResp.setSuccess(true);
regResp.setErrorCode(null);
regResp.setData("testdata");
regResp.setMessage("success");
  
ObjectMapper mapper = new ObjectMapper()
mapper.enable(SerializationFeature.INDENT_OUTPUT);
  
if(toExcludeNull) mapper.setSerializationInclusion(Include.NON_NULL);
else mapper.serializationInclusion(Include.ALWAYS);
  
String regRespStr = null;
try{
  
    regRespStr = mapper.writeValueAsString(regResp);
    }
    catch(JsonProcessingException e)
        e.printStackTrace();
        }
    System.out.println("Formatted JSON Response:" + regRespStr);

这里, regRespStr是应用了 NULL 排除/包含的 JSON 字符串。

您还可以查看 Github 存储库。