如何将com.google.cloud.retail.v2.Product对象解析为标准JSON?
解决Google Retail Search Product对象JSON序列化冗余字段问题
问题背景
在集成Google Retail Search时,需要生成符合官方指定格式的Product对象JSON。官方给出的最小字段示例JSON为:
{ "id": "1234", "categories": "Apparel & Accessories > Shoes", "title": "ABC sneakers" }
对应的Java构建代码为:
Product product = Product.newBuilder() .setId("1234") .addCategories("Apparel & Accessories > Shoes") .setTitle("ABC sneakers") .build();
但使用Gson(初始化代码:Gson gson2 = new GsonBuilder().disableHtmlEscaping().create();)序列化该对象时,会输出大量带下划线的冗馀字段,不符合API要求。
优先使用官方解决方案
Google Cloud Retail的com.google.cloud.retail.v2.Product类是基于Protobuf生成的,官方提供了专门的JSON序列化工具JsonFormat,可以直接生成符合要求的JSON,避免冗余字段。
实现步骤
- 确保项目引入Protobuf JSON工具依赖(Maven示例,版本需与Retail API依赖匹配):
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java-util</artifactId> <version>3.25.3</version> </dependency>
- 使用
JsonFormat序列化Product对象:
import com.google.protobuf.util.JsonFormat; // 构建Product对象 Product product = Product.newBuilder() .setId("1234") .addCategories("Apparel & Accessories > Shoes") .setTitle("ABC sneakers") .build(); // 生成符合要求的JSON字符串 String validJson = JsonFormat.printer().print(product);
执行后输出的JSON完全匹配官方示例格式,无冗余下划线字段。
为什么Gson会生成冗余字段?
Gson通过反射对象字段实现序列化,而Protobuf生成的类内部会将字段命名为带下划线的形式(如_id、_categoriesList),Gson会直接输出这些内部字段,导致JSON包含冗余内容。而JsonFormat是Protobuf官方工具,了解字段映射规则,会自动将内部字段转换为API要求的公开字段名称。
自定义类方案(不推荐)
如果一定要使用Gson,可以自定义与官方JSON结构一致的POJO类,手动将Product对象的字段复制到POJO中再序列化,但这种方式维护成本高,API更新时需要同步修改POJO,容易出错。
示例代码
自定义POJO类:
public class CustomRetailProduct { private String id; private String categories; private String title; public CustomRetailProduct(String id, String categories, String title) { this.id = id; this.categories = categories; this.title = title; } // 省略getter、setter方法 }
字段复制与序列化:
// 将Product字段复制到自定义POJO CustomRetailProduct customProduct = new CustomRetailProduct( product.getId(), product.getCategoriesList().isEmpty() ? null : product.getCategoriesList().get(0), product.getTitle() ); // Gson序列化 Gson gson = new GsonBuilder().disableHtmlEscaping().create(); String json = gson.toJson(customProduct);
内容的提问来源于stack exchange,提问作者Makabeusz
相关产品推荐
相关产品推荐

