You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Scala新手使用Jackson库读取JSON文件遭遇UnrecognizedPropertyException错误求助

Fixing Jackson's UnrecognizedPropertyException in Scala

Hey there! Let's break down why you're hitting this error and how to fix it properly.

Why the Error Happens

That UnrecognizedPropertyException is telling you your JSON structure doesn't match the Inventory case class you defined. Here's the mismatch:

  • Your JSON is a top-level object with three keys: Rice, Pulses, Wheats — each maps to an array of items with name and price.
  • But your Inventory class only has name and price fields. Jackson is trying to shove the entire JSON (with those Rice/Pulses/Wheats keys) into an Inventory instance, which has no place for those keys — hence the error.

How to Fix It

We need to align your Scala classes with the actual structure of your JSON. Here are two solid approaches:

Approach 1: Define Case Classes That Match the JSON Structure

Let's create two layers of case classes: one for individual items, and one for the top-level inventory structure.

// Case class for a single item (matches the objects inside each array)
case class Item(name: String, price: Int) // Note: price is an Int, not String (your JSON uses numbers!)

// Case class for the entire inventory (matches the top-level JSON object)
case class InventoryData(Rice: List[Item], Pulses: List[Item], Wheats: List[Item])

object InventoryDataManagement {
  def main(args: Array[String]): Unit = {
    val mapper = JsonMapper.builder()
      .addModule(DefaultScalaModule)
      .build()
    val src = new File("src/main/json/inventary.json")
    
    // Map the JSON to our InventoryData class instead of Inventory
    val inventory = mapper.readValue(src, classOf[InventoryData])
    
    // Example: Print all rice items
    println("Rice Inventory:")
    inventory.Rice.foreach(item => println(s"${item.name} - ₹${item.price}"))
    
    // Print pulses too!
    println("\nPulses Inventory:")
    inventory.Pulses.foreach(item => println(s"${item.name} - ₹${item.price}"))
  }
}

Approach 2: Use a Map for Flexible Category Handling

If you might add more categories later (like Spices or Oils) and don't want to update your case class every time, map the JSON directly to a Map[String, List[Item]]:

case class Item(name: String, price: Int)

object InventoryDataManagement {
  def main(args: Array[String]): Unit = {
    val mapper = JsonMapper.builder()
      .addModule(DefaultScalaModule)
      .build()
    val src = new File("src/main/json/inventary.json")
    
    // Map the JSON to a Map where keys are category names, values are item lists
    val inventoryMap = mapper.readValue(src, classOf[Map[String, List[Item]]])
    
    // Loop through all categories and their items
    inventoryMap.foreach { case (category, items) =>
      println(s"\n$category:")
      items.foreach(item => println(s"  • ${item.name}: ₹${item.price}"))
    }
  }
}

Quick Extra Tips

  • Fix the Price Type: Your original Inventory class had price as a String, but your JSON uses numeric values. Changing it to Int (or Double if you have decimals) avoids unnecessary type conversions and errors.
  • Ignore Unknown Fields (Optional): If you ever have JSON with extra fields you don't care about, you can tell Jackson to ignore them to avoid similar errors:
    val mapper = JsonMapper.builder()
      .addModule(DefaultScalaModule)
      .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
      .build()
    

内容的提问来源于stack exchange,提问作者Piyush Jiwane

火山引擎 最新活动