文章目录

  • 1. 数据格式引入
  • 2. XML数据格式简介
  • 格式简介
  • 特点
  • 3. 解析XML数据的方法
  • 2.1 DOM方式解析
  • 特点
  • 步骤
  • 代码
  • 2.2 SAX方式解析
  • 步骤
  • 代码
  • 2.3 Pull方式解析
  • PULL方式解析XML基本处理方式:
  • 代码
  • 4. JSON数据格式简介
  • JSON基本的结构两种
  • JSON 表示名称/ 值对的方式
  • JSON 表示数组的方式:
  • XML和JSON的比较
  • 5. 解析JSON数据的方法
  • 下面用到的自定义的类
  • Grade
  • Student
  • StudentInfo
  • 代码1 把普通Java对象转换成Json字符串
  • 代码2:把普通Json串转换成对象
  • 代码3:把嵌套Json串转对象
  • 代码4:把嵌套对象转Json串
  • 代码5:将指定的JSON串传输给服务端(流形式)



掌握Android中XML文件的解析方法
掌握Android中JSON文件的解析方法

1. 数据格式引入

服务器与客户端通讯,或者不同语言间数据传递与交互的情况
人们就总结出了统一的数据格式来传递数据,这就是数据格式或叫做数据交换格式。

常见的格式有:XML,JSON;


2. XML数据格式简介

XML:可扩展标记语言(Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

XML是标准通用标记语言(SGML) 的子集,非常适合Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

XML和HTML或其他语言最大的区别是:XML是用来存储数据的

xml可以一定程度上认为是键值对的信息。
xml格式的要求很严格。

格式简介

  1. 起始标签都必须有结束标签。
  2. 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签。
  3. 所有的属性都必须有值。
  4. 所有的属性都必须在值的周围加上双引号。
<?xml version="1.0" encoding="utf-8"?>   版本,编码,命名空间
<students>
	<student>
		<name sex="man">小明</name>
		<nickname>明明</nickname>
	</student>
	<student>
		<name sex="woman">小红</name>
		<nickname>红红</nickname>
	</student>
</students>

特点

  1. XML 被设计用来结构化存储以及传输信息。
  2. XML 仅仅是纯文本。
  3. XML 可自定义标签。
  4. XML 和HTML 不可相互替代。
  5. XML 是W3C 的推荐标准。
  6. XML 无所不在。

3. 解析XML数据的方法

2.1 DOM方式解析

特点
  1. 先把XML文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。
  2. 一次全部加载,如果对于数据量小的情况下,它的效率还可以,如果XML文件很大的情况下,速度就会慢起来
  3. 直接把文档调入内存中,比较耗内存。
步骤
  1. 首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例;
  2. 然后利用DocumentBuilderFactory创建DocumentBuilder;
  3. 然后加载XML文档(Document);
  4. 然后获取文档的根结点(Element);
  5. 然后获取根结点中所有子节点的列表(NodeList);
  6. 然后再获取子节点列表中的需要读取的结点。
代码

在工程目录下,data-data-项目名-files下导入准备好的xml文件。(没有files的话就创建一个)

student.xml文件内容是:
<?xml version="1.0" encoding="utf-8"?>
<students>
    <student>
        <name sex="男">张三</name>
        <age>20</age>
    </student>
    <student>
        <name sex="女">安迪</name>
        <age>19</age>
    </student>
</students>

android 用户向导 android 用户数据_android 用户向导

java代码

public class MainActivity extends AppCompatActivity {
    private Button btnDom;
    private TextView tvDom;
    private Button btnSax;
    private TextView tvSax;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViews();
        setListener();
    }

    private void findViews() {
        btnDom = findViewById(R.id.btn_dom);
        tvDom = findViewById(R.id.tv_dom);
        btnSax = findViewById(R.id.btn_sax);
        tvSax = findViewById(R.id.tv_sax);
    }

    private void setListener() {
        MyClickListener listener = new MyClickListener();
        btnDom.setOnClickListener(listener);
        btnSax.setOnClickListener(listener);
    }

    class MyClickListener implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            // 获取待解析文件的路径
            String file =getFilesDir().getAbsolutePath() + "/students.xml";
            switch (view.getId()) {
                case R.id.btn_dom:
                    //使用DOM方式解析项目根目录下files文件夹中的xml文件
                    analyzeXmlByDOM(file);
                    break;
            }
        }
    }

//采用DOM方式解析XML文件

    private void analyzeXmlByDOM(String file) {
        try {
            //1. 获取xml解析构建工厂对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //2. 创建XML解析的构建器
            DocumentBuilder builder = factory.newDocumentBuilder();
            //3. 将待解析的XML文件加载成Document
            Document document = builder.parse(new File(file));
            //4. 深度优先搜索方式解析DOM中的每个节点
            NodeList nodes = document.getElementsByTagName("student");
            //遍历获取到的节点集合
            //定义用于存储所有学生的集合对象
            List<Student> list = new ArrayList<>();
            for(int i = 0; i < nodes.getLength(); i++){
                //定义用于存储单个学生信息的Student
                Student student = new Student();
                Node node = nodes.item(i);//student节点
                NodeList childNodes = node.getChildNodes();
                //遍历子节点,获取所有子节点的值
                for(int j = 0; j < childNodes.getLength(); j++){
                    //获取当前的节点
                    Node childNode = childNodes.item(j);
                    //得到当前节点名称,并判断获取到的节点名称
                    String nodeName = childNode.getNodeName();
                    switch (nodeName){
                        case "name"://获取属性值、节点值
                            String name = childNode.getTextContent();
                            //获取属性
                            NamedNodeMap attrs = childNode.getAttributes();
                            //获取sex属性值
                            String sex = attrs.item(0).getTextContent();
                            student.setName(name);
                            student.setSex(sex);
                            break;
                        case "age":
                            //获取age节点的值
                            String content = childNode.getTextContent();
                            int age = Integer.parseInt(content);
                            student.setAge(age);
                            break;
                    }
                }
                list.add(student);
            }
            //把解析出来的内容显示在文本框
            tvDom.setText("DOM解析结果:" + list.toString());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Student类
package com.example.a20201002myxml;

public class Student {
    private String name;
    private String sex;
    private int age;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

2.2 SAX方式解析

SAX即是:Simple API for XML。

SAX是基于事件驱动的。当然Android的事件机制是基于回调函数的,在用SAX解析XML文档的时候,当读取到文档开始或结束标签的时候都会回调一个事件,在读取到其它节点与内容的时候也会回调一个事件,一个字符一个字符的边加载边解析,遇到特殊标号触发特殊事件 ** ( ̄︶ ̄) ↗ **

事件源:
org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。

事件处理器:
org.xml.sax包中ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口。

XML Reader通过相应的事件处理器注册方法setXX()来完成与这4个接口的连接

android 用户向导 android 用户数据_android 用户向导_02

但是无需都实现这4个接口,SDK为我们提供了DefaultHandler类来处理,DefaultHandler类的一些主要事件回调方法如下:

android 用户向导 android 用户数据_JSON_03

步骤

使用SAX方式解析XML需要XMLReader以及DefaultHandler来配合,

  1. 创建SAXParserFactory对象。
  2. 根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器。
  3. 根据SAXParser解析器获取事件源对象XMLReader。
  4. 实例化一个DefaultHandler对象。
  5. 连接事件源对象XMLReader到事件处理类DefaultHandler。
  6. 调用XMLReader的parse方法从输入源中获取xml数据。
  7. 通过DefaultHandler返回我们需要的数据集合。
代码
package com.example.a20201002myxml;

import android.widget.TextView;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;
import java.util.List;

public class MySaxHander extends DefaultHandler {
    private List<Student> list;
    private String content;//用于存储节点值
    private Student student;
    private TextView tvSax;


    public MySaxHander(TextView tvSax) {
        this.tvSax = tvSax;
    } 

    public MySaxHander() {
    }
    /**
     * 开始解析文档,通过做一些初始化逻辑操作
     * @throws SAXException
     */
    @Override//开始解析文档,常用于初始化
    public void startDocument() throws SAXException {
        super.startDocument();
        list = new ArrayList<>();
    }




    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        switch (qName){
            case "student":
                //初始化Student对象
                student = new Student();
                break;
            case "name":
                //获取到该标签的属性值
                String sex = attributes.getValue("sex");
                student.setSex(sex);
                break;
        }
    }



    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        content = new String(ch, start, length);
    }




    @Override   //节点是qname
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        switch (qName){
            case "name":
                student.setName(content);
                content = "";
                break;
            case "age":
                int age = Integer.parseInt(content);
                student.setAge(age);
                content = "";
                break;
            case "student":
                list.add(student);
                content = "";
                break;
        }
    }




    /**
     * 文件解析结束前调用,通常执行一些收尾工作
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        //显示解析的结果
        tvSax.setText("SAX解析结果:" + list.toString());
    }




}
public class MainActivity extends AppCompatActivity {
    private Button btnDom;
    private TextView tvDom;
    private Button btnSax;
    private TextView tvSax;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViews();
        setListener();
    }

    private void findViews() {
        btnDom = findViewById(R.id.btn_dom);
        tvDom = findViewById(R.id.tv_dom);
        btnSax = findViewById(R.id.btn_sax);
        tvSax = findViewById(R.id.tv_sax);
    }

    private void setListener() {
        MyClickListener listener = new MyClickListener();
        btnDom.setOnClickListener(listener);
        btnSax.setOnClickListener(listener);
    }

    class MyClickListener implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            // 获取待解析文件的路径
            String file =getFilesDir().getAbsolutePath() + "/students.xml";
            switch (view.getId()) {
                case R.id.btn_sax:
                    //使用SAX方式解析XML文件
                    analyzeXmlBySAX(file);
                    break;
            }
        }
    }
//-------------------------------------------------------------------------------------------------

     * 采用DOM方式解析XML文件

    private void analyzeXmlByDOM(String file) {
        try {
            //1. 获取xml解析构建工厂对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //2. 创建XML解析的构建器
            DocumentBuilder builder = factory.newDocumentBuilder();
            //3. 将待解析的XML文件加载成Document
            Document document = builder.parse(new File(file));
            //4. 深度优先搜索方式解析DOM中的每个节点
            NodeList nodes = document.getElementsByTagName("student");
            //遍历获取到的节点集合
            //定义用于存储所有学生的集合对象
            List<Student> list = new ArrayList<>();
            for(int i = 0; i < nodes.getLength(); i++){
                //定义用于存储单个学生信息的Student
                Student student = new Student();
                Node node = nodes.item(i);//student节点
                NodeList childNodes = node.getChildNodes();
                //遍历子节点,获取所有子节点的值
                for(int j = 0; j < childNodes.getLength(); j++){
                    //获取当前的节点
                    Node childNode = childNodes.item(j);
                    //得到当前节点名称,并判断获取到的节点名称
                    String nodeName = childNode.getNodeName();
                    switch (nodeName){
                        case "name"://获取属性值、节点值
                            String name = childNode.getTextContent();
                            //获取属性
                            NamedNodeMap attrs = childNode.getAttributes();
                            //获取sex属性值
                            String sex = attrs.item(0).getTextContent();
                            student.setName(name);
                            student.setSex(sex);
                            break;
                        case "age":
                            //获取age节点的值
                            String content = childNode.getTextContent();
                            int age = Integer.parseInt(content);
                            student.setAge(age);
                            break;
                    }
                }
                list.add(student);
            }
            //把解析出来的内容显示在文本框
            tvDom.setText("DOM解析结果:" + list.toString());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.3 Pull方式解析

Android的事件机制是基于回调函数的。PULL方式也是基于事件驱动的,与SAX方式一样。只不过PULL方式解析XML的方法返回的是数字。

– 读取到XML的开始返回START_DOCUMENT;
– 读取到XML的结束返回END_DOCUMENT ;
– 读取到XML的开始标签返回START_TAG ;
– 读取到XML的结束标签返回END_TAG ;
– 读取到XML的文本返回TEXT 。
PULL方式解析XML基本处理方式:
  • 当导航到XmlPullParser.START_DOCUMENT,可以不做处理,当然你可以实例化集合对象等等。
  • 当导航到XmlPullParser.START_TAG,则判断是否是数据标签,如果是,则实例化数据对象,并调用getAttributeValue方法获取标签中属性值。
  • 导航到其他标签,使用nextText方法来获取文本节点内容。
  • 导航到XmlPullParser.END_TAG的,有开始就要有结束。在这里我们就需要判断是否是数据结束标签,如果是,则把数据对象存进list集合中。
代码
/**
     * 使用PULL方式解析XML文件
     * @param file 待解析的XML
     * @return 解析结果集合
     */
    private List<Student> analyzeXmlByPull(String file) {
        try {
            //创建文件对应的输入流
            InputStream inPull = new FileInputStream(file);
            //1. 创建解析器
            XmlPullParser parser = Xml.newPullParser();
            //2. 设置解析器要解析的文件(设置文件对应的输入流)
            parser.setInput(inPull, "utf-8");
            //3. 获取解析状态对应的类型
            int type = parser.getEventType();
            List<Student> list = null;
            Student student = null;
            // 采用循环方式解析所有的内容
            while(type != XmlPullParser.END_DOCUMENT){
                type = parser.next();
                //获取当前的节点名称
                String nodeName = parser.getName();
                //根据节点名称、解析状态判断
                switch (type) {
                    case XmlPullParser.START_TAG:
                        switch (nodeName){
                            case "students":
                                //初始化集合对象
                                list = new ArrayList<>();
                                break;
                            case "student":
                                //初始化学生对象
                                student = new Student();
                                break;
                            case "name":
                                //获取属性sex的值
                                String sex = parser.getAttributeValue(0);
                                //获取name节点的值
                                String name = parser.nextText();
                                student.setName(name);
                                student.setSex(sex);
                                break;
                            case "age":
                                //获取age节点的值
                                String value = parser.nextText();
                                int age = Integer.parseInt(value);
                                student.setAge(age);
                                break;
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        switch (nodeName){
                            case "student":
                                //把解析到的学生对象添加到集合中
                                list.add(student);
                                break;
                            case "students":
                                //把解析到的内容返回
                                return list;
                        }
                        break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

4. JSON数据格式简介

JSON(JavaScript Object Notation) 是 一种轻量级的数据交换格式 。它 基于JavaScript(Standard ECMA-262 3rd Edition -December 1999)的一个子集 。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。

JSON 可以将JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从客户端传递给服务器端程序。这个字符串看起来有点儿古怪,但是JavaScript 很容易解释它,而且JSON 可以表示比"名称/ 值对"更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。

本质是字符串,轻量级,简单,表示数据多样化。
参数如果带小数,默认double,float的话需要加f
json的元素就是大括号里面的东西,数量是逗号+1

key必须是字符串格式
只要有大括号就定义成一个类。
解析时候是加载到内存的

JSON基本的结构两种

  • “名称/值”对的集合(acollection of name/value pairs)。
    不同的语言中,它被理解为对象(object),记录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组(associative array)。
  • 值的有序列表(an ordered list of values)。
    在大部分语言中,它被理解为数组(array)。
JSON 表示名称/ 值对的方式
{
	"name": "zhangsan",
	"sex": "man",
	"age": 18
}
JSON 表示数组的方式:
{
	"person": 
	[
		{
			"name": "zhang",
			"sex": "man",
			"age": 18
		}
		,
		{
			"name": "lily",
			"sex": "woman",
			"age": 18
		}
	]
}
XML和JSON的比较

可读性

JSON和XML的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。

可扩展性

XML天生有很好的扩展性,JSON当然也有。不过JSON可以存储JavaScript复合对象,有着XML不可比拟的优势。

编码难度

XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有提供的工具。无工具的情况下,相信熟练的开发人员一样能很快的写出想要的XML文档和JSON字符串,不过,XML文档要多很多结构上的字符。

解码难度

难度相当,XML存在时间较长,技术较成熟。

JSON是较新的数据结构,但有方便的解析类库。

  • JSON对数据的描述性比XML较差
  • JSON的速度要远远快于XML。

5. 解析JSON数据的方法

Android提供JSON解析类,都在包org.Json下:

  • JsonObject ‘ { ’ :可以看作是一个JSON对象,这是系统中有关JSON定义的基本单元,其包含一对儿(Key/Value)数值。它对外部(External:应用toString()方法输出的数值)调用的响应体现为一个标准的字符串。Value的类型包括:Boolean、JsonArray、JsonObject、Number、String或者默认值JsonObject.NULLobject 。
  • JsonStringer:JSON文本构建类,这个类可以帮助快速和便捷的创建JSON text。其最大的优点在于可以减少由于格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntax rules)创建JSON text。每个JsonStringer实体只能对应创建一个JSON text。
  • JsonArray‘ [ ’ :它代表一组有序的数值。将其转换为String输出(toString)所表现的形式是用方括号包裹,数值以逗号分隔(例如:[value1,value2,value3] )。这个类的内部同样具有查询行为,get()和opt()两种方法都可以通过index索引返回指定的数值,put()方法用来添加或者替换数值。同样这个类的value类型可以包括:Boolean、JsonArray、JsonObject、Number、String或者默认值JsonObject.NULLobject。
  • JsonTokener :Json解析类。
  • JsonException :Json中用到的异常。
  • android 用户向导 android 用户数据_xml_04

android 用户向导 android 用户数据_JSON_05

下面用到的自定义的类

Grade
package com.example.a20201005_jsondemo.beans;

public class Grade {
    private String course;
    private int score;

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Grade{" +
                "course='" + course + '\'' +
                ", score=" + score +
                '}';
    }
}
Student
package com.example.a20201005_jsondemo.beans;

public class Student {
    private String name;
    private String sex;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}
StudentInfo
package com.example.a20201005_jsondemo.beans;

import java.util.List;

public class StudentInfo {
    private String name;
    private String sex;
    private List<Grade> grads;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public List<Grade> getGrads() {
        return grads;
    }

    public void setGrads(List<Grade> grads) {
        this.grads = grads;
    }

    @Override
    public String toString() {
        return "StudentInfo{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", grads=" + grads +
                '}';
    }
}

代码1 把普通Java对象转换成Json字符串

//把普通Java对象转换成Json字符串
                        //构造对象
                        Student stu = buildObj();
                        //转换,参数是上面的那个对象
                        String json = convertToJson(stu);
                        tvJson.setText(json);
                        break;

---------------------------------------------------------
        /**
         * 把指定的对象转换成Json串
         */
        private String convertToJson(Student stu) {
            String json = null;
            try {
                //创建JsonObject对象
                JSONObject jObj = new JSONObject();
                //向JSONObject中添加数据
                jObj.put("name", stu.getName());
                jObj.put("sex", stu.getSex());
                //由JSONObject生成Json字符串
                json = jObj.toString();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return json;
        }



        /**
         * 构造普通Java对象
         */
        private Student buildObj() {
            Student stu = new Student();
            stu.setName("贾宝玉");
            stu.setSex("男");
            return stu;
        }

代码2:把普通Json串转换成对象

//把普通Json串转换成对象
                        //构造Json串
                        String jStr = buildJson();
                        //把Json串转换成对象
                        Student student = convertToObj(jStr);
                        //把对象显示在文本框
                        tvObj.setText(student.toString());
                        break;



-----------------------------------------------------------

        /**
         * 将给定的Json串转换成对象
         */
        private Student convertToObj(String json) {
            Student stu = null;
            try {
                //根据指定的json串创建JSONObject对象
                JSONObject jObj = new JSONObject(json);
                //构造出对象
                stu = new Student();
                //获取JSONObject中的元素
                String name = jObj.getString("name");
                String sex = jObj.getString("sex");
                stu.setName(name);
                stu.setSex(sex);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return stu;
        }




        /**
         * 构造Json字符串
         */
        private String buildJson() {
            String json = "{'name':'林黛玉','sex':'女'}";
            return json;
        }

代码3:把嵌套Json串转对象

先内层,再外层

//把嵌套Json串转对象
                        //构造一个嵌套的Json串
                        String jComJson = buildComJson();
                        //将嵌套的Json串转换成对象(StudentInfo)
                        StudentInfo studentInfo = convertToComObj(jComJson);
                        //显示在文本框
                        tvObj.setText(studentInfo.toString());
                        break;



    /**
         * 构造嵌套的StudentInfo对象
         */
        private StudentInfo buildComObj() {
            StudentInfo sInfo = new StudentInfo();
            List<Grade> grades = new ArrayList<>();
            //构造2个Grade对象
            Grade grade1 = new Grade();
            grade1.setCourse("C语言");
            grade1.setScore(99);
            grades.add(grade1);

            Grade grade2 = new Grade();
            grade2.setCourse("Android");
            grade2.setScore(100);
            grades.add(grade2);

            sInfo.setName("张三丰");
            sInfo.setSex("男");
            sInfo.setGrads(grades);
            return sInfo;
        }





        /**
         * 将给定的对象转换成Json串
         */
        private String convertToComJson(StudentInfo stuInfo) {
            String json = null;
            try {
                //创建外层JSONObject对象(StudentInfo)
                JSONObject jObj = new JSONObject();
                //创建内层JSONArray对象(List<Grade>)
                JSONArray jArray = new JSONArray();
                //向JSONArray对象中添加数据(首先取出给定对象中的集合属性)
                List<Grade> grades = stuInfo.getGrads();
                for (Grade grade : grades) {
                    JSONObject jGradeObj = new JSONObject();
                    jGradeObj.put("course", grade.getCourse());
                    jGradeObj.put("score", grade.getScore());
                    //把构造好的Grade对应的JSONObject添加到JSONArray中
                    jArray.put(jGradeObj);
                }
                //添加外层JSONObject中的数据
                jObj.put("name", stuInfo.getName());
                jObj.put("sex", stuInfo.getSex());
                jObj.put("grades", jArray);
                json = jObj.toString();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return json;
        }

代码4:把嵌套对象转Json串

//把嵌套对象转Json串
                        //构造嵌套对象
                        StudentInfo stuInfo = buildComObj();
                        //将嵌套的对象转成Json串
                        String jsonCom = convertToComJson(stuInfo);
                        tvJson.setText(jsonCom);





        /**
         * 构造嵌套的Json串
         */
        private String buildComJson() {
            String json = "{'name':'薛宝钗','sex':'女','grades':[{'course':'JavaEE','score':98},{'course':'软件过程','score':60}]}";
            return json;
        }







        /**
         * 将给定的json串转换成对象
         * @param json
         * @return
         */
        private StudentInfo convertToComObj(String json) {
            StudentInfo studentInfo = new StudentInfo();
            try {
                //创建外层JSONObject对象
                JSONObject jObj = new JSONObject(json);
                //获取外层JSONObject中的元素
                String name = jObj.getString("name");
                String sex = jObj.getString("sex");
                //将获取到的name和sex赋值给StudentInfo对象
                studentInfo.setName(name);
                studentInfo.setSex(sex);
                //创建内层数组JSONArray对象
                JSONArray jsonArray = jObj.getJSONArray("grades");
                //创建Grade集合
                List<Grade> grades = new ArrayList<>();
                //获取JSONArray中的数据
                for(int i = 0; i < jsonArray.length(); i++){
                    JSONObject jObject = jsonArray.getJSONObject(i);
                    //获取当前JSONObject中的元素
                    Grade grade = new Grade();
                    grade.setCourse(jObject.getString("course"));
                    grade.setScore(jObject.getInt("score"));
                    grades.add(grade);
                }
                studentInfo.setGrads(grades);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return studentInfo;
        }

代码5:将指定的JSON串传输给服务端(流形式)

记得修改网络链接权限

<!--    添加网络访问权限,下面的android:usesCleartextTraffic="true"也是-->
    <uses-permission android:name="android.permission.INTERNET"/>

在application节点里加上下面的东东
        android:usesCleartextTraffic="true"
android代码:
                        //构造用户json串
                        String jUser = "{'name':'lww','pwd':'123'}";
                        //传输数据
                        translateDateToServer(jUser);
                        break;




       /**将指定的JSON串传输给服务端
         * @param json
         * @return
         */
        private void translateDateToServer(final String json) {
            Log.i("lww", json);
            //创建线程传输数据
            new Thread(){
                @Override
                public void run() {
                    //进行网络请求
                    try {
                        URL url = new URL("http://10.7.10.66:8080/Ch11JsonServerDemo/RegisterUserServlet");
                        URLConnection conn = url.openConnection();
                        conn.setDoOutput(true);
                        conn.setDoInput(true);
                        //获取输入流和输出流
                        OutputStream out = conn.getOutputStream();
                        BufferedWriter writer = new BufferedWriter(
                                new OutputStreamWriter(out, "utf-8"));
                        writer.write(json);
                        writer.flush();
                        InputStream in = conn.getInputStream();
                        BufferedReader reader = new BufferedReader(
                                new InputStreamReader(in, "utf-8"));
                        String result = reader.readLine();
                        reader.close();
                        out.close();
                        Log.i("lww", "result:" + result);
                        if("OK".equals(result)){
                            Log.i("lww",result + ":注册成功");
                        }
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }.start();
        }

客户端代码(java/eclipse)

导包

android 用户向导 android 用户数据_JSON_06


并右键构建路径

package net.onest.lww.beans;

//接收客户端的用户信息(json串),并向客户端返回注册结果
@WebServlet("/RegisterUserServlet")
public class RegisterUserServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public RegisterUserServlet() {
        super();
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//通过流的方式接收客户端发来的json串
		//获取网络输入流和输出流
		InputStream in = request.getInputStream();//输入流
		//循环接收数据
		byte[] data = new byte[2048];
		StringBuffer buffer = new StringBuffer();
		int length = -1;
		while((length = in.read(data, 0, data.length)) != -1) {
			buffer.append(new String(data, 0, length));
		}
		System.out.println(buffer.toString());
		OutputStream out = response.getOutputStream();//输出流
		
		//向数据库插入数据(先判断用户是否存在,获取插入的结果,返回客户端)
		//假设插入成功
		out.write("OK".getBytes());
		out.flush();
		in.close();
		out.close();
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}