【问题标题】:Spring Rest -> Hibernate entity to JSONSpring Rest -> Hibernate 实体到 JSON
【发布时间】:2019-03-27 22:15:48
【问题描述】:

我正在使用 spring 框架创建 REST API。我的实体基于一张表,REST API 应该使用具有以下 JSON 结构的 POST 操作来调用。有人可以解释一下如何映射实体类,以便它可以使用下面显示的 json。 由于我的实体仅基于一个表,我无法理解它如何为相同的表属性创建嵌套的 json 对象。

{
    "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",
            }
        }
}

【问题讨论】:

  • 为什么不使用 DTO 并将所需字段映射到代码中的实体类?另一种方法是创建自定义反序列化器。仅使用注释和平面域对象结构是不可能的。
  • 我是 Spring 框架的新手。你是说我应该在 REST 控制器中获取整个 JSON 对象并手动读取所有 JSON 字段并将它们设置到实体 pojo 中。
  • 查看杰克逊库。它将允许您将传入的 json 文件转换为 POJO,然后您可以随心所欲地使用该 pojo 来休眠实体

标签: spring hibernate spring-mvc spring-boot spring-data-jpa


【解决方案1】:

您可以使用 Gson 将 json 转换为 DTO

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

【讨论】:

    【解决方案2】:

    伪代码 假设您的实体类为

    @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;
        }
    }
    

    现在,由于您的 DTO/BO 即数据传输对象或业务对象与实际实体不同,我们将创建所需的 BO 对象,如下所示

    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;
        }
    }
    

    @JsonProperty 注解是从 org.codehaus.jackson.annotate.JsonProperty 导入的;即来自杰克逊罐

    现在是一个简单的测试类来演示 DTO/BO 来回实体转换

    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);
    
        }
    }
    

    这将为您提供以下结果

    [  
       {  
          "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"
             }
          }
       }
    ]
    

    与其他转换类似

        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());
    

    这将打印出来

    ADED-EWQD-REV-E1F4343YG3434
    FooSo_MusicAds
    132
    

    TESTRCPT_1523

    您不必使用映射器代码,您可以直接将杰克逊转换器添加为 HttpMessageConverted,它将自动将 JSON 转换为 java 对象

    @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()));
        }
    }
    

    【讨论】:

    • @Anuj 让我知道,如果您需要对该主题进行更多说明,我可以通过查看您的实体类来分享更多详细信息
    猜你喜欢
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多