使用Gson解析含有集合、数组嵌套的json数据(反序列化)
程序员文章站
2022-05-11 19:53:43
...
一:准备工作
- Gson包
- 下面有使用到了logging日志导入下面几个库包
二:json数据
要获取的是地震等级、位置、时间、url四个信息,通过下面的json格式可以知道这四个属性都属于properties这个对象,而properties又包含在features这个数组同时这个数组又是最外层对象的一个属性。
{
"type": "FeatureCollection",
"metadata": {
"generated": 1587342592000,
"url": "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&limit=10&minmag=6&orderby=time",
"title": "USGS Earthquakes",
"status": 200,
"api": "1.8.1",
"limit": 10,
"offset": 1,
"count": 9
},
"features": [{
"type": "Feature",
"properties": {
"mag": 6.2999999999999998,
"place": "25km SE of Ofunato, Japan",
"time": 1587328745984,
"updated": 1587341149813,
"tz": 540,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us7000903m",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us7000903m&format=geojson",
"felt": 49,
"cdi": 4.5999999999999996,
"mmi": 5.5709999999999997,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 633,
"net": "us",
"code": "7000903m",
"ids": ",us7000903m,pt20110001,at00q91yp4,",
"sources": ",us,pt,at,",
"types": ",dyfi,geoserve,ground-failure,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 1.99,
"rms": 1.1399999999999999,
"gap": 39,
"magType": "mww",
"type": "earthquake",
"title": "M 6.3 - 25km SE of Ofunato, Japan"
},
"geometry": {
"type": "Point",
"coordinates": [141.93180000000001, 38.911900000000003, 38]
},
"id": "us7000903m"
},
{
"type": "Feature",
"properties": {
"mag": 6.5999999999999996,
"place": "209km W of Chichi-shima, Japan",
"time": 1587198337201,
"updated": 1587329781823,
"tz": 540,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008z89",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008z89&format=geojson",
"felt": 40,
"cdi": 3.7999999999999998,
"mmi": 0,
"alert": "green",
"status": "reviewed",
"tsunami": 1,
"sig": 685,
"net": "us",
"code": "70008z89",
"ids": ",at00q8z62q,pt20109000,us70008z89,",
"sources": ",at,pt,us,",
"types": ",dyfi,geoserve,impact-link,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 1.853,
"rms": 0.75,
"gap": 34,
"magType": "mww",
"type": "earthquake",
"title": "M 6.6 - 209km W of Chichi-shima, Japan"
},
"geometry": {
"type": "Point",
"coordinates": [140.1061, 27.139800000000001, 453.76999999999998]
},
"id": "us70008z89"
},
{
"type": "Feature",
"properties": {
"mag": 6,
"place": "55km NNE of Savannah Bight, Honduras",
"time": 1587024277597,
"updated": 1587311760245,
"tz": -360,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008xeb",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008xeb&format=geojson",
"felt": 134,
"cdi": 5.5,
"mmi": 4.6470000000000002,
"alert": "green",
"status": "reviewed",
"tsunami": 1,
"sig": 628,
"net": "us",
"code": "70008xeb",
"ids": ",at00q8vfrr,pt20107000,us70008xeb,",
"sources": ",at,pt,us,",
"types": ",dyfi,geoserve,ground-failure,impact-link,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 3.323,
"rms": 1.45,
"gap": 31,
"magType": "mww",
"type": "earthquake",
"title": "M 6.0 - 55km NNE of Savannah Bight, Honduras"
},
"geometry": {
"type": "Point",
"coordinates": [-85.709900000000005, 16.933199999999999, 10]
},
"id": "us70008xeb"
},
{
"type": "Feature",
"properties": {
"mag": 6,
"place": "194km SE of Raoul Island, New Zealand",
"time": 1586826407913,
"updated": 1586912943507,
"tz": -720,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008vsp",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008vsp&format=geojson",
"felt": 1,
"cdi": 1,
"mmi": 0,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 554,
"net": "us",
"code": "70008vsp",
"ids": ",us70008vsp,at00q8r731,pt20105000,",
"sources": ",us,at,pt,",
"types": ",dyfi,geoserve,ground-failure,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 1.7849999999999999,
"rms": 0.70999999999999996,
"gap": 14,
"magType": "mww",
"type": "earthquake",
"title": "M 6.0 - 194km SE of Raoul Island, New Zealand"
},
"geometry": {
"type": "Point",
"coordinates": [-176.34780000000001, -30.3889, 31]
},
"id": "us70008vsp"
},
{
"type": "Feature",
"properties": {
"mag": 6.0999999999999996,
"place": "96km N of Amsterdam Island, France",
"time": 1586674667719,
"updated": 1586811032040,
"tz": 300,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008um8",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008um8&format=geojson",
"felt": null,
"cdi": null,
"mmi": 4.242,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 572,
"net": "us",
"code": "70008um8",
"ids": ",us70008um8,pt20103000,at00q8ny0e,",
"sources": ",us,pt,at,",
"types": ",geoserve,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 0.83599999999999997,
"rms": 0.91000000000000003,
"gap": 32,
"magType": "mww",
"type": "earthquake",
"title": "M 6.1 - 96km N of Amsterdam Island, France"
},
"geometry": {
"type": "Point",
"coordinates": [77.445899999999995, -36.963700000000003, 10]
},
"id": "us70008um8"
},
{
"type": "Feature",
"properties": {
"mag": 6.5,
"place": "72km W of Challis, Idaho",
"time": 1585698751094,
"updated": 1587340955674,
"tz": -420,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008jr5",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008jr5&format=geojson",
"felt": 39139,
"cdi": 7.5999999999999996,
"mmi": 8.2390000000000008,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 1410,
"net": "us",
"code": "70008jr5",
"ids": ",us70008jr5,mb80387294,pt20091001,at00q830zi,uu60371877,",
"sources": ",us,mb,pt,at,uu,",
"types": ",dyfi,finite-fault,general-link,general-text,geoserve,ground-failure,impact-text,internal-origin,losspager,moment-tensor,oaf,origin,phase-data,shakemap,",
"nst": null,
"dmin": 0.879,
"rms": 0.68000000000000005,
"gap": 31,
"magType": "mww",
"type": "earthquake",
"title": "M 6.5 - 72km W of Challis, Idaho"
},
"geometry": {
"type": "Point",
"coordinates": [-115.1356, 44.460299999999997, 14.529999999999999]
},
"id": "us70008jr5"
},
{
"type": "Feature",
"properties": {
"mag": 6.0999999999999996,
"place": "27km SW of Baliton, Philippines",
"time": 1585237084150,
"updated": 1585407221588,
"tz": 480,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008ghw",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008ghw&format=geojson",
"felt": 24,
"cdi": 5.7000000000000002,
"mmi": 5.6310000000000002,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 586,
"net": "us",
"code": "70008ghw",
"ids": ",us70008ghw,pt20086000,",
"sources": ",us,pt,",
"types": ",dyfi,geoserve,ground-failure,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 1.5740000000000001,
"rms": 1.3200000000000001,
"gap": 11,
"magType": "mww",
"type": "earthquake",
"title": "M 6.1 - 27km SW of Baliton, Philippines"
},
"geometry": {
"type": "Point",
"coordinates": [125.0531, 5.5753000000000004, 59]
},
"id": "us70008ghw"
},
{
"type": "Feature",
"properties": {
"mag": 7.5,
"place": "221km SSE of Severo-Kuril'sk, Russia",
"time": 1585104560896,
"updated": 1586394371534,
"tz": 660,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008fi4",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008fi4&format=geojson",
"felt": 27,
"cdi": 5.5999999999999996,
"mmi": 5.2460000000000004,
"alert": "green",
"status": "reviewed",
"tsunami": 1,
"sig": 881,
"net": "us",
"code": "70008fi4",
"ids": ",at00q7qai7,pt20085000,us70008fi4,",
"sources": ",at,pt,us,",
"types": ",dyfi,finite-fault,general-text,geoserve,ground-failure,impact-link,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 4.1040000000000001,
"rms": 0.67000000000000004,
"gap": 12,
"magType": "mww",
"type": "earthquake",
"title": "M 7.5 - 221km SSE of Severo-Kuril'sk, Russia"
},
"geometry": {
"type": "Point",
"coordinates": [157.69139999999999, 48.968800000000002, 55.390000000000001]
},
"id": "us70008fi4"
},
{
"type": "Feature",
"properties": {
"mag": 6.0999999999999996,
"place": "Central East Pacific Rise",
"time": 1584916684810,
"updated": 1586121707611,
"tz": -420,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us70008e91",
"detail": "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70008e91&format=geojson",
"felt": null,
"cdi": null,
"mmi": 0,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 572,
"net": "us",
"code": "70008e91",
"ids": ",us70008e91,pt20082002,at00q7m9jj,",
"sources": ",us,pt,at,",
"types": ",geoserve,internal-origin,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 22.978000000000002,
"rms": 0.68000000000000005,
"gap": 53,
"magType": "mww",
"type": "earthquake",
"title": "M 6.1 - Central East Pacific Rise"
},
"geometry": {
"type": "Point",
"coordinates": [-104.95189999999999, -4.6744000000000003, 10]
},
"id": "us70008e91"
}
],
"bbox": [-176.3478, -36.9637, 10, 157.6914, 48.9688, 453.77]
}
三:代码(本文以java web形式展示)
Data.java:(一个javabean)
package earthquake;
public class Data {
private double level;
private String address;
private String date;
private String url;
public Data(double level, String address, String date, String url) {
this.level = level;
this.address = address;
this.date = date;
this.url = url;
}
public double getLevel() {
return level;
}
public void setLevel(double level) {
this.level = level;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
GetEarthQuakeData4s.java:
package earthquake;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.List;
import java.util.logging.Level;
import org.apache.log4j.Logger;
import com.google.gson.Gson;
public class GetEarthData4s {
static Logger logger = Logger.getLogger(GetEarthData4s.class.getName());
public static final String USGS_REQUEST_URL =
"https://earthquake.usgs.gov/fdsnws/event/1/query";
public String getResponse( ){
try {
URL url = new URL(USGS_REQUEST_URL+"?format=geojson&limit=10&minmag=6&orderby=time");
String response = makeHttpRequest(url);
return response;
//System.out.println(response);
} catch (MalformedURLException ex) {
java.util.logging.Logger.getLogger(GetEarthData4s.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
java.util.logging.Logger.getLogger(GetEarthData4s.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
public static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
logger.error( "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
logger.error("Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown.
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
//将字符串转化为一个键值对存入List<Map>
public static List<Data> getData(String json){
List<Data> list = new ArrayList<>();
Gson gson = new Gson();
Map map = gson.fromJson(json, Map.class);
List<Map> features = (List<Map>)map.get("features");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(Map m:features) {
Map propertiesMap = (Map)m.get("properties");
double mag = (Double)propertiesMap.get("mag");
String place = (String)propertiesMap.get("place");
Long time = ((Double)propertiesMap.get("time")).longValue();
String timeStr = sdf.format(new Date(time));
String url = (String)propertiesMap.get("url");
list.add(new Data(mag,place,timeStr,url));
}
return list;
}
}
GetDataServlet.java:(没有使用自动配置Servlet,记得在web.xml中配置)
package servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import earthquake.Data;
import earthquake.GetEarthData4s;
public class GetDataServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
GetEarthData4s gd = new GetEarthData4s();
String str = gd.getResponse().toString();
List<Data> list = gd.getData(str);
System.out.println(str);
request.setAttribute("list", list);
request.getRequestDispatcher("/show.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request,response);
}
}
show.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ page import="earthquake.Data" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>EarthQuake Data</title>
<%
List<Data> list = new ArrayList();
list = (List<Data>)request.getAttribute("list");
%>
</head>
<body>
<h1 align="center">地震数据</h1>
<hr/>
<table border="1" width="80%" align="center">
<tr>
<th>震级</th>
<th>地址</th>
<th>时间</th>
<th>URL</th>
</tr>
<%
for(Data data :list){
%>
<tr align="center">
<td><%=data.getLevel()%></td>
<td><%=data.getAddress()%></td>
<td><%=data.getDate()%></td>
<td><a href="<%=data.getUrl()%>"><%=data.getUrl()%></a></td>
<%
}
%>
</table>
</body>
</html>
四:界面
五:总结
一开始看Gson的教程都是将所有Jason中的属性封装到一个bean中,然后进行对象转换。但是像上面那样属性比较多的时候再写一个个bean就繁琐。幸好老师指点了一下,可以直接使用ArrayList、和Map暂存获取的json对象而不用再一个个去写bean了。
掉坑也要弧线!
上一篇: 历代皇帝都热衷于对外作战,那曹魏政权攻打过哪些民族?
下一篇: Linux的文件权限与目录配置