Json parse error cannot deserialize instance of

Java Questions

I’m trying to send a JSON to a POST bodyRequest service to use this information as a Java ArrayList or something like that. When I try to do it, I receive a deserialize error

This is my JSON:

{information: [ {fields: “Periods Offered”, tables: “Courses”,
columns: “Academic Level*”}, {fields: “Default Grading Basis*”,
tables: “Courses”, columns: “Default Offering Percentage”}, {fields:
“Allowed Locations”, tables: “Courses”, columns: “Allowed to Offer”}
] }

This is my POST bodyRequest service

@ResponseBody
@PostMapping("/dataMapping/update/table")

public ResponseEntity<Object> updateDataMappingTable(@RequestBody List<UpdateDataMapping> information) {

    try {
        String update = this.dataMappingService.update(information);
        return new ResponseEntity<Object>(update, HttpStatus.OK);
    } catch (Exception e) {
        Response response = new Response();
        response.setError(e.getMessage());
        return new ResponseEntity<Object>(response, HttpStatus.OK);
    }
}

My UpdateDataMapping class looks like:

public class UpdateDataMapping {

    public String fields;
    public String tables;
    public String columns;

    public UpdateDataMapping() {

    }

    public UpdateDataMapping(String fields, String tables, String columns) {
    
        this.fields = fields;
        this.tables = tables;
        this.columns = columns;
    }

    public String getFields() {
        return fields;
    }

    public void setFields(String fields) {
        this.fields = fields;
    }

    public String getTables() {
        return tables;
    }

    public void setTables(String tables) {
        this.tables = tables;
    }

    public String getColumns() {
        return columns;
    }

    public void setColumns(String columns) {
        this.columns = columns;
    }
}

This is my error:

.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.util.ArrayList<com.kastech.model.UpdateDataMapping> out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList<com.kastech.model.UpdateDataMapping> out of START_OBJECT token
at [Source: (PushbackInputStream); line: 1, column: 1]]

If someone can help me I will appreciate it.

Advertisement

Answer

Your JSON example shows that your array is delivered inside an information object. You are seeing your current stack trace because the Jackson is unable to find an appropriate way to deserialize your request payload.

Either, you can change your request JSON to simply be a list

[ {fields: "Periods Offered", tables: "Courses", columns: "Academic Level*"}, {fields: "Default Grading Basis*", tables: "Courses", columns: "Default Offering Percentage"}, {fields: "Allowed Locations", tables: "Courses", columns: "Allowed to Offer"} ]

or you can have a POJO represent that information object

class UpdateMappingList {
    List<UpdateDataMapping> information;
    ...
}

7 People found this is helpful

MismatchedInpuException is base class for all JsonMappingExceptions. It occurred when input is not mapping with target definition or mismatch between as required for fulfilling the deserialization. This exception is used for some input problems, but in most cases, there should be more explicit subtypes to use.

Here MismatchedInpuException issue is happening because of type mismatch because passing JSON as an array of StudentDetail while deserialization is mapped for single StudentDetail object.

public class StudentDetail {
private int rollNumber;
private String firstName;
private String lastName;

//getter and setter of class
}
import java.io.IOException;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJacksonExample2 {

public static void main(String[] args) {
String json=" ["
+ "{"rollNumber":21 , "firstName":"Saurabh" , "lastName":"Gupta"}, "
+ "{"rollNumber":22 , "firstName":"Abhishek" , "lastName":"Garg"}"
+ "]";

System.out.println(json);
try
{
ObjectMapper mapper = new ObjectMapper();
//issue is here
StudentDetail student= mapper.readValue(json, StudentDetail.class);
System.out.println(student);
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}

}

}

MismatchedInputException Stacktrace


 [{"rollNumber":21 , "firstName":"Saurabh" , "lastName":"Gupta"}, {"rollNumber":22 , "firstName":"Abhishek" , "lastName":"Garg"}]
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.fiot.json.jackson.exceptions.StudentDetail` out of START_ARRAY token
 at [Source: (String)" [{"rollNumber":21 , "firstName":"Saurabh" , "lastName":"Gupta"}, {"rollNumber":22 , "firstName":"Abhishek" , "lastName":"Garg"}]"; line: 1, column: 2]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1139)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1093)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1461)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:185)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at com.fiot.json.jackson.exceptions.TestJacksonExample2.main(TestJacksonExample2.java:22)

Solutions

To resolve this issue, change the type from StudentDetail to as array StudentDetail[]

public static void main(String[] args) {
String json=" ["
+ "{"rollNumber":21 , "firstName":"Saurabh" , "lastName":"Gupta"}, "
+ "{"rollNumber":22 , "firstName":"Abhishek" , "lastName":"Garg"}"
+ "]";
System.out.println(json);
try
{
ObjectMapper mapper = new ObjectMapper();
//Convereted to Type as array
StudentDetail[] students= mapper.readValue(json,  StudentDetail[].class );
System.out.println(students);
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}

}

References

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/exc/MismatchedInputException.html

You would like to see

Follow below link to learn more on JSON and  JSON issues solutions:

  • JSON Tutorial
  • JSON Issues Solutions

The problem
After the front end passes JSON format data to the back end, SpringMVC reports

org.springframework.http.converter.HttpMessageNotReadableException:
     * JSON parse error: Can not deserialize instance of java.lang.String out of START_OBJECT token;
     * nested exception is com.fasterxml.jackson.databind.JsonMappingException:
     * Can not deserialize instance of java.lang.String out of START_OBJECT token
     *  at [Source: [email protected]; line: 1, column: 88] (through reference chain: com.xxx.XXXDto["employees"])

plan
To solve this problem, we can use one of the Uniform Exception Handling methods in Spring

@ExceptionHandler({HttpMessageNotReadableException.class, JsonMappingException.class, HttpMediaTypeNotSupportedException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String,Object> exceptionHandler(Exception ex){
        Map<String,Object> map = new HashMap<>(3);
        try{
           map.put("code","400");
           map.put("msg",ex.getMessage());
           return map;
        }catch (Exception e){
            log.error("exception handler error",e);
            map.put("code","400");
            map.put("msg",e.getMessage());
            return map;
        }
    }

Solve problems encountered in the process
The above method can handle the problem of JSON formatting errors, but the data content returned to the front end is in the following format

JSON parse error: Can not deserialize instance of java.lang.String out of START_OBJECT token;  nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token  at [Source: [email protected]; line: 1, column: 88] (through reference chain: com.xxx.XXXDto["callBackUrl"])

We can’t see what the problem is at first sight, and even if we are familiar with the error, we can’t immediately find out where the problem is, because we need to process the above data and then send it back to the front end. Right
Finally solve the problem
We debug the source code found, Change is abnormal in springframework org. Springframework. HTTP. Converter. Json. AbstractJackson2HttpMessageConverter
thrown inside abnormal is
JsonMappingException extends JsonProcessingException
, Thrown in for springmvc HttpMessageNotReadableException, as a result, we only need to add corresponding processing logic unified exception handling, can be returned to the front

@ExceptionHandler({HttpMessageNotReadableException.class, JsonMappingException.class, HttpMediaTypeNotSupportedException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String,Object> exceptionHandler(Exception ex){
        Map<String,Object> map = new HashMap<>(3);
        try{
            if(ex instanceof HttpMessageNotReadableException
                    && ex.getMessage().indexOf("JSON parse error:")>-1){
                map.put("code","400");
                String message=ex.getMessage();
                int beginIndex=message.indexOf("XXXDto["");
                int endIndex=message.indexOf(""])",beginIndex);
                message="parameter"+message.substring(beginIndex+22,endIndex)+" format error";
                map.put("msg",message);
            }else{
                map.put("code","400");
                map.put("msg",ex.getMessage());
            }
            return map;
        }catch (Exception e){
            log.error("exception handler error",e);
            map.put("code","400");
            map.put("msg",e.getMessage());
            return map;
        }
    }

cannot-deserialize-instance-enum-list-spring-boot-exception-featured

cannot-deserialize-instance-enum-list-spring-boot-exception-blog

Cannot deserialize instance of enum list spring boot exception

Issue

When you are trying to map the POST request body with enum properties, then you must need to do @JsonCreator to map the enums with request body and the list of properties available in the enum.

Full Exception for reference

JSON parse error: Cannot deserialize instance of ‘com.ngdeveloper.posts.enums.PostType’ out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of ‘com.ngdeveloper.posts.enums.PostType’ out of START_OBJECT token at [Source: (PushbackInputStream); line 17, column 5] (through reference chain: com.ngdeveloper.dto.posts”

Solution

Issue code for reference

@Getter
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PostType {
   NEW("NEW","New Post"),
   DRAFT("DRAFT", "Drafted Post");

 private String type;
 private String description;
  
  PostType(String type, String description){
     this.type = type;
     this.description = description;
  }
 
}

Fixed code for reference

Add the @JsonCreator annotation with the static method to map the json property with the enums.

@Getter
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PostType {
   NEW("NEW","New Post"),
   DRAFT("DRAFT", "Drafted Post");

 private String type;
 private String description;
  
  PostType(String type, String description){
     this.type = type;
     this.description = description;
  }

   @JsonCreator
   static PostType findValue(@JsonProperty("type") String type, @JsonProperty("description") String description){
      return Arrays.stream(PostType.values()).filter(pt -> pt.type.equlas(type) && pt.description.equals(description)).findFirst().get();
}
 
}

Still “Cannot deserialize instance of enum list spring boot exception” comes ?

  • Then you may need compare the exact value of the enums are matching with the request body.
  • Do maven build and try once again!

Понравилась статья? Поделить с друзьями:
  • Json parse array error
  • Json logic error
  • Json load memory error
  • Json last error msg syntax error
  • Json error битрикс