Получение нулевого значения из POJO после использования JACKSON ObjectMapper - PullRequest
0 голосов
/ 27 ноября 2018

Я борюсь с этой проблемой некоторое время и не могу найти решение.Я собираюсь получить POJO из следующего JSON, используя Джексон :

{
    "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;
        }
    }
}

Когда я пытаюсь вызвать метод get для моего объекта POJO, я получаю NullPointException, поэтомучто-то не так с привязкой данных.

мой класс Rates.

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 голосов
/ 27 ноября 2018

вы можете использовать

mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

без каких-либо изменений в ваших Pojos, но мне пришлось добавить MXN в качестве свойства к Rates классу.Но идеальный способ справиться с этим - иметь Map для ставок.Потому что он может измениться в любое время, как я понял, в любом случае доступ к нему проще.Поэтому измените класс валюты следующим образом.

public class Currency {

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

    // getters and setters
}

обменные курсы доступа как getRates().get('MXN') // returns value.

0 голосов
/ 27 ноября 2018

Я проверил ваш код локально, и он работает.У меня не было класса Rates, поэтому я вместо этого использовал карту (для сопоставления имени со скоростью (float)):

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;
    }

}

Я добавил следующееМетод main () для вашего класса JSonToPojo:

    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
0 голосов
/ 27 ноября 2018

Вы можете обратиться к http://www.jsonschema2pojo.org/, чтобы получить правильное pojo для вашего json.Ниже тот, который я создал (модифицированный 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;
    }
}
...