您可以编写自定义序列化程序:
public class UnwrappingSerializer extends JsonSerializer<Object>
{
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException
{
JavaType type = TypeFactory.type(value.getClass());
getBeanSerializer(type, provider).serialize(value, new UnwrappingJsonGenerator(jgen), provider);
}
private synchronized JsonSerializer<Object> getBeanSerializer(JavaType type, SerializerProvider provider)
{
JsonSerializer<Object> result = cache.get(type);
if (result == null) {
BasicBeanDescription beanDesc = provider.getConfig().introspect(type);
result = BeanSerializerFactory.instance.findBeanSerializer(type, provider.getConfig(), beanDesc);
cache.put(type, result);
}
return result;
}
private Map<JavaType, JsonSerializer<Object>> cache = new HashMap<JavaType, JsonSerializer<Object>>();
private static class UnwrappingJsonGenerator extends JsonGeneratorDelegate
{
UnwrappingJsonGenerator(JsonGenerator d)
{
super(d);
}
@Override
public void writeEndObject() throws IOException, JsonGenerationException
{
if (depth-- >= yieldDepth) {
super.writeEndObject();
}
}
@Override
public void writeFieldName(SerializedString name) throws IOException, JsonGenerationException
{
if (depth >= yieldDepth) {
super.writeFieldName(name);
}
}
@Override
public void writeFieldName(String name) throws IOException, JsonGenerationException
{
if (depth >= yieldDepth) {
super.writeFieldName(name);
}
}
@Override
public void writeStartObject() throws IOException, JsonGenerationException
{
if (++depth >= yieldDepth) {
super.writeStartObject();
}
}
private int depth;
private final int yieldDepth = 2;
}
}
它将忽略深度低于指定深度的外部对象(默认为 2)。
然后按如下方式使用它:
public class UnwrappingSerializerTest
{
public static class BaseT1
{
public List<String> getTest()
{
return test;
}
public void setTest(List<String> test)
{
this.test = test;
}
private List<String> test;
}
@JsonSerialize(using = UnwrappingSerializer.class)
public static class T1 extends BaseT1
{
}
@JsonSerialize(using = UnwrappingSerializer.class)
public static class T2
{
public BaseT1 getT1()
{
return t1;
}
public void setT1(BaseT1 t1)
{
this.t1 = t1;
}
private BaseT1 t1;
}
@Test
public void test() throws IOException
{
ObjectMapper om = new ObjectMapper();
T1 t1 = new T1();
t1.setTest(Arrays.asList("foo", "bar"));
assertEquals("[\"foo\",\"bar\"]", om.writeValueAsString(t1));
BaseT1 baseT1 = new BaseT1();
baseT1.setTest(Arrays.asList("foo", "bar"));
T2 t2 = new T2();
t2.setT1(baseT1);
assertEquals("{\"test\":[\"foo\",\"bar\"]}", om.writeValueAsString(t2));
}
}
笔记:
- 它只需要单个字段包装器,并且会在类似的东西上生成无效的 JSON
{{field1: {...}, field2: {...}}
- 如果您使用自定义
SerializerFactory
,您可能需要将其传递给序列化程序。
- 它使用单独的序列化程序缓存,因此这也可能是一个问题。