RestTemplate的getForObject()
public void test() {
// 使用方法一,不带参数
String url = "https:/://xxx/xx/x?id=666106231640";
Data data = restTemplate.getForObject(url, InnerRes.class);
System.out.println(data);
// 使用方法二,map传参
url = "https://://xxx/xx/x?id={id}";
Map<String, Object> params = new HashMap<>();
params.put("id", 123);
Data = restTemplate.getForObject(url, Data.class, params);
System.out.println(data);
这个方法在大多数情况下都没问题,还有postForObject()等好用的方法可以用
但是如果返回的值很奇怪,不是严格的JSON,那会报错了,比如遇到一个返回的JSON,内部嵌套的内容有的在大括号外还多了双引号,有的没有,比如:
{
"result":"{"name":"mike","addr":"beijing"}",
"code":"200",
"error":""
}
也不懂对面接口为什么要这么做,也可能是本人见得比较少,不过也没办法了,只能当字符串来处理了
先使用
String str = restTemplate.getForObject(url, String.class);
然后处理字符串,先替换掉转义的""和大括号两边的双引号,假设取到下面这串str
str= "{\"result\":\"{\"name\":\"mike\",\"addr\":\"beijing\"}\",\"code\":\"200\",\"error\":\"\"}";
str = str.replace("\\","");
str = str.replace("\"{","{");
str = str.replace("}\"","}");
然后使用ObjectMapper的readValue()转化为对象
// 创建ObjectMapper
ObjectMapper mapper = new ObjectMapper();
// 下面这步的作用就是忽略json中存在,但java中的目标类中不存在的字段,否则会反序列化报错
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
MyObj obj = mapper.readValue(str,MyObj);
如果MyObj嵌套多个内部类的话,不能够越级访问,如:
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class test{
private String one;
private String two;
private Mytest mytest;
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Mytest{
private String mytest1;
private String mytest2;
}
}
JSON中存在
{
"one": "valone",
"two": "valtwo",
"mytest": {
"mytest1": "t1",
"mytest2": "t2"
}
}
想要获取mytest1的内容,就要创建一个Mytest的内部类,然后才会匹配
最好要把里面各个字段都设为public static,如果是private的话,mapper.readValue()返回的对应字段是null,具体原因未知…
猜想,可能是与ObjectMapper的反射机制有关,private就访问不到了,但是后来发现我有一个三层的内部类,外面两层用private的字段是可以获取到的,第三层后就是null了,必须改成public才能获取到
我使用了lombok,不知道会不会于此有关,希望有知道原因的大佬希望能指点下
顺便记录下一篇比较好的RestTemplate踩坑总结:
https://juejin.im/post/5cb96e84e51d456e5d3dac38