场景
使用restTemplate请求接口,返回体使用使用fastjson转为java对象时异常,fastjson版本1.2.48
异常贴示
com.alibaba.fastjson.JSONException: can not get javaBeanDeserializer. com.alibaba.fastjson.JSONObject
at com.alibaba.fastjson.util.TypeUtils.castToJavaBean(TypeUtils.java:1044) ~[fastjson-1.2.48.jar:na]
at com.alibaba.fastjson.util.TypeUtils.cast(TypeUtils.java:692) ~[fastjson-1.2.48.jar:na]
at com.alibaba.fastjson.util.TypeUtils.cast(TypeUtils.java:858) ~[fastjson-1.2.48.jar:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:1180) ~[fastjson-1.2.48.jar:na]
at com.alibaba.fastjson.util.TypeUtils.castToJavaBean(TypeUtils.java:1046) ~[fastjson-1.2.48.jar:na]
at com.alibaba.fastjson.util.TypeUtils.cast(TypeUtils.java:692) ~[fastjson-1.2.48.jar:na]
at com.alibaba.fastjson.JSON.toJavaObject(JSON.java:997) ~[fastjson-1.2.48.jar:na]
at ts_for_resttemplate.controller.TestController.test(TestController.java:44) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
代码示例
Model
public class Message {
private String address;
private String age;
}
public class Person {
private Message message;
private String name;
}
public class NewPerson {
private JSONObject message;
private String name;
}
Controller
@RestController
public class TestController {
/**
* 样例数据接口
*/
@ResponseBody
@GetMapping("/test")
public String testForRestTemplate() {
Message message=new Message("杭州","27");
Person person = new Person(message,"wuhaohan");
System.out.println("测试接口已被调用");
return JSONObject.toJSONString(person);
}
/**
* 调用接口
*/
@GetMapping("/")
public void test(){
String newUrl = "http://localhost:8080/test";
RestTemplate template = new RestTemplate();
HttpEntity<JSONObject> request = new HttpEntity<>(null,null);
ResponseEntity<JSONObject> response = template.exchange(newUrl, HttpMethod.GET,request,JSONObject.class);
NewPerson newPerson = JSONObject.toJavaObject(response.getBody() ,NewPerson.class);
}
}
通过http://localhost:8080/接口请求,触发异常
规避方式
//方法1.通过将NewPerson中的JSONObject修改为Object类型,演示略去
//方法2.该方法看着有点智障, 即JSONObject 转 String 转 JSONObject
ResponseEntity<JSONObject> response = template.exchange(newUrl, HttpMethod.GET,request,JSONObject.class);
NewPerson newPerson = JSONObject.toJavaObject(JSONObject.parseObject(JSONObject.toJSONString(response.getBody())) ,NewPerson.class);
//方法3.使用String接收,手动转JSONObject
ResponseEntity<String> response = template.getForEntity(newUrl,String.class);
JSONObject jsonObj = (JSONObject) JSON.parse(response.getBody());
NewPerson newPerson = JSONObject.toJavaObject(jsonObj ,NewPerson.class);
异常原因
1.异常方式,response.getBody()
2.手动转换JSONObject方式
由图可知,两种方式下类中的JSONObject类型的字段message是不同的数据类型。
通过对fastjson代码断点知,LinkedHashMap方式得到的解析器是MapDeserializer,非JavaBeanDeserializer方式