zoukankan      html  css  js  c++  java
  • Java 常见数据交换格式——xml、json、yaml

    目录


    数据交换格式介绍

    XML

    使用DOM方式解析

    使用SAX方式解析

    使用DOM4J方式解析

    使用JDOM方式解析

    JSON

    使用JSONObject方式将数据转换为JSON格式

    利用JSONObject对象方式构建JSON

    将map转换为JSON格式

    将JavaBean转换为JSON格式

    使用JSONObjec读取JSON格式数据

    直接读取jsonobject数据

    使用google-gson将数据转换为json格式

    使用gson生成json数据

    使用注解设置json中的key名称

    使用FieldNamingStrategy设置key名称

    设置美化json输出

    使用google-gson解析json数据

    使用fastjson

    使用jackson

    设置javabean属性在转换json时隐藏 

    YAML


    数据交换格式

      每一种编程语言都有不同的数据结构,在多个应用程序之间,如果编写每一个应用程序的编程语言都不同,那么他们的数据是不能直接传递的,需要将他们转换为特定的格式,然后再进行传输,保证发送方和接收方都能正确的读取数据。

      另外,不同操作系统,不同平台之间实现数据共享,也需要将数据转换为两个平台或者操作系统都能读取的格式。

      数据交换格式就是“应用程序间通信时使用的数据格式”,而常见的数据交换格式包括:XML、JSON、YAML。

      下面就是用Java来实现上面这3种格式的操作。

    XML

      xml(eXtensible Markup Language),可扩展标记语言,详细的介绍可以自行查阅。

      一个标准的xml文件内容如下(示例文件名为books.xml):

    <?xml version="1.0" encoding="utf-8"?>
    <books>
    	<book id="one">
    		<name>Java加密与解密的艺术</name>
    		<price>89</price>
    		<language>Chinese</language>
    		<author>梁栋</author>
    	</book>
    	<book id="two">
    		<name>Effective Java</name>
    		<price>59</price>
    		<language>English</language>
    	</book>
    </books>
    

      在xml中,有几个专业术语:

      节点:比如上面的<books>、<book>、<name>、<price>、<language>、<author>;

      节点值:比如"Effective Java" 是< name>节点的值;

      属性:比如<book>节点的id属性;

      属性值:<book>节点的id属性值分别为1、2.

      注意,每一个节点都可以有子节点,比如<books>的子节点有<book>节点,而<book>的子节点包括<name>、<price>、<language>、<author>;

      在使用Java来操作xml的时候,一般就是对于上面这几个内容进行处理,比如获取节点名称和及节点值、节点属性和属性值。Java常用XML解析方式有4种:DOM解析、SAX解析、DOM4J解析、JDOM解析。

      在此之前,需要了解一下节点类型:

      

    使用DOM方式解析

       Java中内置了一些API来使用DOM方式解析xml。不需要另外导入其他jar包。

    package cn.ganlixin.test;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NamedNodeMap;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    public class DOM {
    	public static void main(String[] args) throws Exception {
    		
    		// 创建一个DocumentBuilderFactory的工厂对象
    		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    		
    		// 利用上一步创建的工厂对象来创建一个DocumentBuilder对象
    		DocumentBuilder documentBuilder = factory.newDocumentBuilder();
    		
    		// 利用创建的documentBuilder对象,可以调用parse()来进行解析xml,parse方法有下面四种重载
    		// Document parse(InputStream is)
    		// Document parse(String uri)
    		// Document parse(File f)
    		// Document parse(InputStream is, String systemId)
    		Document document = documentBuilder.parse("books.xml");
    		
    		// 获得xml中的节点,常用的就是下面两种方式,分别是通过tagName和id来获取节点。
    		// NodeList document.getElementsByTagName(String tagname);
    		// Element document.getElementById(String tagId);
    		NodeList bookList = document.getElementsByTagName("book");
    		System.out.println("book节点的个数:" + bookList.getLength());
    		
    		// 遍历所有book节点,解析book节点的信息
    		for (int i = 0; i < bookList.getLength(); i++) {
    			
    			System.out.println("开始解析第 " + (i+1) + " 个book节点");
    			
    			// 获取节点集合中的第i个节点
    			Node book = bookList.item(i); 
    			
    			// 遍历节点的所有属性和属性值
    			NamedNodeMap attributes = book.getAttributes();
    			
    			// 获取属性属性的数量
    			System.out.println("	该节点有 " + attributes.getLength() + " 个属性");
    
    			// 遍历节点的所有属性信息
    			for (int j = 0; j < attributes.getLength(); j++) {
    				
    				// 获取属性,注意属性也是一种节点(Node)
    				Node attr = attributes.item(j); 
    				
    				// 获取属性名
    				String attributeName = attr.getNodeName();
    				
    				// 获取属性值
    				String attributeValue = attr.getNodeValue();
    				
    				// 获取节点类型,其中1表示Element,2表示attr,3表示text。
    				short nodeType = attr.getNodeType();
    				
    				System.out.println("	节点类型为" + nodeType + ", 属性 " + attributeName + "=" + attributeValue );
    			}
    			
    			// 可以直接获取节点指定属性名的值,需要将Node类型转换为Element类型
    			Element element = (Element)book;
    			System.out.println("	直接获取id的属性值 : " + element.getAttribute("id"));
    			
    			// 获取子节点,注意,两个节点之间的也是一个节点(Text节点)
    			NodeList bookChildList = book.getChildNodes();
    			System.out.println("该book节点一共有 " + bookChildList.getLength() + " 个子节点");
    			
    			// 遍历所有子节点,打印子节点的信息
    			for (int j = 0; j < bookChildList.getLength(); j++) {
    				Node childNode = bookChildList.item(j);
    				
    				// 只获取element类型的节点
    				if (childNode.getNodeType() == Node.ELEMENT_NODE) {
    					
    					// 获取子节点的名称
    					String nodeName = childNode.getNodeName();
    					
    					// 获取子节点标签之间的内容(值)
    					String nodeValue = childNode.getFirstChild().getNodeValue();
    					
    					// 如果一个标签内只有内容,没有其他标签的时候,可以使用下面这种方式获取节点内容
    					//String nodeValue = childNode.getTextContent();
    					
    					System.out.println("	" + nodeName + "=" + nodeValue);
    				}
    			}
    			
    			System.out.println("------------------------------------------------------
    ");
    		}
    	}
    
    }
    

      运行结果:

    book节点的个数:2
    开始解析第 1 个book节点
    	该节点有 1 个属性
    	节点类型为2, 属性 id=one
    	直接获取id的属性值 : one
    该book节点一共有 9 个子节点
    	name=Java加密与解密的艺术
    	price=89
    	language=Chinese
    	author=梁栋
    ------------------------------------------------------
    
    开始解析第 2 个book节点
    	该节点有 1 个属性
    	节点类型为2, 属性 id=two
    	直接获取id的属性值 : two
    该book节点一共有 7 个子节点
    	name=Effective Java
    	price=59
    	language=English
    ------------------------------------------------------
    

      需要注意,使用DOM方式解析xml时,需要将整个xml文件都加载进内存,再进行解析。

      其次,dom方式解析和我们在前端JavaScript DOM编程的方式很相似,可以参考JavaScript DOM编程艺术。

    使用SAX方式解析

      SAX方式和DOM方式有一个明显的区别:SAX方式是从上往下逐个解析的。

      Java内置了使用SAX方式解析xml的API,所以不需要导入其他jar包。

      使用SAX方式的解析xml,需要我们自己定义一个Handler(一个class),继承DefaultHandler,自己定义怎么去解析xml中的节点。

      定义handler

    package cn.ganlixin.test;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    /**
     * 自定义的handler
     */
    public class MySAXHandler extends DefaultHandler {
    
    	/**
    	 * 当开始解析xml的根目录时被调用(第一句xml文件声明)
    	 */
    	@Override
    	public void startDocument() throws SAXException {
    		// TODO Auto-generated method stub
    		super.startDocument();
    		System.out.println("开始解析");
    	}
    	
    	/**
    	 * 解析元素的开始标签,比如<name>abc</name>的<name>标签
    	 * 对于每一个元素都会调用该方法
    	 */
    	@Override
    	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    		// qName 就是元素的标签名,比如<name>,就是name
    		// attributes就是<name>标签中的属性集合
    		if (qName.equals("book")) {
    			
    			// 直接获取book标签的id属性值
    			String id = attributes.getValue("id");
    			System.out.println("book标签的id属性值为 " + id);
    			
    			// 获取book标签的所有属性,并遍历
    			int attrNum = attributes.getLength();
    			for (int i = 0; i < attrNum; i++) {
    				String attrName = attributes.getQName(i);
    				System.out.println("第 " + (i+1) + " 个属性--> " + attrName + "="+ attributes.getValue(i));
    			}
    			
    		} else if (!qName.equals("books") && !qName.equals("book")) {
    			// 如果不是books标签,也不是book标签,则证明是book的字标签,直接输出即可
    			System.out.print("解析" + qName + "元素, 节点值为 :");
    		}
    	}
    	
    	/**
    	 * 解析标签的文本内容,比如<name>abc</name>元素的abc
    	 * 每次startElement调用结束后都会自动调用该方法
    	 */
    	@Override
    	public void characters(char[] ch, int start, int length) throws SAXException {
    		// ch字符数组包含了整个xml文件内容,通过start和length两个参数来确定数据段。
    		String text = new String(ch,start, length);
    		if (!text.trim().equals("")) {
    			System.out.println(text);
    		}
    	}
    	
    	/**
    	 * 解析元素的结束标签,比如<name>abc</name>的</name>标签
    	 * 对于每一个元素都会调用该方法
    	 */
    	@Override
    	public void endElement(String uri, String localName, String qName) throws SAXException {
    		// TODO Auto-generated method stub
    		super.endElement(uri, localName, qName);
    	}
    	
    	/**
    	 * 当整个xml解析完毕时被调用
    	 */
    	@Override
    	public void endDocument() throws SAXException {
    		// TODO Auto-generated method stub
    		super.endDocument();
    		System.out.println("end");
    	}
    }
    

      

       编写测试类

    package cn.ganlixin.test;
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    public class SAX {
    	
    	public static void main(String[] args) throws Exception {
    		
    		// 利用SAXParserFactory创建SAXParserFactory的工厂对象
    		SAXParserFactory factory = SAXParserFactory.newInstance();
    		
    		// 获取parser对象
    		SAXParser parser = factory.newSAXParser();
    		
    		// 创建一个Handler对象(我们自己定义的那个handler)
    		MySAXHandler handler = new MySAXHandler();
    		
    		// 传入xml文件路径,并指定handler
    		// xml的路径可以是File f、InputStream is、String uri
    		parser.parse("books.xml", handler);
    	}
    
    }
    

      

      运行结果:

    开始解析
    book标签的id属性值为 one
    第 1 个属性--> id=one
    解析name元素, 节点值为 :Java加密与解密的艺术
    解析price元素, 节点值为 :89
    解析language元素, 节点值为 :Chinese
    解析author元素, 节点值为 :梁栋
    book标签的id属性值为 two
    第 1 个属性--> id=two
    解析name元素, 节点值为 :Effective Java
    解析price元素, 节点值为 :59
    解析language元素, 节点值为 :English
    end
    

       

    使用DOM4J方式解析

    使用JDOM方式解析

    JSON

      json的格式就不在探讨了,可以参考:http://json.org/json-zh.html

      这里介绍几种构造json的方式:

    使用JSONObject方式将数据转换为JSON格式

      使用JSONObject,可以将jsonobject对象、map集合、javabean对象中的数据转换为json格式。转换为json格式之后就可以进行传输了。

    使用JSONObject方式构建JSON

      这种方式需要引入json-java的依赖;

      github地址为:https://github.com/stleary/JSON-java

      官方文档地址:http://stleary.github.io/JSON-java/index.html

      jar包的下载地址:http://central.maven.org/maven2/org/json/json/20180813/json-20180813.jar

      如果使用maven可以自己根据上面的jar包下载地址设置依赖。

    package cn.ganlixin.test;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    public class UseJSONObject {
    	
    	public static void main(String[] args) {
    		
    		List<String> subjects = new ArrayList<>();
    		subjects.add("math");
    		subjects.add("chinese");
    		subjects.add("english");
    		
    		Map<String, Integer> score = new HashMap<>();
    		score.put("math", 99);
    		score.put("chinese", 100);
    		score.put("english", 59);
    		
    		// 创建JSONObject对象,用来存放json数据
    		JSONObject json = new JSONObject();
    		
    		json.put("name", "张三");
    		json.put("age", 99);
    		json.put("wage", 9999.99);
    		json.put("isMan", true);
    		json.put("subjects", subjects);
    		json.put("score", score);
    		
    		System.out.println(json.toString());
    		/*
    		{
    			"score":{
    				"english":59,
    				"chinese":100,
    				"math":99
    			},
    			"subjects":[
    				"math",
    				"chinese",
    				"english"
    			],
    			"name":"张三",
    			"isMan":true,
    			"age":99,
    			"wage":9999.99
    		}
    		*/
    	}
    }
    

      

    利用JSONObject将map转换为JSON格式

      这种方式,就是先创建一个map,然后向map中put键和值,然后将map作为JSONObject构造方法的参数,然后得到的JSONObject对象就是包含了map数据的json。最后调动toString接口输出json。

    package cn.ganlixin.test;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    public class UseJSONObject {
    	
    	public static void main(String[] args) {
    		
    		List<String> subjects = new ArrayList<>();
    		subjects.add("math");
    		subjects.add("chinese");
    		subjects.add("english");
    		
    		Map<String, Integer> score = new HashMap<>();
    		score.put("math", 99);
    		score.put("chinese", 100);
    		score.put("english", 59);
    		
    		// 创建一个HashMap
    		Map<Object, Object> map = new HashMap<>();
    		
    		map.put("name", "张三");
    		map.put("age", 99);
    		map.put("wage", 9999.99);
    		map.put("isMan", true);
    		map.put("subjects", subjects);
    		map.put("score", score);
    		
    		// 将map作为JSONObject的构造参数传入
    		JSONObject json = new JSONObject(map);
    		System.out.println(json.toString());
    	}
    }
    

      运行结果和上一个代码的运行结果一样。

    利用JSONObject将JavaBean转换为JSON格式

       利用JavaBean来创建json,先创建一个javabean:

    package cn.ganlixin.pojo;
    
    import java.util.List;
    import java.util.Map;
    
    public class Person {
    
    	private String name;
    	private int age;
    	private double wage;
    	private boolean gender;
    	private List<String> subjects;
    	private Map<String, Integer> score;
    	
    	// 生成有参构造方法、无参构造方法、getter、setter、toString	
    }
    

      

      测试代码:

    package cn.ganlixin.test;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    import cn.ganlixin.pojo.Person;
    
    public class UseJSONObject {
    	
    	public static void main(String[] args) {
    		
    		List<String> subjects = new ArrayList<>();
    		subjects.add("math");
    		subjects.add("chinese");
    		subjects.add("english");
    		
    		Map<String, Integer> score = new HashMap<>();
    		score.put("math", 99);
    		score.put("chinese", 100);
    		score.put("english", 59);
    		
    		Person person = new Person(); // 创建javabean对象
    		
    		person.setName("张三");
    		person.setAge(99);
    		person.setWage(99999.98);
    		person.setGender(true);
    		person.setSubjects(subjects);
    		person.setScore(score);
    		
    		// 将javabean对象传入构造方法,获得jsonobject
    		JSONObject json = new JSONObject(person);
    		
    		System.out.println(json.toString());
    	}
    }
    

      运行结果和前面的结果一样。  

    使用JSONObjec读取JSON格式数据

      当我们在程序中接收到其他地方传过来的json格式数据的时候,可以使用JSONObject去读取数据中的内容。

      json数据可以是别的应用程序传输过来的,也可以是本地生成的,或者是存储在文件中,无论什么样的方式,都可以将其转换为同一个的格式进行处理。

    直接读取jsonobject数据

      这里为了测试,在项目根目录创建一个文件:person.json,内容为:

    {
        "score": {
            "english": 59,
            "chinese": 100,
            "math": 99
        },
        "subjects": [
            "math",
            "chinese",
            "english"
        ],
        "name": "张三",
        "gender": true,
        "age": 99,
        "wage": 9999.99,
        "demo": null
    }
    

      

      编写解析程序

    package cn.ganlixin.test;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    
    import org.json.JSONArray;
    import org.json.JSONObject;
    
    /**
     * 解析json格式的数据
     */
    public class resolveJSON {
    	
    	public static void main(String[] args) throws IOException {
    		
    		// 这里的json数据来源是文件中,首先需要将文件中的json内容读出,保存到字符串中(可以使用commons-io完成)
    		Reader reader = new FileReader("person.json");
    		char[] data = new char[1024*1024];
    		int length = reader.read(data);
    		String jsonStr = new String(data, 0, length);
    		
    		// 将json格式的字符串作为JSONObjec构造方法的参数,获取的就是解析后的json对象。
    		JSONObject json = new JSONObject(jsonStr);
    		
    		// 根据json中的key和value的类型,调用不同的方法获取json中的数据
    		String name = json.getString("name"); // 张三
    		int age = json.getInt("age");
    		boolean gender = json.getBoolean("gender");
    		double wage = json.getDouble("wage");
    		
    		// 对于json中的数组类型,使用getJSONArray("key")
    		JSONArray subjects = json.getJSONArray("subjects");
    		for (int i = 0; i < subjects.length(); i++) {
    			// 获取数组中的第i个元素
    			Object item = subjects.get(i);
    			System.out.println((String)item);
    		}
    		
    		// 对于value是map类型或者object类型,使用getJSONObject("key")
    		JSONObject score = json.getJSONObject("score");
    		System.out.println(score.getInt("math"));
    		System.out.println(score.getInt("chinese"));
    		System.out.println(score.getInt("english"));
    		
    		// json中key对应的value为null的情况,如果仍旧对其进行getXxx("key"),则会报错,需要先判断一下是否为空,再获取
    		if (! json.isNull("demo")) {
    			System.out.println("demo的值为 " + json.getString("demo"));
    		} else {
    			System.out.println("demo的值为null");
    		}	
    	}
    }
    

      

    使用google-gson

      google-gson是google开源的一个json库,github地址:https://github.com/google/gson

      使用maven的话,可以在pom.xml中添加如下依赖:

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.8.5</version>
    </dependency>
    

      如果是使用jar包,可以访问:https://search.maven.org/artifact/com.google.code.gson/gson/2.8.5/jar

      

    使用gson生成json数据

    package cn.ganlixin.test;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.json.JSONObject;
    
    import com.google.gson.Gson;
    
    import cn.ganlixin.pojo.Person;
    
    public class GSONTest {
    	
    	public static void main(String[] args) {
    		
    		List<String> subjects = new ArrayList<>();
    		subjects.add("math");
    		subjects.add("chinese");
    		subjects.add("english");
    		
    		Map<String, Integer> score = new HashMap<>();
    		score.put("math", 99);
    		score.put("chinese", 100);
    		score.put("english", 59);
    		
    		// 创建一个对象
    		Person person = new Person();
    		
    		person.setName("张三");
    		person.setAge(99);
    		person.setWage(99999.98);
    		person.setGender(true);
    		person.setSubjects(subjects);
    		person.setScore(score);
    		
    		// 创建gson对象
    		Gson gson = new Gson();
    		
    		// 将对象转换为json字符串
    		String jsonStr = gson.toJson(person);
    		
    		System.out.println(jsonStr);
    		/* 手动缩进后输出json数据如下
    		{
    			"name":"张三",
    			"age":99,
    			"wage":99999.98,
    			"gender":true,
    			"subjects":[
    				"math",
    				"chinese",
    				"english"
    			],
    			"score":{
    				"chinese":100,
    				"english":59,
    				"math":99
    			}
    		}
    		 */
    	}
    
    }
    

      

    设置json中的key值

      上面使用gson将一个person对象转换为json时,注意,json中的key都是和person对象中的属性名相同的。如果遇到一些情况,我们的类中的属性名,不是和json中的key相同,那么需要使用一个@Ser注解。

      比如修改Person.class的定义:

    package cn.ganlixin.pojo;
    
    import java.util.List;
    import java.util.Map;
    
    import com.google.gson.annotations.SerializedName;
    
    public class Person {
    
    	// 使用SerializdName注解来设置gson转换为json时的key名称,不适用注解,默认是使用属性名
    	@SerializedName("Name111")
    	private String name;
    	
    	@SerializedName("Age")
    	private int age;
    	private double wage;
    	private boolean gender;
    	private List<String> subjects;
    	private Map<String, Integer> score;
    	
    	// 生成有参构造方法、无参构造方法、getter、setter、toString
    }
    

      在上面gson将person转换为json的代码,缩进之后输出如下:

    {
    	"Name111":"张三",
    	"Age":99,
    	"wage":99999.98,
    	"gender":true,
    	"subjects":[
    		"math",
    		"chinese",
    		"english"
    	],
    	"score":{
    		"chinese":100,
    		"english":59,
    		"math":99
    	}
    }
    

      

    使用FieldNamingStrategy设置key名称

      上面的除了使用注解来实现设置json中属性对应的key值,另外,还可以使用gson提供的fieldNamingStrategy来设置json中key的名称。

    package cn.ganlixin.test;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.google.gson.FieldNamingStrategy;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    import cn.ganlixin.pojo.Person;
    
    public class GSONTest {
    	
    	public static void main(String[] args) {
    		
    		List<String> subjects = new ArrayList<>();
    		subjects.add("math");
    		subjects.add("chinese");
    		subjects.add("english");
    		
    		Map<String, Integer> score = new HashMap<>();
    		score.put("math", 99);
    		score.put("chinese", 100);
    		score.put("english", 59);
    		
    		// 创建一个对象
    		Person person = new Person();
    		
    		person.setName("张三");
    		person.setAge(99);
    		person.setWage(99999.98);
    		person.setGender(true);
    		person.setSubjects(subjects);
    		person.setScore(score);
    		
    		// 创建一个gsonBuilder
    		GsonBuilder gsonBuilder = new GsonBuilder();
    		
    		// 设置打印的时候进行美化输出
    		gsonBuilder.setPrettyPrinting();
    		
    		// 设置json中的key名称策略
    		gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {
    			@Override
    			public String translateName(Field field) { 
    				
    				// 如果是key为name,那么json中的key就是NAME,其余key名称不变。
    				// 注意,不要使用@SerializedName注解
    				if (field.getName().equals("name")) {
    					return "NAME";
    				} else {
    					return field.getName();
    				}
    			}
    		});
    		
    		/*
    		 * 使用Lambda表达式可以写为
    		gsonBuilder.setFieldNamingStrategy( (Field field) -> {
    			if (field.getName().equals("name")) {
    				return "NAME";
    			} else {
    				return field.getName();
    			}
    		});
    		*/
    		
    		// 获取gson对象
    		Gson gson = gsonBuilder.create();
    		String jsonStr = gson.toJson(person);
    		
    		System.out.println(jsonStr);
    	}
    }
    

       

    设置美化json后输出

      前面的输出json内容都是经过手动缩进的,如果没有手动缩进,那么内容就是一个很长的字符串。

      我们在调试的时候,一般都是会将json美化后输出,因为便于阅读,但在实际的生产环境中一般不会将json美化后传送。

      虽然有很多的json格式化工具,但是gson中提供了接口,可以将json进行美化后输出(不用自己手动缩进了)

    package cn.ganlixin.test;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    import cn.ganlixin.pojo.Person;
    
    public class GSONTest {
    	
    	public static void main(String[] args) {
    		
    		List<String> subjects = new ArrayList<>();
    		subjects.add("math");
    		subjects.add("chinese");
    		subjects.add("english");
    		
    		Map<String, Integer> score = new HashMap<>();
    		score.put("math", 99);
    		score.put("chinese", 100);
    		score.put("english", 59);
    		
    		// 创建一个对象
    		Person person = new Person();
    		
    		person.setName("张三");
    		person.setAge(99);
    		person.setWage(99999.98);
    		person.setGender(true);
    		person.setSubjects(subjects);
    		person.setScore(score);
    		
    		// 创建一个gsonBuilder
    		GsonBuilder gsonBuilder = new GsonBuilder();
    		
    		// 设置打印的时候进行美化输出
    		gsonBuilder.setPrettyPrinting();
    		
    		// 获取gson对象
    		Gson gson = gsonBuilder.create();
    		String jsonStr = gson.toJson(person);
    		
    		System.out.println(jsonStr); // 打印的json字符串就是经过美化后的json串
    	}
    }
    

      

    使用google-gson解析json数据

      前面介绍了使用gson将javabean对象转换为json格式,通过使用gson还能将json格式的数据转换为javabean对象,并且,使用gson比是用JSONObject更加方便。

    package cn.ganlixin.test;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.Reader;
    
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    import cn.ganlixin.pojo.Person;
    
    public class GSONTest {
    	
    	public static void main(String[] args) throws FileNotFoundException {
    		
    		// 创建gsonBuilder
    		GsonBuilder gsonBuilder = new GsonBuilder();
    		
    		// 在创建gson对象之前,可以进行一些设置,包括json中key的名称策略、时间格式等
    		gsonBuilder.setDateFormat("yyyy-MM-dd");
    		
    		// 创建gson对象
    		Gson gson = gsonBuilder.create();
    		
    		// 调用下面两个接口,可以将json转换为对应的javabean
    		// gson.fromJson(Reader json, Class<T> type)
    		// gson.fromJson(String json, class<T> type)
    		
    		// 指定json所在的文件名
    		Reader reader = new FileReader("person.json");
    		
    		// 解析json
    		Person person = gson.fromJson(reader, Person.class);
    		
    		System.out.println(person);
    	}
    }
    

      

     设置javabean属性在转换json时隐藏

      有些时候,我们一个类中的某个属性,不允许暴露给外界,但是前面的集中做法中,都是将所有的属性暴露给了外界,这是存在安全隐患的,在对象序列化的时候,也会存在这个问题,他们的解决方式相同,都是在属性的前面增加一个transient关键字,比如Person中的wage属性在序列化或者转换为json时,不允许暴露给外籍,可以这样声明wage属性:

    private transient double wage;
    

      

    使用FastJSON

      fastjson是alibaba开源的一个项目,也是用来处理json的。他的用法和其他几种方式相似,这里只介绍一下常用的API。

    package cn.ganlixin.test;
    
    import com.alibaba.fastjson.JSON;
    
    import cn.ganlixin.pojo.Person;
    
    public class TestFastJson1 {
    	public static void main(String[] args) {
    		
    		// 将对象转换为json格式
    		// String com.alibaba.fastjson.JSON.toJSONString(Object object)
    		// String com.alibaba.fastjson.JSON.toJSONString(Object object, boolean prettyFormat)
    		String jsonStr = JSON.toJSONString(new Person(), true);
    		
    		// 将json数据转化为对象
    		// T com.alibaba.fastjson.JSON.parseObject(String text, Class<T> clazz)
    		Person person = JSON.parseObject(jsonStr, Person.class);
    	}
    }
    

      

    使用Jackson

    package cn.ganlixin.test;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import cn.ganlixin.pojo.Person;
    
    public class TestJackson {
    	public static void main(String[] args) throws Exception {
    		// 将对象转换为json格式
    		ObjectMapper mapper = new ObjectMapper();
    		// 有以下几种API
    		// void mapper.writeValue(File resultFile, value);
    		// void mapper.writeValue(OutputStream out, Object value);
    		// void mapper.writeValue(Writer w, Object value);
    		// byte[] mapper.writeValueAsBytes(Object value);
    		// String mapper.writeValueAsString(Object obj);
    		String jsonStr = mapper.writeValueAsString(new Person());
    		
    		// 将json数据转换为对象
    		// readValue(src, Class<Person> valueType)
    		// src可以是各种类型包括byte[]、inputstream、str、File、reader、url
    		Person person = mapper.readValue(jsonStr, Person.class);
    	}
    
    }
    

      

      

    yaml

  • 相关阅读:
    Android Handler主线程和一般线程通信的应用分析
    在java中string为什么要设计成final的
    Java中有几种创建对象的方式
    String和StringBuilder、StringBuffer的区别
    正确的二分查找实现
    SSH编写程序中文乱码解决
    lamda表达式
    kmp算法核心代码
    简洁清晰的quicksort核心代码
    [趣题]生成多个质数的幂积序列
  • 原文地址:https://www.cnblogs.com/-beyond/p/10574935.html
Copyright © 2011-2022 走看看