Spring Boot RestTemplate调用本地接口报JSON反序列化错误
问题根因
报错核心是接口返回值类型和调用方反序列化目标类型不匹配:
- flight_system侧的
localhost:8050/booking接口返回值是List<Booking>,对应HTTP响应体是JSON数组格式(以[开头) - travel-site侧用RestTemplate调用该接口时,指定的反序列化目标类型是单个
Booking对象,Jackson解析JSON时碰到数组起始标记JsonToken.START_ARRAY,无法将数组结构反序列化为单个Java实体类,因此抛出类型不匹配的反序列化异常。
修复方案
调整travel-site侧的控制器代码,让RestTemplate的接收类型和上游接口返回的数组/列表类型匹配,同时修正当前接口的返回值类型,两种常用改法任选其一即可:
- 方案1:用Booking数组类型接收响应,再转为列表返回
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import com.travelsite.model.Booking; import java.util.Arrays; import java.util.List; @RestController public class TravelSiteController { @Autowired private RestTemplate restTemplate; static final String baseUrl = "http://localhost:8050/"; @GetMapping(value = "/travel-site/booking") public List<Booking> getBooking() { ResponseEntity<Booking[]> responseEntity = restTemplate.exchange( baseUrl + "booking", HttpMethod.GET, null, Booking[].class ); return Arrays.asList(responseEntity.getBody()); } }
- 方案2:使用
ParameterizedTypeReference指定泛型列表类型,规避Java泛型类型擦除导致的类型识别问题
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import com.travelsite.model.Booking; import java.util.List; @RestController public class TravelSiteController { @Autowired private RestTemplate restTemplate; static final String baseUrl = "http://localhost:8050/"; @GetMapping(value = "/travel-site/booking") public List<Booking> getBooking() { ResponseEntity<List<Booking>> responseEntity = restTemplate.exchange( baseUrl + "booking", HttpMethod.GET, null, new ParameterizedTypeReference<List<Booking>>() {} ); return responseEntity.getBody(); } }
注意:如果travel-site侧的
/travel-site/booking接口本身就只需要返回单条Booking数据,那需要先调整flight_system侧的接口逻辑,让其返回单个Booking对象而非列表,再保留原有调用逻辑即可。
内容的提问来源于stack exchange,提问作者Faheem azaz Bhanej
相关产品推荐
相关产品推荐

