当JAXBElement值为null时,将带JAXB注释的PoJo转换为Json时,排除null属性

时间:2019-10-09 19:04:49

标签: java json jackson jaxb

我正在使用Jackson来为Json写一个Jaxb注释的Pojo。输入是一个XML文档,我将其读入Pojo,然后将其写为Json。 它一直都很棒,并且对于大型文档(使用Streaming SAX解析器)也很有效。

当XML具有

时,我遇到了一个问题

<ns1:SomeElement xsi:nil="true"/>

表示此属性的JAXBElement正确解组到具有以下内容的对象

value = null
nil = true

将Pojo写给Json时,我要求在JSON中没有"someElement": null。如果输出Json完全排除“ someElement”,我绝对可以。

致Json:

  1. 我正在使用mixin编写JAXBElement的值
  2. 将objectMapper设置为排除null(但这不起作用)

    objectMapperForXml = new ObjectMapper();
    objectMapperForXml.addMixIn(JAXBElement.class, JAXBElementMixin.class);
    objectMapperForXml.setVisibility(objectMapperForXml.getSerializationConfig()
            .getDefaultVisibilityChecker()
            .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
            .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
            .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
            .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
    objectMapperForXml.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
    /* I've tried NON_NULL, NON_EMTY as well */
    JsonNode document = objectMapperForXml.valueToTree(item.getTransformedDocument());
    
    /* a mixin annotation that overrides the handling for the JAXBElement */
    public interface JAXBElementMixin {
        @JsonValue
        Object getValue();
    }
    

尽管如此,我的输出json包含:"someElement":null

我想念什么?

考虑到JAXBElement封装的属性从技术上讲,是否在考虑NOT_NULL处理是否存在问题!= null?如果是这样,还有另一种排除空值的方法吗?

(我要探讨的另一个角度是弄清楚如何生成Json模式,该模式验证上面生成的json,同时又不会由于null而无法使用...基本上需要

"anyOf": [
      {"type": "string"},
      {"type": "null"}
    ]

但是,再次,我们无法通过以下方式哄骗以下代码来生成json模式

public static void main(final String[] arguments)
{
    final JsonGenerationFromJaxbClasses instance = new JsonGenerationFromJaxbClasses();
    final SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
    final ObjectMapper mapper = instance.createJaxbObjectMapper();
    mapper.addMixIn(JAXBElement.class, JAXBElementMixin.class);

    mapper.setVisibility(mapper.getSerializationConfig()
            .getDefaultVisibilityChecker()
            .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
            .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
            .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
            .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
    try {
        for (SchemaMapping mapping : SchemaMapping.values()) {
            mapper.acceptJsonFormatVisitor(mapper.constructType(Class.forName(mapping.fullyQualifiedClassName)), visitor);
            final com.fasterxml.jackson.module.jsonSchema.JsonSchema jsonSchema = visitor.finalSchema();
            BufferedWriter writer = new BufferedWriter(new FileWriter(mapping.name() + ".schema"));
            writer.write(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));
            writer.flush();
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * Create instance of ObjectMapper with JAXB introspector
 * and default type factory.
 *
 * @return Instance of ObjectMapper with JAXB introspector
 *    and default type factory.
 */
private ObjectMapper createJaxbObjectMapper()
{
    final ObjectMapper mapper = new ObjectMapper();
    final TypeFactory typeFactory = TypeFactory.defaultInstance();
    final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(typeFactory);
    // make deserializer use JAXB annotations (only)
    mapper.getDeserializationConfig().with(introspector);
    return mapper;
}

/**
 * Write out JSON Schema based upon Java source code in
 * class whose fully qualified package and class name have
 * been provided.
 *
 * @param fullyQualifiedClassName Name of Java class upon
 *    which JSON Schema will be extracted.
 */

private void writeToStandardOutputWithModuleJsonSchema(
        final String fullyQualifiedClassName)
{
    final SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
    final ObjectMapper mapper = new ObjectMapper();
    try
    {
        mapper.acceptJsonFormatVisitor(mapper.constructType(Class.forName(fullyQualifiedClassName)), visitor);
        final com.fasterxml.jackson.module.jsonSchema.JsonSchema jsonSchema = visitor.finalSchema();
        out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));
    }
    catch (Exception cnfEx) {
        cnfEx.printStackTrace();
    }
}

0 个答案:

没有答案