代码之家  ›  专栏  ›  技术社区  ›  Jordi

Jackson:根据字段类型添加后缀

  •  0
  • Jordi  · 技术社区  · 5 年前

    这里我的 POJO :

    public class AutorDenormalized {
    
        private String id;
        private Long unitatId;
        private String grupId;
        private String descripcio;
    
        public AutorDenormalized() {
    
        }
    
        // getters $ setters
    
    }
    

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

    • 如果字段类型为字符串->然后添加a *_s 后缀
    • 如果字段类型为长->然后添加a *_l 后缀
    • 否则,继续前进

    你有什么解决办法吗?

    0 回复  |  直到 5 年前
        1
  •  2
  •   Michał Ziober    5 年前

    您需要实现自定义 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"
    }
    

    另请参见:

        2
  •  1
  •   StaxMan    5 年前

    除了公认的答案外,您还可以考虑实施 PropertyNameStrategy :它将允许您重命名属性并获取字段、setter/getter、creator参数(您需要找到属性的类型)。工作可能少一点。