You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 03:36:03