Java 使用JACKSON ObjectMapper后从POJO获取null
我为这个问题挣扎了一段时间,找不到解决办法。 我的目的是使用Jackson从以下JSON检索POJO: 我用以下代码解决了这个问题:Java 使用JACKSON ObjectMapper后从POJO获取null,java,json,jackson,pojo,Java,Json,Jackson,Pojo,我为这个问题挣扎了一段时间,找不到解决办法。 我的目的是使用Jackson从以下JSON检索POJO: 我用以下代码解决了这个问题: public class JsonToPojo { private static final String URL_LATEST = "https://api.exchangeratesapi.io/latest"; public static String getJson() { try { URL
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;
}
}
您可以参考获取json的正确pojo。
下面是我创建的(已修改)
您可以将类似对象日期替换为日期日期等。如果它不起作用,那么您的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();
}
}
import com.fasterxml.jackson.annotation.JsonProperty;
导入java.util.HashMap;
导入java.util.Map;
导入com.fasterxml.jackson.annotation.JsonAnyGetter;
导入com.fasterxml.jackson.annotation.JsonAnySetter;
导入com.fasterxml.jackson.annotation.JsonIgnore;
公开课范例{
@JsonProperty(“日期”)
私有对象日期;
@JsonProperty(“费率”)
私人目标利率;
@JsonProperty(“基础”)
私有对象库;
@杰索尼奥雷
私有映射additionalProperties=new HashMap();
@JsonProperty(“日期”)
公共对象getDate(){
返回日期;
}
@JsonProperty(“日期”)
公共作废设置日期(对象日期){
this.date=日期;
}
@JsonProperty(“费率”)
公共对象getRates(){
回报率;
}
@JsonProperty(“费率”)
公共无效设置率(对象率){
这个。比率=比率;
}
@JsonProperty(“基础”)
公共对象getBase(){
返回基地;
}
@JsonProperty(“基础”)
公共无效收进框(对象库){
this.base=base;
}
@JsonAnyGetter
公共映射getAdditionalProperties(){
返回此。附加属性;
}
@JSONANYSETER
public void setAdditionalProperty(字符串名称、对象值){
this.additionalProperties.put(名称、值);
}
@凌驾
公共字符串toString(){
return“date:+date.toString()+
“,\n评级:“+rates.toString()+
“,\n基:“+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;
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
导入java.io.IOException;
导入java.nio.file.Files;
导入java.nio.file.path;
导入java.util.stream.collector;
导入java.util.stream.stream;
公共班机{
公共静态void main(字符串…参数){
Main Main=新Main();
Example=main.readObjectDataFromJsonFile(Example.class,“test json.json”);
System.out.println(示例);
}
public T readObjectDataFromJsonFile(类clazz,字符串jsonFilePath){
T populatedObject=null;
试一试{
ObjectMapper ObjectMapper=新的ObjectMapper();
字符串objectJson=“”;
streamlines=Files.lines(path.get(jsonFilePath));
objectJson=lines.collect(Collectors.joining());
行。关闭();
populatedObject=objectMapper.readValue(objectJson,clazz);
}捕获(IOException IOException){
System.out.println(“读取json文件中的异常”);
System.out.println(ioException.getMessage());
}
返回populatedObject;
}
}
您可以使用
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
您的POJO没有任何更改,但我必须将MXN
作为属性添加到Rates
类中。但处理这一问题的理想方法是为费率设置Map
。因为据我所知,它可以随时更改,无论哪种方式都更容易访问。因此,按如下方式更改货币类别
public class Currency {
private String date;
private Map<String, Float> rates;
private String base;
// getters and setters
}
公共类货币{
私有字符串日期;
私人地图费率;
私有字符串基;
//接球手和接球手
}
以
getRates()的形式访问汇率。get('MXN')//返回值
我已在本地检查了您的代码,并使其正常工作。我没有Rates类,所以我使用了Map(映射名称,使用rate(float)):
运行main()方法,生成以下输出(我使用了[snip]而不是打印所有JSon(两次)):
“BGN”的输出为:
请发布带有异常相关问题的堆栈跟踪,而不是打印堆栈跟踪并返回null,你可能应该抛出异常,否则你只是在NPE后面屏蔽它。你能发布我添加的类
Rates
@scigs吗。com.fasterxml.jackson.core.JsonParseException正在抛出。@Franz17只是一个建议,使用货币类型枚举的Map
,该Rates
类看起来很可怕感谢站点推荐,这对使用JSON有很大帮助。很高兴它能帮助您:)我建议您更新Rates类,因为它没有MXN货币。@Franz17如果调用外部端点,则需要一种存储响应的方法。在使用Jackson将JSON“转换”为地图之前,您使用的字符串可以临时存储JSON。非常感谢您的帮助并理解此问题。;)
public class Currency {
private String date;
private Map<String, Float> rates;
private String base;
// getters and setters
}
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;
}
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");
}
{"date":"2018-11-27","rates": {"BGN":1.9558, [snip] }
{"date":"2018-11-27","rates": {"BGN":1.9558, [snip] }
1.9558
finished
1.9558