欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Gson解析含有集合、数组嵌套的json数据(反序列化)

程序员文章站 2022-05-11 19:53:43
...

一:准备工作

  1. Gson包
  2. 下面有使用到了logging日志导入下面几个库包

使用Gson解析含有集合、数组嵌套的json数据(反序列化)

二: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解析含有集合、数组嵌套的json数据(反序列化)

 

 五:总结

一开始看Gson的教程都是将所有Jason中的属性封装到一个bean中,然后进行对象转换。但是像上面那样属性比较多的时候再写一个个bean就繁琐。幸好老师指点了一下,可以直接使用ArrayList、和Map暂存获取的json对象而不用再一个个去写bean了。

 


 掉坑也要弧线!

相关标签: 数据格式解析