JAXB, Moxy Unmarshal JSON HTTP-параметры с объектом - PullRequest
0 голосов
/ 26 сентября 2018

Это похоже на мой пост здесь ...

JAXB Unmarshal JSON HTTP POST Параметры

За исключением этого случая мне нужно демонтировать JSON, который не толькосодержит параметры HTTP POST, но также и объект.Рассмотрим следующий JSON ...

{
  "client": "1",
  "forTopic": "topic",
  "MyObject":{
    "name":"the name",
    "id":1
  }
}

client и forTopic - это параметры HTTP POST.MyObject - это объект, который я пытаюсь получить, чтобы действовать.Я хотел бы получить параметры отдельно от объекта.

Я могу сделать это, настроив объект, который содержит 3 поля.Поле 1 является строкой для клиента.Поле 2 - это int для id.Поле 3 является MyObject theObject.

Это позволяет мне все нормально тянуть.Однако я бы предпочел не создавать класс-оболочку для каждого из моих объектов, у которого есть параметры.Есть ли лучший / правильный способ сделать это?Либо путем извлечения параметров из JSON и оставления результирующего JSON MyObject для последующего демаршалирования, либо для определения глубины, которую нужно копать в JSON для демаршалирования?Параметры достаточно согласованы для каждого из моих объектов.Я просто не хочу создавать оболочки для них всех.

Возможно, еще один способ спросить, каков правильный подход для обработки параметров HTTP POST, содержащихся в вашем JSON, с использованием JAXB / Moxy?

Редактировать:

Для справки.Вот мои соответствующие зависимости.

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.moxy</artifactId>
        <version>2.7.2</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>

И мои jaxb.properties ...

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

1 Ответ

0 голосов
/ 27 сентября 2018

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

Сначала давайте создадим pojo для MyObject, который использует jaxb:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MyObject {
    @XmlElement(name = "id")
    private String id_blah;

    @XmlElement(name = "name")
    private String Name;

    public String getId_blah() {
        return id_blah;
    }

    public void setId_blah(String id_blah) {
        this.id_blah = id_blah;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }
}

Мы создадим собственный десериализатор для обработки входящихПолезная нагрузка:

public class MyObjectDeserializer extends StdDeserializer<MyObject> {


        public MyObjectDeserializer() {
            this(null);
        }

        public MyObjectDeserializer(Class<?> vc) {
            super(vc);
        }

        @Override
        public MyObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {

            JsonNode jsonPayload = jp.getCodec().readTree(jp);
            JsonNode myObjectNode = jsonPayload.get("MyObject");
            MyObject myObject = new MyObject();
            myObject.setId_blah(myObjectNode.get("id").textValue());
            myObject.setName(myObjectNode.get("name").textValue());
            return myObject;
        }
    }

Мы зарегистрируем наш десериализатор в конвертерах сообщений:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);

        ObjectMapper objectMapper = new ObjectMapper();
        MappingJackson2HttpMessageConverter jaxMsgConverter = new MappingJackson2HttpMessageConverter();
        AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
        objectMapper.setAnnotationIntrospector(introspector);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        SimpleModule module = new SimpleModule();
        module.addDeserializer(MyObject.class, new MyObjectDeserializer());
        objectMapper.registerModule(module);
        jaxMsgConverter.setObjectMapper(objectMapper);
        converters.add(jaxMsgConverter);
    }
}

И конечную точку, чтобы проверить, что все работает нормально:

@RestController
public class Controller {

    @PostMapping("/test")
    public String test(@RequestBody MyObject myObject) {
        return myObject.getName();
    }
}

Отправкаjson в вашем вопросе работает нормально.

Зависимости для моего примера проекта:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.11</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jaxb-annotations</artifactId>
            <version>2.9.6</version>
        </dependency>
    </dependencies>
...