【问题标题】:JAXB, Moxy Unmarshal JSON HTTP Parameters with ObjectJAXB,Moxy Unmarshal JSON HTTP 参数与对象
【发布时间】:2018-09-26 16:46:20
【问题描述】:

这和我的帖子很相似……

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 的 int。字段 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

【问题讨论】:

  • .JAXB 用于解组 XML,而不是用于解组 JSON
  • @ThomasFritsch JAXB 可以使用我在帖子中提到的 Moxy 等附加技术来解组 JSON。请在我的原始帖子中查看我的链接或查看这里...stackoverflow.com/questions/38789307/…

标签: java json http jaxb moxy


【解决方案1】:

就我个人而言,我会使用包装对象,但有一些方法可以做你想做的事。我创建了一个小型 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>

【讨论】:

  • 哇!非常详细和简洁。这次真是万分感谢。我的一个问题是没有杰克逊可以做到这一点吗?我还没有深入研究杰克逊,看起来我应该进一步简化我的 REST API 吗?我将进一步深入研究 Moxy,看看我是否可以添加这些转换器而不必走杰克逊路线。看起来非常类似于 xstream 与注册自定义转换器的工作方式。
  • 嗨@Etep。老实说,我对 Moxy 并不熟悉。如果可能,我会检查并回复您
猜你喜欢
  • 1970-01-01
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多