I am working on Springboot REST API. My application should consume and produce both XML and JSON. I came across the Jackson json Xml dependency.
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.5.4</version>
</dependency>
I added this in my pom.xml. Now I am able to accept xml input but the values are null when mapped to Java Object. The following is my Resource class.
@Configuration
@ImportResource("/application-context.xml")
@EnableAutoConfiguration
@ResponseBody
@RequestMapping("/match")
public class MatchResource {
private static final Logger logger = LogManager.getLogger(MatchResource.class);
@Autowired
private MatchService matchService;
@RequestMapping(method = RequestMethod.POST)
@Consumes({MediaType.TEXT_XML,MediaType.APPLICATION_JSON})
@Produces({MediaType.TEXT_XML,MediaType.APPLICATION_JSON})
//@Produces( MediaType.APPLICATION_XML)
public Response matchRequest(@RequestBody MatchRequest matchRequest,
@Context HttpServletRequest headers) throws Exception {
Response resp = null;
MiniMatchResponse output = null;
// Headers are store in the "headers" object. To retrieve a specific header, please take a look at the below statement
String apiUser = headers.getHeader("Api-User");
UUID randID = UUID.randomUUID();
logger.info("Get Match for with ID: " + randID);
// Get service profile from headers via MatchConstants.SERVICE_PROFILE_HEADER
String serviceProfile = "";
try {
//TODO: MatchService should return MatchResponse Object
//Json OutPut
output = matchService.findResponse(matchRequest, serviceProfile);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
logger.debug("Match Request: " + matchRequest.toString());
} catch (ErrorException e) {
logger.error(e.getMessage(), e);
}
// Form Response
resp = Response.status(200).entity(output).build();
return resp;
}
The below is my Request Object
package com.infoconnect.api.dto.Match;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class MatchRequest implements Serializable {
// Gets or sets the RequestType of request this represents.
// Allowed values are "Company", "People" and "Any".
private String requestType;
private String name;
private String companyName;
private String streetAddress;
private String streetAddress2;
private String city;
private String stateProvince;
private String postalCode;
private String country;
private String serviceProfile;
private String resourceType;
private int limit;
private Integer confidence;
private String phone;
private Boolean includeHistorical;
private Boolean includeNonVerified;
private String requestId;
private List<String> fields;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getStreetAddress() {
return streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public String getStreetAddress2() {
return streetAddress2;
}
public void setStreetAddress2(String streetAddress2) {
this.streetAddress2 = streetAddress2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStateProvince() {
return stateProvince;
}
public void setStateProvince(String stateProvince) {
this.stateProvince = stateProvince;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getServiceProfile() {
return serviceProfile;
}
public void setServiceProfile(String serviceProfile) {
this.serviceProfile = serviceProfile;
}
public String getResourceType() {
return resourceType;
}
public void setResourceType(String resourceType) {
this.resourceType = resourceType;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public Integer getConfidence() {
return confidence;
}
public void setConfidence(Integer confidence) {
this.confidence = confidence;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Boolean getIncludeHistorical() {
return includeHistorical;
}
public void setIncludeHistorical(Boolean includeHistorical) {
this.includeHistorical = includeHistorical;
}
public Boolean getIncludeNonVerified() {
return includeNonVerified;
}
public void setIncludeNonVerified(Boolean includeNonVerified) {
this.includeNonVerified = includeNonVerified;
}
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
public List<String> getFields() {
return fields;
}
public void setFields(List<String> fields) {
this.fields = fields;
}
@Override
public String toString() {
return "MatchRequest{" +
"requestType='" + requestType + '\'' +
", name='" + name + '\'' +
", companyName='" + companyName + '\'' +
", streetAddress='" + streetAddress + '\'' +
", streetAddress2='" + streetAddress2 + '\'' +
", city='" + city + '\'' +
", stateProvince='" + stateProvince + '\'' +
", postalCode='" + postalCode + '\'' +
", country='" + country + '\'' +
", serviceProfile='" + serviceProfile + '\'' +
", resourceType='" + resourceType + '\'' +
", limit=" + limit +
", confidence=" + confidence +
", phone='" + phone + '\'' +
", includeHistorical=" + includeHistorical +
", includeNonVerified=" + includeNonVerified +
", requestId='" + requestId + '\'' +
", fields=" + fields +
'}';
}
}
JSON request and Response works fine. Can you please help me how to Include XML request and Response in my application.
Try to add a
@XmlRootElement(name="myRootTag")
JAXB annotation with the tag you use as the root tag to the classMatchRequest
. I have had similar issues when using both XML and JSON as transport format in a REST request, but using moxy instead of Jackson. In any case, proper JAXB annotations are necessary to convert to/from XML (XML is much pickier in this respect than JSON).Jackson XML is supposed to support JAXB annotations, and if this does not work, it has an own set of similar annotations that are incompatible to JAXB (see https://github.com/FasterXML/jackson-dataformat-xml and https://github.com/FasterXML/jackson-dataformat-xml/wiki/Jackson-XML-annotations)