我正在努力解决这个问题一段时间,却找不到解决方案。 我的意图是使用 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;
}
}
答案 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