Исключить нулевые свойства при преобразовании аннотированного JAXB PoJo в Json, когда значение JAXBElement равно нулю - PullRequest
0 голосов
/ 09 октября 2019

Я использую Джексона, чтобы написать Jaxb с аннотацией Pojo Json. Входные данные представляют собой XML-документ, который я читаю в Pojo, а затем записываю как Json. Он прекрасно работал, а также был эффективен для больших документов (с использованием анализатора Streaming SAX).

Я столкнулся с проблемой, когда XML имеет

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

Элемент JAXBElement, представляющий это свойство, правильно демарширует объект с

value = null
nil = true

При записи моего Pojo в Json у меня есть требование НЕ ИМЕТЬ "someElement": null в JSON. Я абсолютно в порядке, если вывод Json полностью исключает "someElement".

Запись в Json:

  1. Я использую миксин для записи значенияJAXBElement
  2. Установка objectMapper для исключения нуля (но это не работает)

    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

Чего мне не хватает?

Интересно, есть ли проблема с обработкой NOT_NULL, учитывая, что инкапсулированное свойство JAXBElement технически! = Null? Если так, есть ли другой способ исключить нули?

(Другой угол, который я хочу исследовать, - это выяснить, как сгенерировать схему Json, которая проверяет сгенерированный выше json, в то же время не исключая из-за нуля. ..В основном, он должен иметь

"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();
    }
}
...