com.google.gson.stream.MalformedJsonException报错解决及仅获取货币code方法
问题根因
你遇到的MalformedJsonException和货币名称带空格没有任何关系,报错的核心原因是序列化逻辑错误:
你先用
RestTemplate将接口返回的JSON反序列化为Object[],此时数组内的元素是Java的LinkedHashMap对象,调用toString()得到的是Java对象的默认字符串格式(键值对用等号、字符串无引号),完全不是合法JSON,Gson解析非法字符串自然会报错。
解决方案
按以下步骤修改即可同时解决报错、实现仅提取货币code的需求:
步骤1:新增Currency实体类
仅保留你需要的code字段即可,Gson/Jackson会自动忽略JSON中其他未定义的字段:
package country.neighbours.tour.models; public class Currency { private String code; public String getCode() { return code; } public void setCode(String code) { this.code = code; } }
步骤2:修改Country类的currencies字段
将原有的Object[]类型改为List<Currency>类型:
package country.neighbours.tour.models; import java.util.List; public class Country { private String name; private String alpha2Code; private String alpha3Code; private List<String> borders; // 替换原有Object[] currencies private List<Currency> currencies; // 其他原有getter、setter保持不变 public List<Currency> getCurrencies() { return currencies; } public void setCurrencies(List<Currency> currencies) { this.currencies = currencies; } }
步骤3:优化Controller的序列化逻辑
直接让RestTemplate将接口返回的JSON转为Country数组,省去中间转Object再转字符串的错误逻辑:
@RestController public class CountryController { @Autowired private RestTemplate restTemplate; private static String baseURL = "https://restcountries.com/v2/"; public Country createCountryObject(String countryName) { // 直接反序列化为Country数组,无需手动用Gson二次解析 Country[] countries = restTemplate.getForObject( baseURL + "name/" + countryName + "?fields=name,alpha2Code,alpha3Code,capital,currencies", Country[].class ); return countries != null && countries.length > 0 ? countries[0] : null; } @GetMapping("/") public String getAll(){ Country country = createCountryObject("bulgaria"); // 按需获取货币code即可 if (country != null && country.getCurrencies() != null) { for (Currency currency : country.getCurrencies()) { System.out.println("货币code:" + currency.getCode()); } } return country != null ? country.getName() : "未查询到对应国家"; } }
可选说明
如果你坚持要使用Gson做序列化,可以直接让RestTemplate返回String类型的原始响应,再用Gson解析即可,不要走Object[]转toString的逻辑:
public Country createCountryObject(String countryName) { // 拿原始JSON字符串 String response = restTemplate.getForObject( baseURL + "name/" + countryName + "?fields=name,alpha2Code,alpha3Code,capital,currencies", String.class ); Gson gson = new Gson(); Country[] countries = gson.fromJson(response, Country[].class); return countries != null && countries.length > 0 ? countries[0] : null; }
内容的提问来源于stack exchange,提问作者Enchantres
相关产品推荐
相关产品推荐

