JAXB,带有对象的Moxy取消编组JSON HTTP参数

时间:2018-09-26 16:46:21

标签: java json http jaxb moxy

这类似于我在这里的帖子...

JAXB Unmarshal JSON HTTP POST Parameters

除了在这种情况下,我需要解组我的JSON,它不仅包含HTTP POST参数而且还包含一个对象。考虑以下JSON ...

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

client和forTopic是HTTP POST参数。 MyObject是我要接收以对其执行操作的对象。我想将参数与对象分开。

我可以通过设置一个包含3个字段的对象来做到这一点。字段1是客户端的字符串。字段2是ID的整数。字段3是MyObject theObject。

这可以使我一切正常。但是,我希望不必为每个具有参数的对象创建一个“包装器”类。有没有更好/合适的方法来做到这一点?通过将参数从JSON中拉出并留给MyObject生成的JSON然后进行解组,还是以某种方式指定深度以深入探究要解组的JSON?这些参数对于我的每个对象都相当一致。我只是不想为它们全部创建包装器。

也许这是另一种询问方式,那就是使用JAXB / Moxy处理JSON中包含的HTTP POST参数的正确方法是什么?

编辑:

供参考。这是我相关的依赖项。

    <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 :(得分:2)

我个人会使用包装对象,但是有多种方法可以执行您想要的操作。我创建了一个小型的Spring Boot应用程序来检查您的情况。

首先让我们为MyObject创建一个使用jaxb的pojo:

@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>