I really don't understand why my @RequestBody is null, when I try to send the XML defined .
Here the XML that I try to push
<File>
<FileDate>2020-12-25</FileDate>
<RecordCount>2</RecordCount>
<transactionMTDs>
<transactionMTD>
<RecordID>45</RecordID>
</transactionMTD>
</transactionMTDs>
</File>
My entity File
package com.entities;
import javax.xml.bind.annotation.*;
import java.io.Serializable;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"fileDate",
"recordCount",
"transactions"
})
@XmlRootElement(name = "File")
public class File {
@XmlElement(name = "FileDate", required = true)
protected String fileDate;
@XmlElement(name = "RecordCount", required = true)
protected String recordCount;
@XmlElementWrapper(name="transactionMTDs")
@XmlElements({
@XmlElement(name="transactionMTD", type=Transaction.class),
})
protected List<Transaction> transactions;
public String getFileDate() {
return fileDate;
}
public void setFileDate(String fileDate) {
this.fileDate = fileDate;
}
public String getRecordCount() {
return recordCount;
}
public void setRecordCount(String recordCount) {
this.recordCount = recordCount;
}
public List<Transaction> getTransaction() {
return transactions;
}
public void setTransaction(List<Transaction> transaction) {
this.transactions = transaction;
}
}
My entity Transaction
package com.entities;
import javax.xml.bind.annotation.*;
import java.io.Serializable;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"recordID"
})
@XmlRootElement(name = "transactionMTD")
public class Transaction {
@XmlElement(name = "RecordID", required = true)
protected String recordID;
// setter and getter
public String getRecordID() {
return recordID;
}
public void setRecordID(String recordID) {
this.recordID = recordID;
}
}
My Controller
package com.controller;
import com.entities.File;
import com.mq.AMQPConfig;
import com.mq.RabbitMQProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.xml.bind.JAXB;
import java.io.StringWriter;
/*
example to be tested and worked
<File>
<FileDate>2020-12-25</FileDate>
<RecordCount>2</RecordCount>
<transactionMTDs>
<transactionMTD>
<RecordID>45</RecordID>
</transactionMTD>
</transactionMTDs>
</File>
*/
@ComponentScan({"org.springframework.amqp.rabbit","com.mq","com.entities"})
@RestController
public class FileController {
@Autowired
private AMQPConfig amqpconfig;
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
RabbitMQProperties rabbitMQProperties;
@RequestMapping(method = RequestMethod.POST, consumes = {MediaType.APPLICATION_XML_VALUE})
public void parseXML(@RequestBody File file) {
}
@PostMapping("/save-file")
public void pushXML(@RequestBody File file) {
System.out.println(file.getFileDate());
rabbitTemplate.convertAndSend(rabbitMQProperties.getExchange(), rabbitMQProperties.getRoutingKey(), file);
}
@GetMapping("/trest")
public void trest() {
System.out.println("ok");
rabbitTemplate.convertAndSend(rabbitMQProperties.getExchange(), rabbitMQProperties.getRoutingKey(),"test");
}
}
And my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<jackson.version>2.12.5</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<!--<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>-->
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.13.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I suppose it's related to the exclude but I am not too sure ...
Many thanks for your help
Nicolas
CodePudding user response:
So having the xml:
<file>
<fileDate>2020-12-25</fileDate>
<recordCount>2</recordCount>
<transactions>
<transaction>
<recordId>45</recordId>
</transaction>
</transactions>
</file>
And the following objects:
package com.entities;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"fileDate",
"recordCount",
"transactions"
})
@XmlRootElement(name = "file")
public class File {
@XmlElement(name = "fileDate", required = true)
protected String fileDate;
@XmlElement(name = "recordCount", required = true)
protected String recordCount;
@XmlElementWrapper(name="transactions")
@XmlElement(name="transaction")
protected List<Transaction> transactions;
public String getFileDate() {
return fileDate;
}
public void setFileDate(String fileDate) {
this.fileDate = fileDate;
}
public String getRecordCount() {
return recordCount;
}
public void setRecordCount(String recordCount) {
this.recordCount = recordCount;
}
public List<Transaction> getTransactions() {
return transactions;
}
public void setTransactions(List<Transaction> transactions) {
this.transactions = transactions;
}
}
package com.entities;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"recordId"
})
@XmlRootElement(name = "transaction")
public class Transaction {
@XmlElement(name = "recordId", required = true)
protected String recordId;
public String getRecordId() {
return recordId;
}
public void setRecordId(String recordId) {
this.recordId = recordId;
}
}
The xml is deserialized using your controller.