I'd like to write a rest service that accepts and produces XML or JSON based on the information from headers. To do so, I followed one of tutorials. The problem is that when I try to read fields of dto in Spring controller, they are all set to null.
For test purposes, I send in body a DTO and in controller I return it concatenating string Changed
to two of its fields.
In body I send:
<?xml version="1.0" encoding="UTF-8"?>
<name>name</name>
<description>description</description>
However, I receive:
<Dto name="null Changed" description="null Changed"/>
I send request by Postman:
Here's my configuration:
Controller
@RestController
public class Controller {
@RequestMapping(value = "/endpoint", method = RequestMethod.POST,
consumes = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE},
produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE})
public Dto getAndReturnEntity(@RequestBody Dto dto) {
dto.setName(dto.getName() + " Changed");
dto.setDescription(dto.getDescription() + " Changed");
return dto;
}
}
DTO
@JacksonXmlRootElement
public class Dto {
@JacksonXmlProperty(isAttribute = true) // I also tried without it
private String name;
@JacksonXmlProperty(isAttribute = true)
private String description;
// getters and setters ommited for brevity
}
Configuration for Spring
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
favorParameter(false).
parameterName("mediaType").
ignoreAcceptHeader(false).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
}
Relevant part of pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
The input XML should be like this:
<Dto>
<name>abcd</name>
<description>desc</description>
</Dto>
In case you want the tag names be different than you can use either custom object mapper or add @JsonProperty.