将 Json 解析为 Java 对象
Posted
技术标签:
【中文标题】将 Json 解析为 Java 对象【英文标题】:Parse Json into Java Object 【发布时间】:2014-10-17 22:53:54 【问题描述】:我对 Json 的经验非常少,我必须将复杂的 Json 解析为 Java 对象。
我尝试了几种方法都没有成功...我正在获取我所在城市的 Json 格式天气预报,我需要将 Json 数据解析为 Java 对象。
Json:
"city":
"city_code":"ATAT10678",
"name":"Wien",
"url":"oesterreich/wien/ATAT10678.html",
"credit":"info":"In order to use the free weather data from wetter.com you HAVE TO display at least two out of three of the following possibilities: text, link, logo",
"text":"Powered by wetter.com","link":"http://www.wetter.com",
"logo":"Download at http://www.wetter.com/api/downloads/#logos",
"forecast":
"2014-08-24":
"w":"1",
"tx":"20",
"pc":"30",
"06:00":
"w":"2",
"tx":"16",
"pc":"30",
"tn":"15",
"p":"5",
"dhl":"2014-08-24 06:00",
"ws":"19",
"w_txt":"wolkig",
"11:00":
"w":"2",
"tx":"18",
"pc":"30",
"tn":"16",
"p":"6",
"dhl":"2014-08-24 11:00",
"ws":"20",
"w_txt":"wolkig",
"17:00":
"w":"1",
"tx":"20",
"pc":"20",
"tn":"16",
"p":"6",
"dhl":"2014-08-24 17:00",
"ws":"12",
"w_txt":"leicht bewölkt",
"23:00":
"w":"1",
"tx":"16",
"pc":"10",
"tn":"13",
"p":"6",
"dhl":"2014-08-24 23:00",
"ws":"7",
"w_txt":"leicht bewölkt",
"tn":"15",
"p":"24",
"dhl":"2014-08-24 06:00",
"ws":"14",
"w_txt":"leicht bewölkt",
"2014-08-25":"w":"2","tx":"22","pc":"30","06:00":"w":"2","tx":"17","pc":"20","tn":"12","p":"5","dhl":"2014-08-25 06:00","ws":"5","w_txt":"wolkig","11:00":"w":"2","tx":"21","pc":"30","tn":"17","p":"6","dhl":"2014-08-25 11:00","ws":"10","w_txt":"wolkig","17:00":"w":"2","tx":"22","pc":"30","tn":"18","p":"6","dhl":"2014-08-25 17:00","ws":"11","w_txt":"wolkig","23:00":"w":"3","tx":"18","pc":"30","tn":"16","p":"6","dhl":"2014-08-25 23:00","ws":"6","w_txt":"bedeckt","tn":"12","p":"24","dhl":"2014-08-25 06:00","ws":"8","w_txt":"wolkig","2014-08-26":"w":"3","tx":"22","pc":"75","06:00":"w":"3","tx":"17","pc":"75","tn":"15","p":"5","dhl":"2014-08-26 06:00","ws":"6","w_txt":"bedeckt","11:00":"w":"61","tx":"21","pc":"75","tn":"17","p":"6","dhl":"2014-08-26 11:00","ws":"9","w_txt":"leichter Regen","17:00":"w":"61","tx":"22","pc":"75","tn":"18","p":"6","dhl":"2014-08-26 17:00","ws":"9","w_txt":"leichter Regen","23:00":"w":"3","tx":"18","pc":"75","tn":"17","p":"6","dhl":"2014-08-26 23:00","ws":"9","w_txt":"bedeckt","tn":"15","p":"24","dhl":"2014-08-26 06:00","ws":"8","w_txt":"bedeckt"
我不知道如何将其解析为对象..
非常感谢您的建议!
这是我的第一次试用..
Gson gson = new Gson();
JsonObject jsonObj = gson.fromJson(br, JsonObject.class);
Map<String, LinkedTreeMap> map = new HashMap<String, LinkedTreeMap>();
map = (Map<String, LinkedTreeMap>) gson.fromJson(jsonObj.toString(), map.getClass());
LinkedTreeMap<String, LinkedTreeMap> tmp = new LinkedTreeMap<>();
tmp = map.get("city");
for(Map.Entry<String, LinkedTreeMap> e : tmp.entrySet())
System.out.println("k: " + e.getKey());
LinkedTreeMap<String, LinkedTreeMap> tmp1 = new LinkedTreeMap<>();
tmp1 = tmp.get("forecast");
for(Map.Entry<String, LinkedTreeMap> e : tmp1.entrySet())
System.out.println("k: " + e.getKey());
LinkedTreeMap<String, LinkedTreeMap> values = e.getValue();
for(Map.Entry<String, LinkedTreeMap> v : values.entrySet())
System.out.println("k: " + v.getKey() + " v: " + v.getValue());
以及一天的输出:
k: city_code
k: name
k: url
k: credit
k: forecast
k: 2014-08-25
k: w v: 2
k: tx v: 23
k: pc v: 90
k: 06:00 v: w=2, tx=17, pc=20, tn=13, p=5, dhl=2014-08-25 06:00, ws=5, w_txt=wolkig
k: 11:00 v: w=2, tx=21, pc=20, tn=17, p=6, dhl=2014-08-25 11:00, ws=9, w_txt=wolkig
k: 17:00 v: w=2, tx=23, pc=30, tn=17, p=6, dhl=2014-08-25 17:00, ws=11, w_txt=wolkig
k: 23:00 v: w=3, tx=17, pc=90, tn=16, p=6, dhl=2014-08-25 23:00, ws=6, w_txt=bedeckt
k: tn v: 13
k: p v: 24
k: dhl v: 2014-08-25 06:00
k: ws v: 8
k: w_txt v: wolkig
到目前为止一切顺利,但我如何获得 06:00、11:00、17:00 和 23:00(通用,因为时间可以更改),因为这是我需要的信息?
非常感谢,BR 台风
【问题讨论】:
到目前为止您尝试过什么?从谷歌查看 GSOn 库。code.google.com/p/google-gson 使用 Gson 解析,但我无法访问动态属性“2014-08-24”:在预测中。 我已经回答了这里的解决方案***.com/a/15943171/441902 【参考方案1】:这是一个使用 GSON 的示例
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
public class CodeChefTest1
public static String json = "\"balance\": 1000.21, \"num\":100, \"is_vip\":true, \"name\":\"foo\"";
public static void main(String[] args)
JsonElement ele = new JsonParser().parse(json);
for(java.util.Map.Entry<String, JsonElement> entr : ele.getAsJsonObject().entrySet())
System.out.println(entr.getKey());
System.out.println(entr.getValue());
您可以使用上述方法并通过检查 JSONElement(如 isJSONArray(),isJSONObject(),isJSONPrimitive()
等)在循环中运行它,并使用相同的策略执行适当的重新解析。
上面只是遍历 json 字符串并打印所有键值对。您可以对 json 字符串的日期部分执行相同操作。
【讨论】:
我已经尝试过了,但我无法访问属性“2014-08-24”:在预测中,因为它是可变的【参考方案2】:我个人推荐使用杰克逊。使用 jackson,您可以将 JSON 字符串转换为 POJO(java bean)。 https://github.com/FasterXML/jackson
这个库是免费的、快速且易于使用的。
由于您有日期和时间作为属性名称,我认为至少您的对象的那部分应该是 JAVA 映射,正如 Amaynut 建议的那样。
【讨论】:
【参考方案3】:除了gba的Jackson,还可以使用谷歌GSON:https://code.google.com/p/google-gson/
另外,看看这个帖子:Jackson Vs. Gson
【讨论】:
【参考方案4】:您可以使用来自 google 的库 Gson。这是一个将 json 对象转换为 Map 类型的 Java 对象的示例:
Gson gson=new Gson();
String json="\"k1\":\"v1\",\"k2\":\"v2\"";
Map<String,String> map=new HashMap<String,String>();
map=(Map<String,String>) gson.fromJson(json, map.getClass());
另一个尝试使用 Gson 库的解决方案如下:
Gson gson = new Gson();
String json="\"k1\":\"v1\",\"k2\":\"v2\"";
LinkedTreeMap result = gson.fromJson(json, LinkedTreeMap.class);
你需要导入这两个类:
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
你可以查看这篇关于同一主题的帖子: How can I convert JSON to a HashMap using Gson?
【讨论】:
我试过你的建议:Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(br, JsonObject.class); Map这是第一个工作代码..(快速'n脏)..
感谢 Sumeet Sharma!也许有人有更好的解决方案...
public void updateWeather()
forecasts = new ArrayList<>();
try
URL url = new URL(createURL());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.flush();
if (conn.getResponseCode() != 200)
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
Gson gson = new Gson();
JsonObject jsonObj = gson.fromJson(br, JsonObject.class);
JsonElement element = jsonObj.get("city");
jsonObj = gson.fromJson(element.getAsJsonObject(), JsonObject.class);
element = jsonObj.get("forecast");
for (Map.Entry<String, JsonElement> entr : element.getAsJsonObject().entrySet())
JsonElement element1 = entr.getValue().getAsJsonObject();
for (Map.Entry<String, JsonElement> entr1 : element1.getAsJsonObject().entrySet())
if (entr1.getValue().isJsonObject())
JsonElement element2 = entr1.getValue().getAsJsonObject();
Forecast forecast = new Forecast();
for (Map.Entry<String, JsonElement> entr2 : element2.getAsJsonObject().entrySet())
switch (entr2.getKey())
case "w":
forecast.setW(entr2.getValue().getAsString());
break;
case "tx":
forecast.setTx(entr2.getValue().getAsString());
break;
case "pc":
forecast.setPc(entr2.getValue().getAsString());
break;
case "tn":
forecast.setTn(entr2.getValue().getAsString());
break;
case "p":
forecast.setP(entr2.getValue().getAsString());
break;
case "dhl":
forecast.setDhl(entr2.getValue().getAsString());
break;
case "ws":
forecast.setWs(entr2.getValue().getAsString());
break;
case "w_txt":
forecast.setW_txt(entr2.getValue().getAsString());
break;
forecasts.add(forecast);
conn.disconnect();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
for(Forecast f : forecasts)
System.out.println(f);
【讨论】:
以上是关于将 Json 解析为 Java 对象的主要内容,如果未能解决你的问题,请参考以下文章