Spring Rest -> Hibernate 实体到 JSON

Posted

技术标签:

【中文标题】Spring Rest -> Hibernate 实体到 JSON【英文标题】:Spring Rest -> Hibernate entity to 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 来休眠实体 【参考方案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 让我知道,如果您需要对该主题进行更多说明,我可以通过查看您的实体类来分享更多详细信息

以上是关于Spring Rest -> Hibernate 实体到 JSON的主要内容,如果未能解决你的问题,请参考以下文章

Spring Rest 是 JAX-RS 的实现还是 Spring Rest 使用啥实现来支持 REST?

是否有适用于 JPA、spring-data、spring-data-rest 的通用 REST 查询语言

Spring-Data-Rest 验证器

使用 Spring Security Rest 插件保护 Grails Rest Api

转: Rest简介及Spring实现

CacheProvider 的异常 NoClassDefFoundError