使用Gson解析ProductsByCategory集合JSON数据的技术问询
Hey there! The issue here is that your JSON response is a top-level object containing the ProductsByCategory array, not a raw array itself. Your current parsing code tries to deserialize it directly as a Collection<ProductsByCategory>, which Gson doesn't expect—this will throw a parsing error because the JSON starts with { (object) instead of [ (array).
Here's how to fix this properly:
Step 1: Create a Wrapper Class for the Root JSON Object
You need a class that matches the structure of your JSON's top-level object. Let's name it ProductCategoryResponse:
import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import java.util.List; public class ProductCategoryResponse { @SerializedName("ProductsByCategory") @Expose private List<ProductsByCategory> productsByCategory; // Getter and setter methods public List<ProductsByCategory> getProductsByCategory() { return productsByCategory; } public void setProductsByCategory(List<ProductsByCategory> productsByCategory) { this.productsByCategory = productsByCategory; } }
Step 2: Update Your Parsing Logic
Instead of targeting a Collection, deserialize the JSON into the wrapper class first, then extract the product list from it:
// Initialize Gson (use GsonBuilder if you need @Expose support) Gson gson = new Gson(); // If you rely on @Expose to exclude fields, use this instead: // Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); // Parse the JSON into the wrapper class ProductCategoryResponse response = gson.fromJson(mMessage, ProductCategoryResponse.class); // Extract the list of products List<ProductsByCategory> productItems = response.getProductsByCategory();
Step 3: Polish Your ProductsByCategory Class
Looking at your truncated code, make sure to address these details:
- Nested
DimensionsClass: Your JSON includes adimensionsfield, so you need to define this nested class properly:public class Dimensions { @SerializedName("length") @Expose private String length; @SerializedName("width") @Expose private String width; @SerializedName("height") @Expose private String height; // Add getters and setters here } - Replace Generic
ObjectFields: Fields likedateOnSaleFromare defined asObject—replace them with specific types (e.g.,Stringfor raw date strings, orLocalDateTimeif you want parsed dates). For date parsing, you can add a Gson type adapter:// Example adapter for Java 8+ LocalDateTime class LocalDateTimeAdapter implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> { private final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; @Override public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(formatter.format(src)); } @Override public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return LocalDateTime.parse(json.getAsString(), formatter); } } // Register the adapter when building Gson Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter()) .create(); - Complete Truncated Fields: Finish the truncated fields in your
ProductsByCategoryclass, ensuring every JSON key has a matching@SerializedNameannotation.
Quick Reminders
- Double-check your JSON is valid (the snippet you provided is truncated—make sure all brackets and quotes are properly closed before parsing).
- If you use
@Expose, always build Gson withexcludeFieldsWithoutExposeAnnotation()to make those annotations take effect.
内容的提问来源于stack exchange,提问作者Tunga

