Spring MVC REST Json Conversion异常

时间:2014-01-12 10:06:47

标签: java json spring rest spring-mvc

我正在关注一个简​​单的Spring MVC REST示例。在PUT请求中,我遇到以下异常:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "property" (Class domain.Property), not marked as ignorable
    at [Source: org.apache.catalina.connector.CoyoteInputStream@75280b93; line: 1, column: 14] (through reference chain: domain.Property["property"]); 
nested exception is org.codehaus.jackson.map.exc.UnrecognizedPropertyException:                               
    Unrecognized field "property" (Class domain.Property), not marked as ignorable
    at [Source: org.apache.catalina.connector.CoyoteInputStream@75280b93; line: 1, column: 14] (through reference chain: domain.Property["property"])

我收到以下JSON

{"property":
    {
        "name":"name",
        "age":"22"
    }
}

以下是我的REST方法:

@RequestMapping(method = RequestMethod.PUT, value = "/{id}")
public ResponseEntity<Property> updateProperty(@RequestBody Property property,
                                               @PathVariable String id) {   
  final ResponseEntity<Property> response = 
          new ResponseEntity<Property>(property, HttpStatus.OK);
  return response;
}

Property是标准的POJO,其中包含姓名和年龄的getter / setter。

如何解决此异常?

2 个答案:

答案 0 :(得分:6)

您的JSON包含{"property": { "name":"name", "age":"22" } }

因此JSON解析器在property(setProperty() method exactly)类中搜索名为Property的字段。因此,您的property类中应该有一个名为Property的字段,其中包含getter和setter。

因此要忽略任何不在类中的JSON解析的字段,您应该使用@JsonIgnoreProperties(ignoreUnknown = true)

注释该类

在你的课堂上,它将是

@JsonIgnoreProperties(ignoreUnknown = true)
public class Property

因此它将忽略JSON字符串中不属于您的Property类的任何字段。

但你的问题仍然无法解决。因为您的JSON字符串name and age位于属性中。所以基本上JSON解析器将查找名为property的字段(类的对象)。然后在对象内部设置名称和年龄的值。然后不需要设置JSON ignore属性。

所以你有三个选择

1。使用getter和setter

属性类中创建一个名为property属性对象

public class Property{
    private Property property;
    private String name;
    private int age;
    //getter and setter
}

然后在你的Controller类中

public ResponseEntity<Property> updateProperty(@RequestBody Property property,
                                               @PathVariable String id) {  

     Property property2=new Property();
     property2=property.getProperty(); 

     //Get Strings from normal object property2

     String name = property2.getName();
     int age = property2,getAge();


  final ResponseEntity<Property> response = 
          new ResponseEntity<Property>(property, HttpStatus.OK);
  return response;
}

<强> 2 即可。为避免混淆,请使用名为 property 的字段创建另一个类作为Property的对象。

示例:

public class PropertiesJson{
private Property property
//getter and setter
}

然后在控制器中使用它而不是Property

public ResponseEntity<Property> updateProperty(@RequestBody PropertiesJson propertiesJson,
                                                   @PathVariable String id) {  

         Property property=propertiesJson.getProperty(); 

         //Get Strings from normal object property

         String name = property.getName();
         int age = property.getAge();


      final ResponseEntity<Property> response = 
              new ResponseEntity<Property>(property, HttpStatus.OK);
      return response;
    }

第3 即可。另一个选项是更改您的JSON字符串

{ "name":"name", "age":"22" }

这就够了。如果你可以改变JSON字符串,这是更好的主意。否则,您必须选择任何其他选项。

答案 1 :(得分:2)

JSON包含一个名为property的属性,该属性无法映射到property类的Property字段。更改JSON以省略此字段。如果您无法更改JSON以删除属性property,请为Property类创建包装。

class PropertyWrapper(){

    private Property property;

    public Property getProperty(){
       return property;
    }

    public Property setProperty(Property p){
        this.property = property;
    }
}

然后使用控制器中的PropertyWrapper

public ResponseEntity<Property> updateProperty(@RequestBody PropertyWrapper property,
                                               @PathVariable String id) {   
  final ResponseEntity<Property> response = 
          new ResponseEntity<Property>(property.getProperty(), HttpStatus.OK);
  return response;
}