Spring Rest服务@RequestBody嵌套json解析失败

时间:2017-12-28 08:17:05

标签: json jackson spring-rest

  • Spring 4.3.2
  • Jackson 2.7.0

我使用弹簧支架创建了微服务。我要求RequestBody应该有一个嵌套的json。

RequestWrapper.java:

public class RequestWrapper implements Serializable{ 
private String id;
private String message; // json in string format
/**
getter & setter
**/
}

消息属性是动态的,例如,对于一个请求,它可能具有json of" Person"对象,另一个请求它可能有不同的对象。

当我将嵌套的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 ,将消息属性的类型设为对象而不是字符串

public class RequestWrapper<Object extends Serializable> implements Serializable{
private String id;
    private Object message; // Changed to Object
    /**
    getter & setter
    **/
    }

更改控制器类,如下所示

@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(消息)应映射到哪个对象实例,但我不知道如何解决问题。

1 个答案:

答案 0 :(得分:0)

错误消息为您提供问题,甚至告诉您确切的位置。

  

行:1,列:115 ](通过参考链:   com.common.model.RequestWrapper [&#34;消息&#34;]);

     

无法构建   java.io.Serializable的一个例子,问题:抽象类型要么需要   要映射到具体类型,有自定义反序列化器,或者是   使用其他类型信息进行实例化

让您的域对象扩展Serializable是没有意义的。

除此之外,您将方法字段类型更改为Object并设置子字段&#34; age&#34;它不存在于Object.class中的String字段中。没有办法对它进行映射,并且没有任何关于JSON的内容对于该域对象是合法的,并且它自己的域对象是不合法的。