【问题标题】:Spring Boot Preprocess JSON dataSpring Boot 预处理 JSON 数据
【发布时间】:2017-08-17 11:46:30
【问题描述】:

我有一个 RESTful Spring Boot API,它有一个注册端点。

在我的@RestController 类中,我编写了一个简单的字符串值预处理器,用null 值修剪和替换只有空格的字符串。

  @InitBinder
  public void blankStringBinder(WebDataBinder dataBinder) {
    dataBinder.setDisallowedFields("password", "confirmPassword");
    StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true);
    dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
  }

但是,当我从 Postman 以原始 JSON 提交数据时,没有进行修剪编辑。我在blankStringBinder 方法中放置了一个断点,我看到它在每个传入请求中都会被调用。

WebDataBinder 似乎适用于 form-data。有没有办法让它也适用于原始 JSON 数据?

【问题讨论】:

    标签: java json spring spring-boot serialization


    【解决方案1】:

    如果您只想对少数String 字段执行此操作,请先创建一个自定义JsonDeserializer

    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.fasterxml.jackson.databind.JsonNode;
    
    public class EmptyToNullCustomDeserializer extends JsonDeserializer<String> {
        @Override
        public String deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
            JsonNode node = jp.readValueAsTree();
            if (node.textValue().isEmpty()) {
                return null;
            }
            return node.textValue();
        }
    }
    

    然后在POJO的每个String上添加这个注解:@JsonDeserialize(using = EmptyToNullCustomDeserializer.class)。 例如:

    @JsonDeserialize(using = EmptyToNullCustomDeserializer.class)
    private String content;
    

    编辑:

    如果您有很多 String 字段要进行预处理,那么对每个字段进行注释可能会非常麻烦。

    作为替代方案,您可以对 all String 字段进行预处理,而无需对其进行注释。为此,您必须首先修改EmptyToNullCustomDeserializer,使其父类为Jacksons StdDeserializer

    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
    import java.io.IOException;
    import org.springframework.stereotype.Component;
    
    @Component
    public class EmptyToNullCustomDeserializer extends StdDeserializer<String> {
        protected EmptyToNullCustomDeserializer() {
            super(String.class);
        }
    
        @Override
        public String deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
            JsonNode node = jp.readValueAsTree();
            if (node.textValue().isEmpty()) {
                return null;
            }
            return node.textValue();
        }
    }
    

    然后通过将上述反序列化器添加到配置中来创建此组件以自定义 Jackson 对象映射器:

    import java.util.List;
    import lombok.AllArgsConstructor;
    import lombok.NonNull;
    import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Primary;
    import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
    import org.springframework.stereotype.Component;
    
    @Component
    public class JacksonConfiguration {
    
        @Autowired
        private EmptyToNullCustomDeserializer emptyToNullCustomDeserializer;
    
        @Primary
        @Bean
        public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
            Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
            for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
                customizer.customize(builder);
            }
            return builder;
        }
    
        @Bean
        public Jackson2ObjectMapperBuilderCustomizer addEmptyToNullStringDeserialization() {
            return new Jackson2ObjectMapperBuilderCustomizer() {
                @Override
                public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
                    jacksonObjectMapperBuilder.deserializerByType(String.class, emptyToNullCustomDeserializer);
                }
    
            };
        }
    }
    

    【讨论】:

      【解决方案2】:

      excellent answer from @sébastien-temprado 的小扩展:如果您需要“将空白字符串修剪为 null”(如问题所提)而不是“将空字符串修剪为 null”,请使用例如Apache Commons Lang StringUtils:

      import org.apache.commons.lang3.StringUtils;
      
      //[...]
      @Override
      public String deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
          JsonNode node = jp.readValueAsTree();
          
          return StringUtils.trimToNull(node.textValue());
      }
      //[...]
      

      【讨论】:

        猜你喜欢
        • 2021-11-04
        • 1970-01-01
        • 1970-01-01
        • 2019-02-14
        • 1970-01-01
        • 2017-04-06
        • 2019-09-24
        • 2023-03-28
        • 1970-01-01
        相关资源
        最近更新 更多