Может создать пользовательскую строку json с экземпляром класса данных в java

Существует класс, определенный следующим образом:

@Data // lombok
public class MyData {
    @Required // my custom annotation
    String testValue1;
    Integer testValue2;
}

И myData создается следующим образом:

MyData myData = new MyData();
myData.setTestValue1("test1");
myData.setTestValue2(123);

Я хочу сериализовать myData как строку json следующим образом:

{
    "testValue1": {
        "type": "String",
        "isRequired": "true",
        "value": "test1"
    },
    "testValue2": {
        "type": "Integer",
        "isRequired": "false",
        "value": "123"
    },
}

Есть ли хороший способ создать строку json?

редактировать|

Я помещаю кавычки в строку json, чтобы она была действительной.

Я хочу установить ключ как имя поля и создать дополнительную информацию о поле. установить тип поля на клавишу "type" и если поле имеет аннотацию @Required, установите true на «isRequired» и установить значение экземпляра поля на «значение».

Это недопустимый JSON. Я полагаю, вы имеете в виду использовать кавычки для type и value?

shmosel 14.02.2023 07:39

@shmosel Да, ты прав. я редактирую свой вопрос

miniar 14.02.2023 07:56

Я не знаю, найдете ли вы какое-либо готовое решение для такого конкретного случая использования, но довольно просто прочитать тип поля и аннотации с отражением и составить JSON самостоятельно.

shmosel 14.02.2023 08:03

@shmosel Я попробую с вашим мнением. Спасибо

miniar 14.02.2023 08:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, я немного поиграл с сериализацией Джексона и пришел к такому результату (конечно, незаконченному и не полностью протестированному, но работает с вашим данным объектом).:

Модуль для информирования Spring/Jackson о новом Serializer.

@JsonComponent
public class TestSerializerModule extends SimpleModule {

    @Override
    public String getModuleName() {
        return TestSerializerModule.class.getSimpleName();
    }

    @Override
    public Version version() {
        return new Version(
                1,
                0,
                0,
                "",
                TestSerializerModule.class.getPackage().getName(),
                "TestModule"
        );
    }

    @Override
    public void setupModule(SetupContext context) {
        context.addBeanSerializerModifier(new BeanSerializerModifier() {

            @Override
            public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {

                if (beanDesc.getBeanClass().equals(MyData.class)) { //Add some smart logic here to identify your objects
                    return new TestSerializer();
                }

                return serializer;
            }
        });
    }
}

Затем сам Serialisier:

public class TestSerializer extends StdSerializer<Object> {

    protected TestSerializer() {
        super(Object.class);
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        ClassIntrospector classIntrospector = provider.getConfig().getClassIntrospector();
        BasicBeanDescription beanDescription = (BasicBeanDescription) classIntrospector.forSerialization(provider.getConfig(), provider.constructType(value.getClass()), null);


        // Start of the MyValue Object
        gen.writeStartObject();
        beanDescription.findProperties().forEach(p -> {

                    // Requiered if Annoation is present
                    boolean required = p.getField().hasAnnotation(Required.class);

                    try {

                        // Write all the wanted fields
                        gen.writeFieldName(p.getName());
                        gen.writeStartObject();
                        gen.writeBooleanField("isRequired", required);
                        gen.writeStringField("type", p.getField().getRawType().getSimpleName());
                        gen.writeFieldName("value");

                        Object value1 = p.getGetter().getValue(value);
                        
                        // Use existing serializer for the value    provider.findValueSerializer(value1.getClass()).serialize(value1, gen, provider);
                        gen.writeEndObject();

                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }

        );
        gen.writeEndObject();


    }
}

Запуск этого теста:

@JsonTest
class TestSerializerTest {


    @Autowired
    ObjectMapper objectMapper;

    @Test
    public void testSerializer() throws Exception {


        MyData value = new MyData();
        value.setTestValue1("test1");
        value.setTestValue2(123);

        String s = objectMapper.writeValueAsString(value);

        System.out.println(s);

    }


}

дает мне этот вывод:

{"testValue1":{"isRequired":false,"type":"String","value":"test1"},"testValue2":{"isRequired":false,"type":"Integer","value":123}}

Надеюсь, это даст вам представление о том, с чего начать и как двигаться дальше!

спасибо за Ваш ответ. Я еще не мог решить проблему с ошибкой модуляции установки, но я думаю, что этот ответ решит мою проблему достаточно. Позвольте мне попросить вас еще об одной услуге, не могли бы вы предоставить мне URL-адрес справочных документов об этом?

miniar 14.02.2023 09:40

Некоторую простую информацию о пользовательской сериализации с помощью Jackson можно найти здесь: baeldung.com/jackson-custom-serialization

berse2212 14.02.2023 09:56

Другие вопросы по теме