amique
amique

Reputation: 2226

Spring MVC REST Json Conversion exception

I am following a simple Spring MVC REST example. On PUT request, I am getting following exception:

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"])

I am receiving following JSON

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

Following is my REST method:

@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;
}

The Property is standard POJO with getter/setter for name and age.

How can I resolve this exception?

Upvotes: 2

Views: 4254

Answers (2)

Coder
Coder

Reputation: 7076

Your JSON contains {"property": { "name":"name", "age":"22" } }

So the JSON parser searching for a field called property(setProperty() method exactly) in the Property Class. So you should have a field called property with getter and setter in your Property Class.

So to ignore any field to parse by JSON which is not in the class, You should annotate the class with @JsonIgnoreProperties(ignoreUnknown = true)

In your class it would be

@JsonIgnoreProperties(ignoreUnknown = true)
public class Property

So it will ignore any field in JSON string which is not in you Property class.

But still your problem wont get solved. Because your JSON string name and age is inside property. So Basically JSON parser will look for field called property (The object of the class). And then inside the object it will set the values of name and age. Then no need to set the JSON ignore property.

So you have three options

1. Create one object of Property called property inside the Property class with getter and setter

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

And then in your Controller class

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. To avoid confusion, create another class with a field named property as object of Property.

Example:

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

Then in controller use it instead of 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. The other option is change your JSON string

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

This is enough. If you can change JSON string, this is better idea. Otherwise, you have to choose any of the other options.

Upvotes: 5

Kevin Bowersox
Kevin Bowersox

Reputation: 94429

The JSON contains a property named property that is not mappable to a property field on your Property class. Change the JSON to omit this field. If you cannot change your JSON to remove the property property, create a wrapper for the Property class.

class PropertyWrapper(){

    private Property property;

    public Property getProperty(){
       return property;
    }

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

Then use the PropertyWrapper within your controller:

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

Upvotes: 2

Related Questions