【发布时间】:2017-12-28 08:17:04
【问题描述】:
- 春季 4.3.2
- 杰克逊 2.7.0
我已经使用 spring rest 创建了微服务。我要求 RequestBody 应该有一个嵌套的 json。
RequestWrapper.java:
public class RequestWrapper implements Serializable{
private String id;
private String message; // json in string format
/**
getter & setter
**/
}
消息属性是动态的,例如,对于一个请求,它可能具有“Person”对象的 json,对于另一个请求,它可能具有不同的对象。
当我将嵌套的 json 作为字符串并随后转换为实际对象时,一切正常 例如:
{
"id":"sample",
"message":"{\"age\":\"12\"}"
}
控制器示例:
@Controller
@EnableWebMvc
public class RequestController{
@RequestMapping(value = "/request.htm", method = RequestMethod.POST, headers = "Accept=*/*", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseWrapper handleRequest(@RequestBody RequestWrapper requestWrapper,
HttpServletResponse response) {
ResponseWrapper responseWrapper = new ResponseWrapper();
ObjectMapper mapper = new ObjectMapper();
Person person= mapper.readValue(requestWrapper.getMessage(), Person.class);
}
}
Junit 测试用例也用这种方法成功执行。
现在我修改了 RequestWrapper.java,将消息属性的类型设为 Object 而不是 String
public class RequestWrapper<Object extends Serializable> implements Serializable{
private String id;
private Object message; // Changed to Object
/**
getter & setter
**/
}
改变了Controller类如下
@Controller
@EnableWebMvc
public class CipherController{
@RequestMapping(value = "/request.htm", method = RequestMethod.POST, headers = "Accept=*/*", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseWrapper handleRequest(@RequestBody RequestWrapper requestWrapper,
HttpServletResponse response) {
ResponseWrapper responseWrapper = new ResponseWrapper();
ObjectMapper mapper = new ObjectMapper();
Person person= (Person)requestWrapper.getMessage();
}
}
新的 json 格式现在如下所示:
例如:
{
"id":"sample",
"message":{"age":"12"}
}
当我执行 Junit 测试用例时,我得到以下异常
WARNING: Failed to read HTTP message:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not construct instance of java.io.Serializable, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: java.io.PushbackInputStream@3e58d65e; line: 1, column: 115] (through reference chain: com.common.model.RequestWrapper["message"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.io.Serializable, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
pom.xml 中的杰克逊依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
我假设 Jackson 解析器无法识别嵌套的 json(message) 应该映射到哪个对象实例,但我不知道如何解决这个问题。
【问题讨论】:
标签: json jackson spring-rest