无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象
Posted
技术标签:
【中文标题】无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象【英文标题】:Can't serialize Json to Java object using Jackson ObjectMapper 【发布时间】:2019-08-21 23:12:30 【问题描述】:我正在编写一个可以导出/导入数据的 Java spring boot mvc 应用程序。我写了一个包装类,应该为学生类序列化/反序列化数据。它适用于导出,但在导入过程中会出现错误
com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name
'student' does not match expected ('students') for type [simple type,
class org.bajiepka.courseApp.wrappers.Response] at [Source:
(FileInputStream); line: 2, column: 3]
这是我的 maven jackson 依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
我使用包装类 Response 作为学生列表,
package org.bajiepka.courseApp.wrappers;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
import org.bajiepka.courseApp.domain.Student;
@JsonRootName("import")
public class Response
private Iterable<Student> students;
@JsonProperty("students")
public Iterable<Student> getStudents()
return students;
public void setStudents(Iterable<Student> students)
this.students = students;
这是我的学生课:
@Data
@Entity
public class Student
private @Id @GeneratedValue Long id;
private @Version int version;
@NotNull
private String name;
private String address;
private String phone;
private Integer gradeBook;
private float averageProgress;
public Student()
这是创建导出文件的方法:
public String write(boolean toFile)
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
try
String result = writer.writeValueAsString(response);
if (toFile)
result = fileService.writeToFile(result);
return result;
catch (JsonProcessingException e)
e.printStackTrace();
return "";
导出后我得到带有 json 的文件,但我无法转换为 java 对象:
"student" : [
"id" : 1,
"version" : 0,
"name" : "Rachel Jessica Parker",
"address" : "Pentaho",
"phone" : "111-22-33",
"gradeBook" : 1000121,
"averageProgress" : 0.0
,
"id" : 2,
"version" : 0,
"name" : "Bobby Jackson Junior",
"address" : "Illinois",
"phone" : "222-33-44",
"gradeBook" : 1000122,
"averageProgress" : 0.0
,
"id" : 3,
"version" : 0,
"name" : "Sammy Smith Carlson",
"address" : "Pennsylvania",
"phone" : "333-44-55",
"gradeBook" : 1000123,
"averageProgress" : 0.0
,
"id" : 4,
"version" : 0,
"name" : "Harry Dale Harrison",
"address" : "Detroit",
"phone" : "444-55-66",
"gradeBook" : 1000124,
"averageProgress" : 0.0
,
"id" : 5,
"version" : 0,
"name" : "Lindsey jefferson Conly",
"address" : "Washington",
"phone" : "555-66-77",
"gradeBook" : 1000125,
"averageProgress" : 0.0
,
"id" : 6,
"version" : 0,
"name" : "Mo Williams Jr.",
"address" : "New York",
"phone" : "666-77-88",
"gradeBook" : 1000126,
"averageProgress" : 0.0
]
最后是转换的方法:
@GetMapping(value = "/import")
public String importFile(@RequestParam Long id)
File importFile = new File(exchangeFileService.findById(id).getName());
if (importFile.exists())
try (FileInputStream stream = new FileInputStream(importFile))
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
TypeReference<Response> typeReference = new TypeReference<>();
Response response = mapper.readValue(stream, typeReference);
catch (IOException e)
e.printStackTrace();
return "redirect:/exchange/upload";
我在 mapper.readValue(stream, typeReference) 上面提到了 MismatchInputException
ObjectMapper 应该向我返回一个包含学生列表的响应,但它没有...
@UPDATE
我已经设法找到了错误的原因。 在 Object -> Json 序列化期间,缺少 jackson 根名称... 我已经手动添加了
**"import" : **
"student" : [
"id" : 1,
"version" : 0,
"name" : "Rachel Jessica Parker",
"address" : "Pentaho",
"phone" : "111-22-33",
"gradeBook" : 1000121,
"averageProgress" : 0.0
, ... ]
,
"course" : [
"id" : 7,
"version" : 0,
"name" : "Physics for 9-th grade",
"number" : 100292910,
"cost" : 25000.0,
"modules" : 0,
"max_COURSES_PER_STUDENT" : 3,
"modules_PER_COURSE" : 10
, ... ]
****
我还设法扩展了 Response 类,因为它是必需的......现在我正在尝试在序列化期间在 ObjectMapper 中找到原因......
【问题讨论】:
【参考方案1】:问题是由于Java对象->没有根级别的Json序列化引起的。 要将其添加到 Json,我刚刚通过 withRootName() 方法将其添加到 mapper,从现在开始一切正常!
mapper.writer().withDefaultPrettyPrinter().withRootName("import")
【讨论】:
以上是关于无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象的主要内容,如果未能解决你的问题,请参考以下文章
理解异常的麻烦:“无法从 START_OBJECT 令牌中反序列化 `java.lang.String` 的实例”在 Jackson 中使用 ObjectMapper
Spring Boot 不使用配置的 Jackson ObjectMapper 和 @EnableWebMvc
Jackson ObjectMapper 无法反序列化 POJO,抛出异常:没有找到适合类型 [...] 的构造函数:无法从 JSON 对象实例化