使用 GSON 反序列化内部 json 字符串 属性
Deserialize inner json string property with GSON
我的后端使用 Springboot 和 Gson。
我在多对多关系中有这两个 classes:
订单class
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table( name = "orders")
public class Order {
@Id
@Expose
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Expose
@NotBlank
private String poNumber;
@Expose
@NotBlank
private String dimension;
@Expose
@NotBlank
private int initialQuantity;
@Expose
@NotBlank
private int leftQuantity;
@Expose
@NotBlank
private Date startDate;
@Expose
@NotBlank
private Date endDate;
@Expose
@SerializedName("status")
@Enumerated(EnumType.STRING)
@Column(length = 20)
private PoStatus status;
@OneToMany(mappedBy="order")
private Set<Log> logs;
@Expose
@SerializedName("products")
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable( name = "orders_products",
joinColumns = @JoinColumn(name = "order_id"),
inverseJoinColumns = @JoinColumn(name = "sap_code"))
private Set<Product> products = new HashSet<>();
产品Class
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table( name = "products")
public class Product {
@Expose
@Id
@NotBlank
private String sapCode;
@Expose
@NotBlank
private String sapCodeDescription;
@Expose
private String productData;
}
这是我用来将数据提供给我的其余端点的服务
public String getAllOrders() {
List<Order> allOrders = orderRepository.findAll();
String allOrdersResult = gson.toJson(allOrders);
return allOrdersResult;
}
这是回复:
[
{
"id": 1,
"poNumber": "003100059361",
"dimension": "INTBKGR",
"initialQuantity": 200000,
"leftQuantity": 200000,
"startDate": "17/08/2022 00:00",
"endDate": "17/08/2022 00:00",
"status": "READY",
"products": [
{
"sapCode": "000000000000416234",
"sapCodeDescription": "1.STUFE 15X",
"productData": "{\"pieces\": 85, \"mark\": true, \"description\": \"elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget\"}"
}
]
}
]
我的目标是deserialize/escapeproductData
字符串属性。
我已经尝试创建 ProductData
class 并使用 @JsonAdapter
注释,但据我了解,当您需要提供自定义行为时会使用此注释对于您的反序列化,我示例中的 JSON 字符串非常简单,我不需要它背后的任何特定逻辑。
我认为您必须为此声明 class 并将 productData 类型从字符串更改为 class。
我是这样解决的,我认为这不是一个好方法,我希望有一个更自动的方法来解决这个问题。
产品Class
public class Product {
@Expose
@Id
@NotBlank
private String sapCode;
@Expose
@NotBlank
private String sapCodeDescription;
//THIS PROPERTY IS TO SAVE THE JSON IN THE DB
@NotBlank
@Column(columnDefinition="TEXT")
@JsonProperty
private String productDataColumn;
//THIS PROPERTY IS TO EXPOSE THE DATA TO THE API
@Transient
@Expose
private ProductData productData;
public void createProductData() {
this.productData = new Gson().fromJson(productDataColumn, ProductData.class);
}
}
产品数据Class
public class ProductData {
@Expose
public int pieces;
@Expose
public boolean marcatura;
@Expose
public String description;
}
订单服务
public String getAllOrders() {
List<Order> allOrders = orderRepository.findAll();
for(Order o : allOrders){
Product orderProduct = o.getProducts().stream().findFirst().get();
orderProduct.createProductData();
}
String allOrdersResult = gson.toJson(allOrders);
return allOrdersResult;
}
我的后端使用 Springboot 和 Gson。 我在多对多关系中有这两个 classes:
订单class
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table( name = "orders")
public class Order {
@Id
@Expose
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Expose
@NotBlank
private String poNumber;
@Expose
@NotBlank
private String dimension;
@Expose
@NotBlank
private int initialQuantity;
@Expose
@NotBlank
private int leftQuantity;
@Expose
@NotBlank
private Date startDate;
@Expose
@NotBlank
private Date endDate;
@Expose
@SerializedName("status")
@Enumerated(EnumType.STRING)
@Column(length = 20)
private PoStatus status;
@OneToMany(mappedBy="order")
private Set<Log> logs;
@Expose
@SerializedName("products")
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable( name = "orders_products",
joinColumns = @JoinColumn(name = "order_id"),
inverseJoinColumns = @JoinColumn(name = "sap_code"))
private Set<Product> products = new HashSet<>();
产品Class
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table( name = "products")
public class Product {
@Expose
@Id
@NotBlank
private String sapCode;
@Expose
@NotBlank
private String sapCodeDescription;
@Expose
private String productData;
}
这是我用来将数据提供给我的其余端点的服务
public String getAllOrders() {
List<Order> allOrders = orderRepository.findAll();
String allOrdersResult = gson.toJson(allOrders);
return allOrdersResult;
}
这是回复:
[
{
"id": 1,
"poNumber": "003100059361",
"dimension": "INTBKGR",
"initialQuantity": 200000,
"leftQuantity": 200000,
"startDate": "17/08/2022 00:00",
"endDate": "17/08/2022 00:00",
"status": "READY",
"products": [
{
"sapCode": "000000000000416234",
"sapCodeDescription": "1.STUFE 15X",
"productData": "{\"pieces\": 85, \"mark\": true, \"description\": \"elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget\"}"
}
]
}
]
我的目标是deserialize/escapeproductData
字符串属性。
我已经尝试创建 ProductData
class 并使用 @JsonAdapter
注释,但据我了解,当您需要提供自定义行为时会使用此注释对于您的反序列化,我示例中的 JSON 字符串非常简单,我不需要它背后的任何特定逻辑。
我认为您必须为此声明 class 并将 productData 类型从字符串更改为 class。
我是这样解决的,我认为这不是一个好方法,我希望有一个更自动的方法来解决这个问题。
产品Class
public class Product {
@Expose
@Id
@NotBlank
private String sapCode;
@Expose
@NotBlank
private String sapCodeDescription;
//THIS PROPERTY IS TO SAVE THE JSON IN THE DB
@NotBlank
@Column(columnDefinition="TEXT")
@JsonProperty
private String productDataColumn;
//THIS PROPERTY IS TO EXPOSE THE DATA TO THE API
@Transient
@Expose
private ProductData productData;
public void createProductData() {
this.productData = new Gson().fromJson(productDataColumn, ProductData.class);
}
}
产品数据Class
public class ProductData {
@Expose
public int pieces;
@Expose
public boolean marcatura;
@Expose
public String description;
}
订单服务
public String getAllOrders() {
List<Order> allOrders = orderRepository.findAll();
for(Order o : allOrders){
Product orderProduct = o.getProducts().stream().findFirst().get();
orderProduct.createProductData();
}
String allOrdersResult = gson.toJson(allOrders);
return allOrdersResult;
}