使用JACKSON ObjectMapper后从POJO获取null

时间:2018-11-27 16:25:56

标签: java json jackson pojo

我正在努力解决这个问题一段时间,却找不到解决方案。 我的意图是使用 Jackson 从以下JSON检索POJO:

{
    "date": "2018-11-27",
    "rates": {
        "BGN": 1.9558,
        "CAD": 1.5018,
        "BRL": 4.4011,
        "HUF": 324.06,
        "DKK": 7.4617,
        "JPY": 128.66,
        "ILS": 4.2215,
        "TRY": 5.9313,
        "RON": 4.6583,
        "GBP": 0.88748,
        "PHP": 59.439,
        "HRK": 7.4275,
        "NOK": 9.7325,
        "USD": 1.1328,
        "MXN": 23.1784,
        "AUD": 1.5631,
        "IDR": 16410.59,
        "KRW": 1279.17,
        "HKD": 8.8679,
        "ZAR": 15.632,
        "ISK": 141,
        "CZK": 25.914,
        "THB": 37.371,
        "MYR": 4.7498,
        "NZD": 1.6647,
        "PLN": 4.2902,
        "SEK": 10.2823,
        "RUB": 75.6401,
        "CNY": 7.8708,
        "SGD": 1.5582,
        "CHF": 1.1309,
        "INR": 80.162
    },
    "base": "EUR"
}

我用以下代码解决了它:

public class JsonToPojo {

    private static final String URL_LATEST = "https://api.exchangeratesapi.io/latest";

    public static String getJson() {


        try {
            URL url = new URL(URL_LATEST);

            HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();

            urlConnection.setRequestMethod("GET");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = bufferedReader.readLine()) != null) {
                System.out.println(inputLine);
                 response.append(inputLine);
            }
            bufferedReader.close();
            urlConnection.disconnect();

            return response.toString();

        } catch (IOException e) {
            e.getStackTrace();
            return null;
        }
    }
}

这是我的POJO:

public class Currency {

    private String date;
    private Rates rates;
    private String base;


    public String getBase() {
        return base;
    }

    public void setBase(String base) {
        this.base = base;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Rates getRates() {
        return rates;
    }

    public void setRates(Rates rates) {
        this.rates = rates;
    }


}

使用ObjectMapper的类:

public class CurrencyService {

    public static Currency getLatestCurrency(){

        try {
            ObjectMapper mapper = new ObjectMapper();
            Currency currency = mapper.readValue(JsonToPojo.getJson(), Currency.class);
            return currency;
        }catch (IOException e){
            e.getStackTrace();
            return null;
        }
    }
}

当我尝试在POJO对象上调用get方法时,我得到了NullPointException,因此数据绑定有问题。

我的费率类。

public class Rates {
    private float BGN;
    private float CAD;
    private float BRL;
    private float HUF;
    private float DKK;
    private float JPY;
    private float ILS;
    private float TRY;
    private float RON;
    private float GBP;
    private float PHP;
    private float HRK;
    private float NOK;
    private float ZAR;
    private float MXD;
    private float AUD;
    private float USD;
    private float KRW;
    private float HKD;
    private float EUR;
    private float ISK;
    private float CZK;
    private float THB;
    private float MYR;
    private float NZD;
    private float PLN;
    private float CHF;
    private float SEK;
    private float CNY;
    private float SGD;
    private float INR;
    private float IDR;
    private float RUB;

    public void setBGN(Float BGN) {
        this.BGN = BGN;
    }

    public void setCAD(Float CAD) {
        this.CAD = CAD;
    }

    public void setBRL(Float BRL) {
        this.BRL = BRL;
    }

    public void setHUF(Float HUF) {
        this.HUF = HUF;
    }

    public void setDKK(Float DKK) {
        this.DKK = DKK;
    }

    public void setJPY(Float JPY) {
        this.JPY = JPY;
    }

    public void setILS(Float ILS) {
        this.ILS = ILS;
    }

    public void setTRY(Float TRY) {
        this.TRY = TRY;
    }

    public void setRON(Float RON) {
        this.RON = RON;
    }

    public void setGBP(Float GBP) {
        this.GBP = GBP;
    }

    public void setPHP(Float PHP) {
        this.PHP = PHP;
    }

    public void setHRK(Float HRK) {
        this.HRK = HRK;
    }

    public void setNOK(Float NOK) {
        this.NOK = NOK;
    }

    public void setZAR(Float ZAR) {
        this.ZAR = ZAR;
    }

    public void setMXD(Float MXD) {
        this.MXD = MXD;
    }

    public void setAUD(Float AUD) {
        this.AUD = AUD;
    }

    public void setUSD(Float USD) {
        this.USD = USD;
    }

    public void setKRW(Float KRW) {
        this.KRW = KRW;
    }

    public void setHKD(Float HKD) {
        this.HKD = HKD;
    }

    public void setEUR(Float EUR) {
        this.EUR = EUR;
    }

    public void setISK(Float ISK) {
        this.ISK = ISK;
    }

    public void setCZK(Float CZK) {
        this.CZK = CZK;
    }

    public void setTHB(Float THB) {
        this.THB = THB;
    }

    public void setMYR(Float MYR) {
        this.MYR = MYR;
    }

    public void setNZD(Float NZD) {
        this.NZD = NZD;
    }

    public void setPLN(Float PLN) {
        this.PLN = PLN;
    }

    public void setCHF(Float CHF) {
        this.CHF = CHF;
    }

    public void setSEK(Float SEK) {
        this.SEK = SEK;
    }

    public void setCNY(Float CNY) {
        this.CNY = CNY;
    }

    public void setSGD(Float SGD) {
        this.SGD = SGD;
    }

    public void setINR(Float INR) {
        this.INR = INR;
    }

    public void setIDR(Float IDR) {
        this.IDR = IDR;
    }

    public void setRUB(Float RUB) {
        this.RUB = RUB;
    }

    public Float getBGN() {
        return BGN;
    }

    public Float getCAD() {
        return CAD;
    }

    public Float getBRL() {
        return BRL;
    }

    public Float getHUF() {
        return HUF;
    }

    public Float getDKK() {
        return DKK;
    }

    public Float getJPY() {
        return JPY;
    }

    public Float getILS() {
        return ILS;
    }

    public Float getTRY() {
        return TRY;
    }

    public Float getRON() {
        return RON;
    }

    public Float getGBP() {
        return GBP;
    }

    public Float getPHP() {
        return PHP;
    }

    public Float getHRK() {
        return HRK;
    }

    public Float getNOK() {
        return NOK;
    }

    public Float getZAR() {
        return ZAR;
    }

    public Float getMXD() {
        return MXD;
    }

    public Float getAUD() {
        return AUD;
    }

    public Float getUSD() {
        return USD;
    }

    public Float getKRW() {
        return KRW;
    }

    public Float getHKD() {
        return HKD;
    }

    public Float getEUR() {
        return EUR;
    }

    public Float getISK() {
        return ISK;
    }

    public Float getCZK() {
        return CZK;
    }

    public Float getTHB() {
        return THB;
    }

    public Float getMYR() {
        return MYR;
    }

    public Float getNZD() {
        return NZD;
    }

    public Float getPLN() {
        return PLN;
    }

    public Float getCHF() {
        return CHF;
    }

    public Float getSEK() {
        return SEK;
    }

    public Float getCNY() {
        return CNY;
    }

    public Float getSGD() {
        return SGD;
    }

    public Float getINR() {
        return INR;
    }

    public Float getIDR() {
        return IDR;
    }

    public Float getRUB() {
        return RUB;
    }
}

3 个答案:

答案 0 :(得分:1)

您可以参考http://www.jsonschema2pojo.org/来获取json的正确pojo。 下面是我创建的(修改了moderatley) 您可以将“对象日期”替换为“日期日期”,等等。如果它不起作用,那么您的POJO中可能存在一些错误

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;


public class Example {

    @JsonProperty("date")
    private Object date;
    @JsonProperty("rates")
    private Object rates;
    @JsonProperty("base")
    private Object base;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("date")
    public Object getDate() {
        return date;
    }

    @JsonProperty("date")
    public void setDate(Object date) {
        this.date = date;
    }

    @JsonProperty("rates")
    public Object getRates() {
        return rates;
    }

    @JsonProperty("rates")
    public void setRates(Object rates) {
        this.rates = rates;
    }

    @JsonProperty("base")
    public Object getBase() {
        return base;
    }

    @JsonProperty("base")
    public void setBase(Object base) {
        this.base = base;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    @Override
    public String toString() {
        return "date:" + date.toString() +
                ",\nrates:" + rates.toString() +
                ",\nbase: " + base.toString();

    }
}

这是驱动程序类,您可以在其中读取对象并传递用户定义的文件路径(我将其设置为“ test-json.json”)。您可以使用本地文件路径地址对此进行更新。

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String... args){
        Main main = new Main();
        Example example = main.readObjectDataFromJsonFile(Example.class,"test-json.json");
        System.out.println(example);
    }

    public <T> T readObjectDataFromJsonFile(Class<T> clazz, String jsonFilePath) {
        T populatedObject = null;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String objectJson = "";
            Stream<String> lines = Files.lines(Paths.get(jsonFilePath));
            objectJson = lines.collect(Collectors.joining());
            lines.close();
            populatedObject = objectMapper.readValue(objectJson, clazz);
        } catch (IOException ioException) {
            System.out.println("Exception in reading json file");
            System.out.println(ioException.getMessage());
        }
        return populatedObject;
    }
}

答案 1 :(得分:1)

您可以使用

mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

没有对您的Pojos进行任何更改,但是我不得不将MXN作为属性添加到Rates类中。但是,处理此问题的理想方法是为费率设置Map。据我了解,由于它可以随时更改,因此无论哪种方式,它都更易于访问。因此,如下更改Currency类。

public class Currency {

    private String date;
    private Map<String, Float> rates;
    private String base;

    // getters and setters
}

访问汇率为getRates().get('MXN') // returns value

答案 2 :(得分:1)

我已经在本地检查了您的代码,并使其正常运行。我没有Rates类,所以我改用了Map(用速率(浮动)映射名称):

import java.util.Map;

public class Currency {

    private String date;
    private Map<String, Float> rates;
    private String base;


    public String getBase() {
        return base;
    }

    public void setBase(String base) {
        this.base = base;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Map<String, Float> getRates() {
        return rates;
    }

    public Float getSingleRate(String rateKey) {
       if (rates.containsKey(rateKey)) {
           return rates.get(rateKey);
       }

       return 0.0F;
    }

    public void setRates(Map<String, Float> rates) {
        this.rates = rates;
    }

}

我在您的JSonToPojo类中添加了以下main()方法:

    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();

        Currency currency = new Currency();

        String jsonStr = getJson();


        try {
            currency = mapper.readValue(jsonStr, Currency.class);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(jsonStr);

        System.out.println(currency.getSingleRate("BGN"));

        System.out.println("finished");
    }

运行main()方法,将产生以下输出(我使用[snip]而不是打印出所有JSon(两次)):

{"date":"2018-11-27","rates":    {"BGN":1.9558, [snip] }

{"date":"2018-11-27","rates":    {"BGN":1.9558, [snip] }

1.9558

finished

“ BGN”的输出为:

1.9558