美文网首页
数据交换格式与反射(第六天)

数据交换格式与反射(第六天)

作者: hzhang94 | 来源:发表于2018-09-27 15:42 被阅读0次

    数据交换格式

    客户端与服务器常用数据交换格式xml、json、html

    json

    什么是json

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比较的复杂,而且需要编写大段的代码,所以客户端和服务器的数据交换格式往往通过JSON来进行交换。

    JSON格式的分类

    json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。

    1. 对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
    2. 数组:数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

    常用JSON解析框架

    fastjson(阿里)、gson(谷歌)、jackson(SpringMVC自带)

    使用fastjson解析json

    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。
    

    xml

    什么是XML?

    它是可扩展标记语言(Extensible Markup Language,简称XML),是一种标记语言。XML 全称为可扩展的标记语言,主要用于描述数据和用作配置文件。
    XML 文档在逻辑上主要由一下 5 个部分组成:

    • XML 声明:指明所用 XML 的版本、文档的编码、文档的独立性信息;
    • 文档类型声明:指出 XML 文档所用的 DTD;
    • 元素:由开始标签、元素内容和结束标签构成;
    • 注释:以结束,用于对文档中的内容起一个说明作用;
    • 处理指令:通过处理指令来通知其他应用程序来处理非 XML 格式的数据。

    XML 文档的根元素被称为文档元素,它和在其外部出现的处理指令、注释等作为文档实体的子节点,根元素本身和其内部的子元素也是一棵树。

    XML解析方式?

    Dom4j、Sax、Pull

    Dom4j与Sax区别

    dom4j不适合大文件的解析,因为它是一下子将文件加载到内存中,所以有可能出现内存溢出,sax是基于事件来对xml进行解析的,所以他可以解析大文件的xml,也正是因为如此,所以dom4j可以对xml进行灵活的增删改查和导航,而sax没有这么强的灵活性,所以sax经常是用来解析大型xml文件,而要对xml文件进行一些灵活(crud)操作就用dom4j。

    1.自己创建Document对象
    Document document = DocumentHelper.createDocument();
    Element root = document.addElement("students");
    其中students是根节点,可以继续添加其他节点等操作。
    2.读取文件中的Document对象
    // 创建SAXReader对象
    SAXReader reader = new SAXReader();
    // 读取文件 转换成Document
    Document document = reader.read(new File("XXXX.xml"));
    3.读取XML文本内容获取Document对象
    String xmlStr = "<students>......</students>";
    Document document = DocumentHelper.parseText(xmlStr);
    

    XML与JSON区别

    1. Xml是重量级数据交换格式,占宽带比较大。
    2. JSON是轻量级交换格式,xml占宽带小。

    java反射机制

    什么是Java反射

    就是在正在运行中,动态获取这个类的所有信息。

    反射机制的作用

    1. 反编译:.class-->.java
    2. 通过反射机制访问java对象的属性,方法,构造方法等

    反射机制获取类有三种方法

    //第一种方式:  
    Class c1 = Class.forName("Employee");  
    //第二种方式:  
    //java中每个类型都有class 属性.  
    Class c2 = Employee.class;  
    //第三种方式:  
    //java语言中任何一个java对象都有getClass 方法  
    Employee e = new Employee();  
    Class c3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
    

    反射创建对象的方式

    1.无参
    Class<?> forName = Class.forName("com.itmayiedu.entity.User");
    // 创建此Class对象所表示的类的一个新实例 调用了User的无参数构造方法.
    Object newInstance = forName.newInstance();
    2.实例化有参构造函数
    Class<?> forName = Class.forName("com.itmayiedu.entity.User");
    Constructor<?> constructor = forName.getConstructor(String.class, String.class);
    User newInstance = (User) constructor.newInstance("123", "123");
    

    java反射api

    方法名称 作用
    getDeclaredMethods [] 获取该类的所有方法
    getReturnType() 获取该类的返回值
    getParameterTypes() 获取传入参数
    getDeclaredFields() 获取该类的所有字段
    setAccessible 允许访问私有成员
    package top.nightliar.study.day06;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * Created by Nightliar
     * 2018-09-26 14:27
     */
    public class FsDemo02 {
    
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
            // 1.使用java反射机制获取类的所有属性、方法,并且为私有属性赋值。
            Class<?> aClass = Class.forName("top.nightliar.study.day06.User");
            // 2.获取到当前类的所有属性
            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }
            // 3.获取当前类的所有方法
            Method[] methods = aClass.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method.getName());
            }
            // 4.使用java反射给私有属性赋值
            Object object = aClass.newInstance();
            Field fieldName = aClass.getDeclaredField("name");
            fieldName.setAccessible(true);  // 允许反射操作私有属性
            fieldName.set(object, "zhangsan");
            Field fieldAge = aClass.getDeclaredField("age");
            fieldAge.setAccessible(true);   // 允许反射操作私有属性
            fieldAge.set(object, 12);
            User user = (User) object;
            System.out.println(user.toString());
        }
    }
    

    如何禁止使用反射机制初始化

    将构造函数为私有化

    使用反射机制实现SpringIOC

    SpringIOC底层实现原理

    1. 读取bean的XML配置文件
    2. 使用beanId查找bean配置,并获取配置文件中class地址。
    3. 使用Java反射技术实例化对象
    4. 获取属性配置,使用反射技术进行赋值。

    详细步骤

    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
    public class ClassPathXmlApplicationContext {
        private String pathXml = null;
    
        public ClassPathXmlApplicationContext(String pathXml) {
            this.pathXml = pathXml;
        }
    
        public Object getBean(String beanId) throws Exception {
            if (StringUtils.isEmpty(beanId)) {
                throw new Exception("beanId is null");
            }
            SAXReader saxReader = new SAXReader();
            Document read = saxReader.read(this.getClass().getClassLoader().getResource(pathXml));
            // 获取到根节点
            Element rootElement = read.getRootElement();
            // 根节点下所有的子节点
            List<Element> elements = rootElement.elements();
            for (Element element : elements) {
                // 获取到节点上的属性
                String id = element.attributeValue("id");
                if (StringUtils.isEmpty(id)) {
                    continue;
                }
                if (!id.equals(beanId)) {
                    continue;
                }
    
                // 使用java反射机制初始化对象
                String beanClass = element.attributeValue("class");
                Class<?> forName = Class.forName(beanClass);
                Object newInstance = forName.newInstance();
                List<Element> propertyElementList = element.elements();
                for (Element el : propertyElementList) {
                    String name = el.attributeValue("name");
                    String value = el.attributeValue("value");
                    Field declaredField = forName.getDeclaredField(name);
                    declaredField.setAccessible(true);
                    declaredField.set(newInstance, value);
                }
                return newInstance;
            }
            return null;
        }
    
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext classPath = new ClassPathXmlApplicationContext("applicationContext.xml");
            User user = (User) classPath.getBean("user2");
            System.out.println(user.getUserId() + "---" + user.getUserName());
        }
        
    }
    

    相关文章

      网友评论

          本文标题:数据交换格式与反射(第六天)

          本文链接:https://www.haomeiwen.com/subject/ixieoftx.html