廖雪峰Java14Java操作XML和JSON-2JSON-2处理JSON

解析JSON

  • JSR 353 API
  • 常用的第三方库
    * Jackson
    * gson
    * fastjson

Jackson:

  • 提供了读写JSON的API
  • JSON和JavaBean可以互相转换
  • 可食用Annotation定制序列化和反序列化

Jackson初步使用

依赖

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.0</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.datatype</groupId>
			<artifactId>jackson-datatype-jsr310</artifactId>
			<version>2.9.0</version>
		</dependency>
package com.feiyangedu.sample.pop3;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class ParseJsonTest {
    public static void main(String[] args) {
        String data = "{"type":2,"range":1,"start":1368417600,"end":1368547140,"
                + ""cityName":"天津","companyIds":["12000001"],"companyNames":["天津"],"
                + ""12000001":{"data":[47947,48328,48573,48520],"
                + ""timestamps":[1368417600,1368417900,1368418200,1368418500]}}";
        String data2 = parseJson(data);
        System.out.println(data2);
    }
    public static String parseJson(String data){
        StringBuffer buffer = new StringBuffer();
        try{
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(data); //读取JSON
            //根据key获取对应的value
            int type = rootNode.path("type").asInt();
            int range = rootNode.path("range").asInt();
            long start = rootNode.path("start").asLong();
            long end = rootNode.path("end").asLong();
            String cityName = rootNode.path("cityName").asText();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
            sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
            String str = "类型(type):"+type+"
"+"范围(range):"+range+"
"+
                    "开始时间(start):"+sdf.format(new Date(start*1000))+"
"+"结束时间(end):"+sdf.format(new Date(end*1000))+"
"+
                    sdf.format(new Date(end*1000))+"
"+"城市名称(cityName):"+cityName;
            buffer.append(str);
            JsonNode companyIds = rootNode.path("companyIds");
            JsonNode companyNames = rootNode.path("companyNames");
            for(int i=0;i<companyIds.size();i++){
                String companyId = companyIds.get(i).asText();
                String companyName = companyNames.get(i).asText();
                JsonNode infoNode = rootNode.path(companyId);
                JsonNode dataNode = infoNode.path("data");
                JsonNode timestampsNode = infoNode.path("timestamps");
                buffer.append("
{
 公司ID(companyId):"+companyId+"
 公司名称(companyName):"+companyName+"
"+"data:");
                for(int j=0;j<dataNode.size();j++){
                    long dataValue = dataNode.get(j).asLong();
                    buffer.append(dataValue+",");
                }
                buffer.append("
 timestamp:");
                for(int k=0;k<timestampsNode.size();k++){
                    long timeValue = timestampsNode.get(k).asLong();
                    buffer.append(sdf.format(new Date(timeValue*1000))+",");
                }
                buffer.append("
}
");
            }
        }catch (JsonProcessingException e){
            e.printStackTrace();;

        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer.toString();
    }
}

使用JavaBean读取JSON

JsonToBean.java

package csj2019;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class JsonToBean {
    //来自豆瓣的API,传入一个关键字,返回符合条件的书籍,结果为JSON格式的字符串
    static final String JSON_URL = "https://api.douban.com/v2/book/search?apikey=0df993c66c0c636e29ecbb5344252a4a&q=";
    //如何把JSON解析为Java对象
    public static void main(String[] args) throws Exception {
        //创建ObjectMapper对象,对mapper设置一些值,通过registerModule注册一个JavaTimeModule,具有序列化和反序列化Java8日期时间的格式
        ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
        //配置DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES为false,自动忽略JavaBean中找不到的属性
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //返回JSON字符串
        String json = search("java");
        //通过readValue把一个JSON字符串反序列化成指定的Java对象,这里的Java对象是SearchResult这个类
        SearchResult result = mapper.readValue(json, SearchResult.class);
        //用mapper对象把JavaBean序列化为JSON并且输出
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result));
    }

    static String search(String q) {
        HttpURLConnection conn = null;
        StringBuilder sb = new StringBuilder(4096);
        try {
            URL url = new URL(JSON_URL + URLEncoder.encode(q, "UTF-8"));
            conn = (HttpURLConnection) url.openConnection();
            if (200 == conn.getResponseCode()) {
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(conn.getInputStream(), "UTF-8"))) {
                    char[] buffer = new char[1024];
                    for (;;) {
                        int n = reader.read(buffer);
                        if (n == (-1)) {
                            break;
                        }
                        sb.append(buffer, 0, n);
                    }
                }
                return sb.toString();
            }
            throw new RuntimeException("Bad response code: " + conn.getResponseCode());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }
}

SearchResult.java

import java.util.List;

public class SearchResult {
    //用SearchResult来表示整个JSON对象,包含count,total,books数组,Book在Book类中
    public long count;
    public long total;

    public List<Book> books;

}

Book.java

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.time.LocalDate;
import java.util.List;

public class Book {
    public String id;
    public String title;
    public String subtitle;
    public List<String> author;

    @JsonSerialize(using = CustomLocalDateSerializer.class) //序列化使用自定义的指定类
    @JsonDeserialize(using = CustomLocalDateDeserializer.class) //反序列化使用自定义的指定类
    public LocalDate pubdate;
    public String url;
    public String price;
}

CustomLocalDateDeserializer.java

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class CustomLocalDateDeserializer extends JsonDeserializer<LocalDate> {
    static DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-M-d",Locale.US);

    @Override
    //覆写deserialize
    public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException,JsonProcessingException {
        //获得原始的String
        String s = p.getValueAsString();
        if(s!=null){
            try{
                //用自己的格式来解析LocalDate对象
                return LocalDate.parse(s,FORMATTER);
            }catch (DateTimeException e){
                //ignore
            }
        }
        return null;
    }
}

CustomLocalDateSerializer.java

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.IOException;
import java.time.LocalDate;

public class CustomLocalDateSerializer extends JsonSerializer<LocalDate> {
    //把自定义的LocalDate对象序列化为一个String对象
    @Override
    public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(value.toString());
    }
}

总结:

Jackson提供了读写JSON的API

  • 实现JSON和JavaBean的互相转换
  • 可使用Annotation定制序列化和反序列化

City.java

public class City {
    private String id;
    private String cityName;
    public City(){};
    public void setId(String id){
        this.id = id;
    }
    public String getId(){
        return id;
    }
    public void setCityName(String cityName){
        this.cityName = cityName;
    }
    public String getCityName(){
        return cityName;
    }
}

Province.java

import java.util.Date;
import java.util.List;

public class Province {
    private Integer id;
    private String name;
    private Date birthDate;
    private List<City> cites;
    public Province(){}

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public List<City> getCites() {
        return cites;
    }

    public void setCites(List<City> cites) {
        this.cites = cites;
    }
}

Country.java

import java.util.*;

public class Country {
    private Integer id;
    private String countryName;
    private Date establishTime;
    private List<Province> provinces;
    private String[] lakes;
    private Map<String,String> forest = new HashMap<String,String>();
    public Country(){}

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCountryName() {
        return countryName;
    }

    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }

    public Date getEstablishTime() {
        return establishTime;
    }

    public void setEstablishTime(Date establishTime) {
        this.establishTime = establishTime;
    }

    public List<Province> getProvinces() {
        return provinces;
    }

    public void setProvinces(List<Province> provinces) {
        this.provinces = provinces;
    }

    public String[] getLakes() {
        return lakes;
    }

    public void setLakes(String[] lakes) {
        this.lakes = lakes;
    }

    public Map<String, String> getForest() {
        return forest;
    }

    public void setForest(Map<String, String> forest) {
        this.forest = forest;
    }
}

Bean2JsonStr


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class Bean2JsonStr {
    public static void main(String[] args) throws ParseException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        mapper.setDateFormat(sdf);

        City city1 = new City();
        city1.setCityName("杭州");
        city1.setId("0571");
        City city2 = new City();
        city2.setCityName("宁波");
        city2.setId("0572");

        Province province = new Province();
        province.setBirthDate(new Date());
        List<City> cities = new ArrayList<City>();
        cities.add(city1);
        cities.add(city2);
        province.setCites(cities);
//        province.setId(1);
        province.setName("浙江");

        Country country = new Country();
        country.setCountryName("中国");
        country.setId(1);
        country.setEstablishTime(sdf.parse("1949-10-01"));
        country.setLakes(new String[]{"青海湖","微山湖","洞庭湖","太湖","鄱阳湖"});
        HashMap<String,String> forests = new HashMap<String,String>();
        forests.put("NO.1","大兴安岭");
        forests.put("NO.2","小兴安岭");
        country.setForest(forests);
        List<Province> provinces = new ArrayList<Province>();
        provinces.add(province);
        country.setProvinces(provinces);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        mapper.writeValue(new File("county.json"),country);
    }
}

Jsonstr2Bean.java

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

public class Jsonstr2Bean {
    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        File jsonFile = new File("county.json");
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        Country country = mapper.readValue(jsonFile,Country.class);
        System.out.println(country.getCountryName()+country.getEstablishTime());
        List<Province> provinces = country.getProvinces();
        for(Province province:provinces){
            System.out.println(province.getName()+"	"+province.getBirthDate());
            for(City city:province.getCites()){
                System.out.println(city.getId()+"	"+city.getCityName());
            }
        }
    }
}
Jsonstr2List.java ```#java import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Jsonstr2List {
public static void main(String[] args) throws JsonProcessingException,IOException {
City city1 = new City();
city1.setId("0571");
city1.setCityName("杭州");
City city2 = new City();
city2.setId("0572");
city2.setCityName("宁波");

    List<City> cites = new ArrayList<City>();
    cites.add(city1);
    cites.add(city2);

    ObjectMapper mapper = new ObjectMapper();
    String listJsonStr = mapper.writeValueAsString(cites);
    System.out.println(listJsonStr);
    List<City> list = mapper.readValue(listJsonStr,new TypeReference<List<City>>(){});
    for(City city:list){
        System.out.println(city.getId()+"	"+city.getCityName());
    }
}

}

<img src="https://img2018.cnblogs.com/blog/1418970/201908/1418970-20190828201936155-1300012672.png" width="500" />


参考:
[https://www.cnblogs.com/williamjie/p/9242932.html](https://www.cnblogs.com/williamjie/p/9242932.html)
[https://www.cnblogs.com/williamjie/p/9242451.html](https://www.cnblogs.com/williamjie/p/9242451.html)
原文地址:https://www.cnblogs.com/csj2018/p/11397742.html