1

I am creating REST API using spring framework. My entity is based on one table and REST API is supposed to be invoked using POST operation with below JSON structure. Can someone explain me how to map the entity class so that it can consume below-shown json. Since my entity is based on only one table, I am not able to understand how can it create nested json objects for same table properties.

{
    "process_ar_receipt": {
        "message_header": {
            "source_system_guid": "DDED-DBCD-REV-E1F4343DB3434",
            "source_system": "MeSo_TravelAds"
        },
        "receipt_header": {
            "customer_number": "123",
            "source_receipt_number": "TESTRCPT_1523",
            }
        }
}
Anuj Marwaha
  • 53
  • 1
  • 1
  • 7
  • 1
    Why not use DTOs and just map the required fields to your entity classes in code? Alternative is to create a custom deserialiser. It’s not possible with just annotations and a flat domain object structure. – Strelok Oct 23 '18 at 15:52
  • I am new to Spring framework. Are you saying that I should take the whole JSON object in REST controller and manually read all the JSON fields and set them into the Entity pojo. – Anuj Marwaha Oct 23 '18 at 16:07
  • look at the jackson library. It will allow you to convert an incoming json file to a POJO, then you can do as you wish with that pojo to hibernate entity – locus2k Oct 23 '18 at 17:38

2 Answers2

0

you could use Gson to convert the json to a DTO

https://jarroba.com/gson-json-java-ejemplos/

Oscar Mera
  • 64
  • 1
  • 7
0

pseudo code assuming your Entity class as

@Entity(name="foo") 
class Data{
    @Id
    private String source_system_guid;
    @Column
    private String source_system;
    @Column
    private String customer_number;
    @Column
    private String source_receipt_number;

    public Data() {}
    public Data(String ssId, String sourceSystm, String custNum, String srcRcptNum) {
        this.source_system_guid = ssId;
        this.source_system = sourceSystm;
        this.customer_number = custNum;
        this.source_receipt_number = srcRcptNum;
    }
    public String getSource_system_guid() {
        return source_system_guid;
    }
    public void setSource_system_guid(String source_system_guid) {
        this.source_system_guid = source_system_guid;
    }
    public String getSource_system() {
        return source_system;
    }
    public void setSource_system(String source_system) {
        this.source_system = source_system;
    }
    public String getCustomer_number() {
        return customer_number;
    }
    public void setCustomer_number(String customer_number) {
        this.customer_number = customer_number;
    }
    public String getSource_receipt_number() {
        return source_receipt_number;
    }
    public void setSource_receipt_number(String source_receipt_number) {
        this.source_receipt_number = source_receipt_number;
    }
}

Now since your DTO/BO i.e. Data Transfer Object or Business Object is different from the actual entity we will create the required BO object as below

class DataTO{
    @JsonProperty("process_ar_receipt")
    private ReceiptTO receiptTO=new ReceiptTO();       
    public ReceiptTO getReceiptTO() {
        return receiptTO;
    }
    public void setReceiptTO(ReceiptTO receiptTO) {
        this.receiptTO = receiptTO;
    }
}
class ReceiptTO{
    @JsonProperty("message_header")
    private MessageHeader messageHeder = new MessageHeader();
    @JsonProperty("receipt_header")
    private ReceiptHeader receiptHeder = new ReceiptHeader();

    public MessageHeader getMessageHeder() {
        return messageHeder;
    }
    public void setMessageHeder(MessageHeader messageHeder) {
        this.messageHeder = messageHeder;
    }
    public ReceiptHeader getReceiptHeder() {
        return receiptHeder;
    }
    public void setReceiptHeder(ReceiptHeader receiptHeder) {
        this.receiptHeder = receiptHeder;
    }  
}
class MessageHeader{
    @JsonProperty("source_System_Guid")
    private String sourceSystemId;
    @JsonProperty("system_Id")
    private String systemId;

    public String getSourceSystemId() {
        return sourceSystemId;
    }
    public void setSourceSystemId(String sourceSystemId) {
        this.sourceSystemId = sourceSystemId;
    }
    public String getSystemId() {
        return systemId;
    }
    public void setSystemId(String systemId) {
        this.systemId = systemId;
    }
}
class ReceiptHeader{
    @JsonProperty("customer_number")
    private String customerNumber;
    @JsonProperty("source_rcpt_number")
    private String sourceReceiptNumber;

    public String getCustomerNumber() {
        return customerNumber;
    }
    public void setCustomerNumber(String customerNumber) {
        this.customerNumber = customerNumber;
    }
    public String getSourceReceiptNumber() {
        return sourceReceiptNumber;
    }
    public void setSourceReceiptNumber(String sourceReceiptNumber) {
        this.sourceReceiptNumber = sourceReceiptNumber;
    }
}

The @JsonProperty annotation is imported from org.codehaus.jackson.annotate.JsonProperty; i.e from jackson jar

Now a Simple Test class to demo DTO/BO back and forth Entity conversion

public class Test{
    public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
        List<Data> datas = new ArrayList<Data>();
        datas.add(new Data("DDED-DBCD-REV-E1F4343DB3434","MeSo_TravelAds","123","TESTRCPT_1523"));
        datas.add(new Data("ADED-EWQD-REV-E1F4343YG3434","FooSo_MusicAds","132","TESTRCPT_1523"));
        datas.add(new Data("YDED-YUTR-REV-E1F43UIDB3434","BarSo_HealthAds","143","TESTRCPT_1523"));

        List<DataTO> dataTOs = new ArrayList<DataTO>();
        for (Data data : datas) {
            DataTO dataTO = new DataTO();
            dataTO.getReceiptTO().getMessageHeder().setSourceSystemId(data.getSource_system_guid());
            dataTO.getReceiptTO().getMessageHeder().setSystemId(data.getSource_system());
            dataTO.getReceiptTO().getReceiptHeder().setCustomerNumber(data.getCustomer_number());
            dataTO.getReceiptTO().getReceiptHeder().setSourceReceiptNumber(data.getSource_receipt_number());
            dataTOs.add(dataTO);
        }
        ObjectMapper mapper = new ObjectMapper();
        String str = mapper.writeValueAsString(dataTOs);
        System.out.println(str);

    }
}

This will give you below result

[  
   {  
      "process_ar_receipt":{  
         "message_header":{  
            "source_System_Guid":"DDED-DBCD-REV-E1F4343DB3434",
            "system_Id":"MeSo_TravelAds"
         },
         "receipt_header":{  
            "customer_number":"123",
            "source_rcpt_number":"TESTRCPT_1523"
         }
      }
   },
   {  
      "process_ar_receipt":{  
         "message_header":{  
            "source_System_Guid":"ADED-EWQD-REV-E1F4343YG3434",
            "system_Id":"FooSo_MusicAds"
         },
         "receipt_header":{  
            "customer_number":"132",
            "source_rcpt_number":"TESTRCPT_1523"
         }
      }
   },
   {  
      "process_ar_receipt":{  
         "message_header":{  
            "source_System_Guid":"YDED-YUTR-REV-E1F43UIDB3434",
            "system_Id":"BarSo_HealthAds"
         },
         "receipt_header":{  
            "customer_number":"143",
            "source_rcpt_number":"TESTRCPT_1523"
         }
      }
   }
]

similarly the other conversion

    String input = "{  \r\n" + 
                    "      \"process_ar_receipt\":{  \r\n" + 
                    "         \"message_header\":{  \r\n" + 
                    "            \"source_System_Guid\":\"ADED-EWQD-REV-E1F4343YG3434\",\r\n" + 
                    "            \"system_Id\":\"FooSo_MusicAds\"\r\n" + 
                    "         },\r\n" + 
                    "         \"receipt_header\":{  \r\n" + 
                    "            \"customer_number\":\"132\",\r\n" + 
                    "            \"source_rcpt_number\":\"TESTRCPT_1523\"\r\n" + 
                    "         }\r\n" + 
                    "      }\r\n" + 
                    "   }";
            DataTO dataTO = mapper.readValue(input, DataTO.class);
            System.out.println(dataTO.getReceiptTO().getMessageHeder().getSourceSystemId());
            System.out.println(dataTO.getReceiptTO().getMessageHeder().getSystemId());
            System.out.println(dataTO.getReceiptTO().getReceiptHeder().getCustomerNumber());
System.out.println(dataTO.getReceiptTO().getReceiptHeder().getSourceReceiptNumber());

this will print

ADED-EWQD-REV-E1F4343YG3434
FooSo_MusicAds
132

TESTRCPT_1523

You dont have to use the mapper code you can directly add the jackson converter as HttpMessageConverted which will convert the JSON to java object automatically

@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {

 ... other configurations

@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        builder.serializationInclusion(Include.NON_EMPTY);
        builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
    }
}
Amit Kumar Lal
  • 5,537
  • 3
  • 19
  • 37
  • @Anuj let me know in case you need more clarification on the topic I can share more details by looking into your Entity class – Amit Kumar Lal Oct 24 '18 at 05:52