这类似于我在这里的帖子...
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
答案 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>