使用Gson解析复杂的Json数据(反序列化)

Gson解析复杂的Json数据(反序列化)

一、准备工作

需要Gson的Jar包:
在这里插入图片描述

二、代码实现

1、复杂的Json数据

{
	"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]
}

2、后端代码实现

这个json可以说是相当的复杂,对象里有数组,数组里有对象,而我们要获得地震的等级、地点、时间、url是在features数组里的properties中的部分数据。
如果我们按照常规的方法用Gson将Json转换为Javabean的对象,我们要创建多个Javabean对象,并且要将Json里的每个数据都要和类里的对象一一对应,在有几百上千条数据的Json里这是不切实际的。比如这个Json就要创建三个Javabean,相当复杂。
在这里插入图片描述
而简便的从Json中拿到我们需要的等级、地点、时间、url,我们可以灵活的运用List<>()、Map(),这里只需要创建一个Javabean代码如下:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.lsq.earth;

/**
 *
 * @author 刘
 */
public class Properties {

    private double mag;

    private String place;

    private String time;

    private String url;

    public Properties(double mag, String place, String time, String url) {
        this.mag = mag;
        this.place = place;
        this.time = time;
        this.url = url;

    }

    public double getMag() {
        return mag;
    }

    public void setMag(double mag) {
        this.mag = mag;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}

使用Gson反序列化Json

 public List<Properties> getProperties() {
        List<Properties> list = new ArrayList<>();
        try {
        //获取json数据,makeHttpRequest()是自己编写的从网络获取Json的方法。
            URL url = new URL(USGS_REQUEST_URL + "?format=geojson&limit=10&minmag=6&orderby=time");
            String response = makeHttpRequest(url);
            //将json反序列化成Map
            Gson gson = new Gson();
            Map map = gson.fromJson(response, Map.class);
            List<Map> features = (List<Map>) map.get("features");
            //设置时间的格式为yyyy-MM-dd HH:mm:ss
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //遍历获取你要的数据,添加到Javabean对象里
            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 Properties(mag, place, timeStr, Url));

            }

        } 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 list;
    }

这样我们就可以简便的从复杂的Json数据里剔除不必要的数据,获取我们想要的数据了。

这里给上如何从网络获取Json数据的代码:

package org.dusin.gson.excises;


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.util.logging.Level;
import org.apache.log4j.Logger;

/**
 *
 * @author dusin
 */
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 static void main(String[] args){
        try {
            URL url = new URL(USGS_REQUEST_URL+"?format=geojson&limit=10&minmag=6&orderby=time");
            String response = makeHttpRequest(url);            
            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);
        }
        
    }
    
    /**
     * 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();
    }

   
}

3、前端代码实现

<%@page import="com.lsq.earth.GetEarthData4s"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="java.util.*"%>
<%@page import="com.lsq.earth.Properties"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <%
            GetEarthData4s earth = new GetEarthData4s();
            List<Properties> list = earth.getProperties();


        %>
        <table align="center" border="1" cellpadding="6">
            <tr>
                <td>震级</td><td>地点</td><td>时间</td><td>url</td>
            </tr>
            <%                for (Properties b : list) {
                    out.println("<tr><td/>" + b.getMag() + "</td><td>" + b.getPlace()
                            + "</td><td>" + b.getTime() + "</td><td><a href=" + b.getUrl() + ">" + b.getUrl()
                            + "</a></td>");
                }
            %>
        </table>

    </body>
</html>

三、效果图

在这里插入图片描述
以后遇到这种复杂的Json,不要再傻傻地去创建多个bean了,我们可以将Json暂存在List、Map中,灵活的运用Gson。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值