数据传递格式(json + xml)、反射机制、手写SpringIOC框架
第一:数据传递格式之json
1.1 JSON 是什么?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比较的复杂,而且需要编写大段的代码,所以客户端和服务器的数据交换格式往往通过JSON来进行交换。
示例:
{
"sites": [
{
"name": "腾讯云课堂",
"url": "https://cloud.tencent.com/"
},
{
"name": "深信服",
"url": "https://www.sangfor.com.cn/"
}
]
}
JSON语法格式说明:JSON的形式是用大括号“{}”包围起来的对象列表,每一个对象间用逗号(,)分隔,而对象的属性就是用冒号(:)分隔的属性名和属性值。这是典型的字典表示形式
1.2 JSON 格式分类:对象和数组,通过这两种结构可以表示各种复杂的数据结构。
对象:对象在json中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构。
数组:数组在json中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。
1.3 JSON 常用解析框架:fastjson(阿里)、gson(谷歌)、jackson(spring框架自带)
1.3.1 fastjson 框架使用
第一步: 添加fastjson的jar 包依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
第二步: 使用fastjson api
public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray
public static final JSONObject parseObject(String text); // 把JSON文本parse成JSONObject
public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean
public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray
public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合
public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本
public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本
public static final Object toJSON(Object javaObject); 将JavaBean转换为JSONObject或者JSONArray。
第三步:解析JSON和拼接JSON
package com.zzg.json;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class FastjsonDemo {
static String json ="{\r\n" +
" \"sites\": [\r\n" +
" {\r\n" +
" \"name\": \"腾讯云课堂\",\r\n" +
" \"url\": \"https://cloud.tencent.com/\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"name\": \"深信服\",\r\n" +
" \"url\": \"https://www.sangfor.com.cn/\"\r\n" +
" }\r\n" +
" ]\r\n" +
"}";
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
// 将json字符串转为jsonbject
JSONObject jsonStrObject = jsonObject.parseObject(json);
JSONArray jsonArray = jsonStrObject.getJSONArray("sites");
for (Object object : jsonArray) {
JSONObject stObject = (JSONObject) object;
String name = stObject.getString("name");
String url = stObject.getString("url");
System.out.println(name + "---" + url);
}
}
}
package com.zzg.json;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class FastJSONDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
JSONObject jsonObject = new JSONObject();
JSONArray jsonArray = new JSONArray();
JSONObject stObject = new JSONObject();
stObject.put("name", "腾讯云课堂");
stObject.put("url", "https://ke.qq.com/");
jsonArray.add(stObject);
jsonObject.put("sites", jsonArray);
System.out.println(jsonObject.toJSONString());
}
}
2.1 什么是XML
XML 全称为可扩展的标记语言。主要用于描述数据和用作配置文件。
XML 文档在逻辑上主要由一下 5 个部分组成:
第一部分:XML 声明:指明所用 XML 的版本、文档的编码、文档的独立性信息
第二部分:文档类型声明:指出 XML 文档所用的 DTD
第三部分:元素:由开始标签、元素内容和结束标签构成
第四部分:注释:以结束,用于对文档中的内容起一个说明作用
第五部分:处理指令:通过处理指令来通知其他应用程序来处理非 XML 格式的数据(比如:根元素或者是注解)
示例:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student1 id="001">
<学号>20140101</学号>
<地址>北京海淀区</地址>
<座右铭>要么强大,要么听话</座右铭>
</student1>
<student2 id="002">
<学号>20140102</学号>
<地址>北京朝阳区</地址>
<座右铭>在哭泣中学会坚强</座右铭>
</student2>
</students>
2.2 XML 解析方式
Dom4j、Sax、Pull
2.3 Dom4j 与Sax 解析差异
dom4j不适合大文件的解析,因为它是一下子将文件加载到内存中,所以有可能出现内存溢出,sax是基于事件来对xml进行解析的,所以他可以解析大文件的xml,也正是因为如此,所以dom4j可以对xml进行灵活的增删改查和导航,而sax没有这么强的灵活性,所以sax经常是用来解析大型xml文件,而要对xml文件进行一些灵活(crud)操作就用dom4j。
2.4 使用Dom4j 解析
2.4.1 生成xml
package com.zzg.xml;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class Dom4jDemo {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// 第一步:创建一个Document实例
Document doc = DocumentHelper.createDocument();
// 第二步:先添加一个根结点,然后再添加子结点,构造成一个树形结构
Element root = doc.addElement("students");
// 创建根节点关联的子节点数据
Element oneChildern = root.addElement("student1 ").addAttribute("id", "001");
oneChildern.addElement("学号").addText("20140101");
oneChildern.addElement("地址").addText("北京海淀区");
oneChildern.addElement("座右铭").addText("要么强大,要么听话");
Element twoChildern = root.addElement("student2 ").addAttribute("id", "002");
twoChildern.addElement("学号").addText("20140102");
twoChildern.addElement("地址").addText("北京海淀区");
twoChildern.addElement("座右铭").addText("在哭泣中学会坚强");
// 第三步:添加xml文件样式(也可自定义样式),并输出xml文件到指定的路径下
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream(new File("E:\\dom4j.xml")), format);
writer.write(doc);
writer.flush();
writer.close();
}
}
2.4.1 解析xml
package com.zzg.xml;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Dmo4jParseDemo {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// 第一步:创建一个SAXReader解析器
SAXReader reader = new SAXReader();
// 第二步:解析xml文件,重新构建成一个Document对象
Document doc = reader.read(new File("E:\\dom4j.xml"));
// 第三步:处理Document对象信息,在控制台打印
Element rootElement = doc.getRootElement();
getNodes(rootElement);
}
static public void getNodes(Element rootElement) {
System.out.println("当前节点名称:" + rootElement.getName());
// 获取属性ID
List<Attribute> attributes = rootElement.attributes();
for (Attribute attribute : attributes) {
System.out.println("属性:" + attribute.getName() + "---" + attribute.getText());
}
if (!rootElement.getTextTrim().equals("")) {
System.out.println(rootElement.getName() + "--" + rootElement.getText());
}
// 使用迭代器遍历
Iterator<Element> elementIterator = rootElement.elementIterator();
while (elementIterator.hasNext()) {
Element next = elementIterator.next();
getNodes(next);
}
}
}
效果展示:
XML 与JSON之间的区别:
Xml是重量级数据交换格式,占宽带比较大。JSON是轻量级交换格式,xml占宽带小。
所有很多互联网公司都会使用json作为数据交换格式
很多银行项目,大多数还是在使用xml。
第二、反射机制
2.1 什么是反射机制
就是正在运行,动态获取这个类的所有信息。
2.2 反射机制的作用
通过反射机制访问java对象的属性,方法,构造方法等;
2.3 反射机制的应用场景
1.Jdbc 加载驱动加载
2.Spring ioc框架(控制反转)
2.4 反射机制获取类的三种方式
package com.zzg.reflex;
import java.io.Serializable;
import java.util.Date;
@SuppressWarnings("serial")
public class Person implements Serializable {
private String name;
private Integer age;
private String sex;
private String address;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
package com.zzg.reflex;
import java.lang.reflect.Field;
public class ReflexDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//第一种方式
Class one = Class.forName("com.zzg.reflex.Person");
System.out.println("class name is:" + one.getName());
// 第二种方式
Class two = Person.class;
System.out.println("class name is:" + two.getName());
// 第三种方式
Person obj = new Person();
Class three = obj.getClass();
System.out.println("class name is:" + three.getName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.5 反射机制创建对象的二种方式
package com.zzg.reflex;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflexTwo {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
// 第一种方式:无参构造函数调用
Class<?> forNameOne = Class.forName("com.zzg.reflex.Person");
// 创建对象实例,无参构造函数
Person newInstance = (Person) forNameOne.newInstance();
if(newInstance != null) {
System.out.println("newInstance is not null");
}
//第二种方式:有参构造函数调用
Class<?> forNameTwo = Class.forName("com.zzg.reflex.Person");
Constructor<?> constructor = forNameTwo.getConstructor(String.class);
Person person = (Person) constructor.newInstance("zzg");
if(person != null) {
System.out.println("person is not null");
System.out.println("person name is:" + person.getName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.6 反射涉及api 接口
方法名称 作用
getDeclaredMethods [] 获取该类的所有方法
getReturnType() 获取该类的返回值
getParameterTypes() 获取传入参数
getDeclaredFields() 获取该类的所有字段
setAccessible 允许访问私有成员
2.7 使用反射机制为类的私有属性赋值
package com.zzg.reflex;
import java.lang.reflect.Field;
public class ReflexThree {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
// 获取当前类class地址
Class<?> forName = Class.forName("com.zzg.reflex.Person");
// 使用反射实例化对象 无参数构造函数
Object newInstance = forName.newInstance();
// 获取当前类的 name字段
Field declaredField = forName.getDeclaredField("name");
// 允许操作私有成员
declaredField.setAccessible(true);
// 设置值
declaredField.set(newInstance, "zzg");
Person person = (Person) newInstance;
System.out.println("person name is :" + person.getName());
}catch(Exception e) {
System.out.println("error message is:" + e.getMessage());
}
}
}
第三:手写SpringIOC框架
3.1 什么是SpringIOC:
就是把每一个bean(实体类)的实例化交给第三方容器进行管理。
3.2 SpringIOC 工作原理
1.读取bean的XML配置文件
2.使用beanId查找bean配置,并获取配置文件中class地址。
3.使用Java反射技术实例化对象
4.获取属性配置,使用反射技术进行赋值。
3.3 自定义SpringIOC 实现功能描述:
1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象
2.对于Document对象获取根元素对象<beans>后对下面的<bean>标签进行遍历,判断是否有符合的id.
3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.
4.遍历<bean>标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.
5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.
6.返回建立的对象,如果没有对应的id,或者<beans>下没有子标签都会返回null
3.4 自定义SpringIOC 源码:
package com.zzg.ioc;
import java.lang.reflect.Field;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.zzg.reflex.Person;
public class ClassPathXmlApplicationContext {
// 私有属性
private String xmlPath;
// set 和 get 方法
public String getXmlPath() {
return xmlPath;
}
public void setXmlPath(String xmlPath) {
this.xmlPath = xmlPath;
}
// 构造函数
public ClassPathXmlApplicationContext(String xmlPath) {
super();
this.xmlPath = xmlPath;
}
// 功能方法
public Object getBean(String beanId) throws Exception {
// 解析xml器
SAXReader saxReader = new SAXReader();
Document read = null;
try {
// 从项目根目录路径下 读取
read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
} catch (Exception e) {
}
if (read == null) {
return null;
}
// 获取根节点资源
Element root = read.getRootElement();
List<Element> elements = root.elements();
if (elements.size() <= 0) {
return null;
}
Object oj = null;
for (Element element : elements) {
String id = element.attributeValue("id");
if (StringUtils.isEmpty(id)) {
return null;
}
if (!id.equals(beanId)) {
// 跳出当前循环
continue;
}
// 获取实体bean class地址
String beanClass = element.attributeValue("class");
// 使用反射实例化bean
Class<?> forNameClass = Class.forName(beanClass);
oj = forNameClass.newInstance();
// 获取子类对象
List<Element> attributes = element.elements();
if (attributes.size() <= 0) {
return null;
}
for (Element et : attributes) {
// 使用反射技术为方法赋值
String name = et.attributeValue("name");
String value = et.attributeValue("value");
Field field = forNameClass.getDeclaredField(name);
field.setAccessible(true);
// 待优化,动态属性值注入
field.set(oj, value);
}
}
return oj;
}
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
Person bean = (Person) applicationContext.getBean("person1");
System.out.println("使用反射获取bean" + bean.getName() + "---" + bean.getSex());
}
}
<beans>
<bean id="person1" class="com.zzg.reflex.Person">
<property name="name" value="张三"></property>
<property name="sex" value="男"></property>
</bean>
<bean id="person2" class="com.zzg.reflex.Person">
<property name="name" value="李四"></property>
<property name="" value="男"></property>
</bean>
</beans>
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。