【问题标题】:Jackson: add suffix according to a field typeJackson:根据字段类型添加后缀
【发布时间】:2021-03-02 16:56:19
【问题描述】:

这里是我的POJO

public class AutorDenormalized {

    private String id;
    private Long unitatId;
    private String grupId;
    private String descripcio;

    public AutorDenormalized() {

    }

    // getters $ setters

}

我想序列化这种对象,根据字段类型添加后缀。我的意思是,

  • 如果字段类型是字符串 -> 则添加*_s 后缀
  • 如果字段类型是 Long -> 则添加 *_l 后缀
  • 否则继续前进

你有什么解决办法吗?

【问题讨论】:

    标签: java serialization jackson jackson2 jackson-modules


    【解决方案1】:

    您需要实现自定义BeanPropertyWriter,它可以生成带有后缀的属性名称。要注册自定义BeanPropertyWriter,您需要创建自定义BeanSerializerModifier

    下面的例子展示了简化的实现,展示了如何实现上述结果:

    import com.fasterxml.jackson.databind.BeanDescription;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationConfig;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
    import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
    import com.fasterxml.jackson.databind.util.NameTransformer;
    
    import java.io.IOException;
    import java.util.List;
    
    public class JsonTypeInfoApp {
    
        public static void main(String[] args) throws IOException {
            SimpleModule typeSuffixModule = new SimpleModule();
            typeSuffixModule.setSerializerModifier(new TypeSuffixBeanSerializerModifier());
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            mapper.registerModule(typeSuffixModule);
    
            System.out.println(mapper.writeValueAsString(new AutorDenormalized()));
        }
    }
    
    class TypeSuffixBeanSerializerModifier extends BeanSerializerModifier {
    
        @Override
        public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
            for (int i = 0; i < beanProperties.size(); ++i) {
                final BeanPropertyWriter writer = beanProperties.get(i);
                Class<?> rawType = writer.getType().getRawClass();
                if (supports(rawType)) {
                    final String suffix = constructSuffix(rawType);
    
                    beanProperties.set(i, writer.rename(NameTransformer.simpleTransformer(null, suffix)));
                }
            }
            return beanProperties;
        }
    
        private String constructSuffix(Class<?> rawType) {
            return "_" + Character.toLowerCase(rawType.getSimpleName().charAt(0));
        }
    
        private boolean supports(Class<?> rawClass) {
            return rawClass == String.class || rawClass == Long.class;
        }
    }
    

    上面的代码打印:

    {
      "id_s" : "1",
      "unitatId_l" : 123,
      "grupId_s" : "2",
      "descripcio_s" : "3"
    }
    

    另见:

    【讨论】:

    • 这行得通,虽然可能没有必要创建自定义BeanPropertyWriters——类型已经在“changeProperties()”中可用,所以可以在那里检查适用性,如果有匹配,调用“ BeanPropertyWriter.rename(NameTransformer())" ?
    • @StaxMan,好点子,+1。我使用您的建议改进了我的答案。谢谢!
    【解决方案2】:

    除了可以正常工作的公认答案之外,您还可以考虑实现PropertyNameStrategy:它可以让您重命名属性并获取字段、setter/getter、creator 参数(您需要查找属性类型)。可能会少一些工作。

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 2018-11-10
      • 1970-01-01
      • 2020-12-14
      • 2021-09-07
      • 1970-01-01
      • 2020-11-07
      • 1970-01-01
      • 2013-12-23
      相关资源
      最近更新 更多