HTML&XML
Html和XML都属于SGML(标准通用标记语言)语言分支
程序型标记-HTML(HTML5不属于SGML分支) XHTML
描述型标记-XML-(1998正式形成标准)
两者都由W3C维护
XML:Extensiable Markup Language可扩展标记语言,xml只代表数据本身,而不包含任何样式结构的呈现,所以也称之为一种数据描述语言
Xml作用:
1.实现不同平台之间的数据交换(webservice:soap协议)
2.Xml还可以用于一些应用程序的配置文件(框架,tomcat,servlet)
XML文档构成(当前xml标签必须是*.dtd中定义的)
一个标准的XML文档由3个部分构成
1.xml指令<?xml version=”1.0” encoding=”utf-8” standalone="yes"?>
2.文档类型定义<!DOCTYPE books SYSTEM “books.dtd” >(表示当前xml标签必须是books.dtd中定义的)
3.文档元素部分
Xml指令主要描述xml版本(目前为1.0),编码,文档类型定义是否是一个独立文件
文档类型定义(DTD,XSD):规范文档中允许出现的标记,属性,以及标记之间关系
文档的详细构成部分:标签,属性,文本
Xml元素:由一对标签以及标签对之间的内容构成
Xml标签:主要包含开始标记以及结束标记
Xml属性:属性通常定义在元素的开始标记中
CDATA:元数据
<![CDATA[
元数据具体内容
]]>
命名空间:namespace,防止标签的命名冲突
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table xmlns:f="http://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
XML规范
Xml规范相对HTML来说相当严格
1.标记必须成对出现(空标签例外)
2.标签严格区分大小写
3.属性值必须使用双引号包含
4.属性值中不能包含特殊符号(<,&...)
5.xml支持类似html中实体(< > ")
6.注释代码不允许嵌套
7.一个XML文档中有且只有一对根节点
JSON&XML
AJAX:异步的javascript and XML
JSON:是一种轻量级的数据交换格式,实现不同平台之间的数据交换
XML解析
<?xml version="1.0" encoding="utf-8"?>
<books>
<book no = "0103410">
<name>还珠格格</name>
<author>琼瑶</author>
<publish>XX版社</publish>
<price>34.5</price>
</book>
<book no = "0103411">
<name>三国演义</name>
<author>罗贯中</author>
<publish>XXX出版社</publish>
<price>34.5</price>
</book>
<book no = "0103412">
<name>红楼梦</name>
<author>曹雪芹</author>
<publish>XXXX出版社</publish>
<price>34.5</price>
</book>
</books>
1.DOM解析(换行标记也算一个节点)
将需要被解析的文档完整的加载到内存中,解析为一颗倒置的文档树,可以通过解析器任意获取文档树中的节点
优点:适合解析较小的文档,解析速度快,可以任意搜索节点,并行搜索
缺点:一次性加载的整个文档,会消耗大量内存,无法解析过大的文件
public class DomParseDemo {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
//实例化一个解析工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取解析器对象
DocumentBuilder builder = factory.newDocumentBuilder();
//解析文件并获取文档对象
Document document = builder.parse(new File("src/java/userInfo.xml"));
//根据元素的标签名获取元素并取出匹配第一个元素(根节点)
Node root = document.getElementsByTagName("users").item(0);
//获得当前节点下的所有子节点
NodeList list = root.getChildNodes();
//跳过0 因为0是空格节点
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
//判断当前节点名称是否为user
if ("user".equals(node.getNodeName())){
//获取节点中的属性节点集合
NamedNodeMap nnm = node.getAttributes();
//根据节点名称(属性名)获取节点值(属性值)
String id = nnm.getNamedItem("id").getNodeValue();
String type = nnm.getNamedItem("type").getNodeValue();
System.out.println(id);
System.out.println(type);
//继续搜索user下的子节点
NodeList user_child_list = node.getChildNodes();
for (int j = 0; j < user_child_list.getLength(); j++){
Node child_node = user_child_list.item(j);
if (child_node != null)
switch (child_node.getNodeName()){
case "name":
System.out.println("name:"+child_node.getTextContent());
break;
case "sex":
System.out.println("sex:"+child_node.getTextContent());
break;
case "age":
System.out.println("age:"+child_node.getTextContent());
break;
case "ismarray":
System.out.println("ismarray:"+child_node.getTextContent());
break;
default:
break;
}
}
}
}
System.out.println(document.getElementsByTagName("name").getLength());
}
}
2.SAX解析
基于事件驱动的方式以类似流媒体的方式进行解析,在读取到一部分内容之后立即开始解析,直到读取到文档结束标记后停止解析
优点:适合解析较大的文档,解析效率较快,一边读取一边解析
缺点:无法任意搜索节点,比较难以实现并行搜索
public class SAXParseDemo extends DefaultHandler {
public List<Book> books;
private Book book;
private String nowTag;
//文档开始时触发 读到users触发
@Override
public void startDocument() throws SAXException {
books = new ArrayList<Book>();
System.out.println("开始解析");
}
//读取到开始标记时触发 读到每一个节点开头触发
@Override
/** uri 命名空间的url地址
* localName 不带命名空间前缀的标签名称
* qName 带命名空间的标签名
* attribute 元素中的属性列表 例如id(只存在于开始节点)
*/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("读取到开始标记" + qName);
//记录当前读取到的开始标记
nowTag = qName;
//当读取到一个book的开始标记后创建一个book对象
if ("book".equals(qName)){
book = new Book();
book.setNo(attributes.getValue("no"));
}
}
//读取到文本节点时触发 读到文本节点触发,空白节点也是文本节点
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String value = new String(ch, start, length);
System.out.println("读取到文本节点" + value);
switch (nowTag){
case "name":
book.setName(value);
break;
case "author":
book.setAuthor(value);
break;
case "publish":
book.setPublish(value);
break;
case "price":
book.setPrice(value);
break;
default:
break;
}
nowTag = "";
}
//读取到结束时触发 读到这里</>触发
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("读取到结束标记" + qName);
if ("book".equals(qName)){
books.add(book);
book = null;
}
}
//文档结束时触发 只执行一次
@Override
public void endDocument() throws SAXException {
System.out.println("解析完成");
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//创建解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//生产解析器
SAXParser parse = factory.newSAXParser();
//开始解析
SAXParseDemo spd = new SAXParseDemo();
parse.parse("src/java/book.xml", spd);
for (Book book:spd.books) {
System.out.println(book);
}
}
}
- JDOM解析
public class JDomParseDemo {
public static void main(String[] args) throws JDOMException, IOException {
//创建解析器
SAXBuilder builder = new SAXBuilder();
//解析指定文档为一个Document对象
Document document = builder.build(new File("src/java/book.xml"));
//获取文档的根节点
Element root = document.getRootElement();
//获取根节点下的子节点集合
List<Element> list = root.getChildren("book");
for (Element e:list) {
//取出节点中指定属性值
String no = e.getAttributeValue("no");
System.out.println(no);
//获取当前节点下指定名称的单个子节点
String name = e.getChild("name").getText();
String author = e.getChild("author").getText();
String publish = e.getChild("publish").getText();
String price = e.getChild("price").getText();
System.out.println(name);
System.out.println(author);
System.out.println(publish);
System.out.println(price);
System.out.println("==========");
}
}
}
4.DOM4J解析
public class Dom4JParseDemo {
public static void main(String[] args) throws DocumentException {
//创建一个Dom4J解析器
SAXReader reader = new SAXReader();
//解析文档
Document document = reader.read("src/java/book.xml");
//获取根节点
Element root = document.getRootElement();
//获取当前根节点下指定名称的子节点
List<Element> list = root.elements("book");
for (Element e:list) {
//取出节点中指定属性值
String no = e.attributeValue("no");
System.out.println(no);
//获取当前节点下指定名称的单个子节点
String name = e.element("name").getText();
String author = e.element("author").getText();
String publish = e.element("publish").getText();
String price = e.element("price").getText();
System.out.println(name);
System.out.println(author);
System.out.println(publish);
System.out.println(price);
System.out.println("==========");
}
}
}
快速搜索节点:
public class Dom4J_XPathDemo {
public static void main(String[] args) throws DocumentException {
//获取解析器
SAXReader reader = new SAXReader();
//获取文档对象
Document document = reader.read("src/java/book.xml");
//快速搜索某节点
List<Node> list = document.selectNodes("books/book/name");
for (Node node:list) {
Element pnode = node.getParent();
System.out.println(node.getName() + "=" + node.getText());
System.out.println(pnode.getName() + ":" + pnode.attribute(0).getName() +
" = " + pnode.attributeValue("no"));
System.out.println("------------------");
}
//快速搜索属性
List<Node> list2 = document.selectNodes("books/book");
for (Node node:list2) {
//获取节点的属性值
System.out.println("no="+node.valueOf("@no"));
}
}
}
5.DOM4J创建XML文件
/*
* <books>
<book no = "0103410">
<name>还珠格格</name>
<author>琼瑶</author>
<publish>芒果台出版社</publish>
<price>34.5</price>
</book>
</books>
* */
public class CreateXMLFileByDom4J {
public static void main(String[] args) throws IOException {
//创建一个文档对象
Document document = DocumentHelper.createDocument();
//创建一个根节点
Element root = document.addElement("books");
Element book = root.addElement("book").addAttribute("no", "0103410");
book.addElement("name").setText("还珠格格");
book.addElement("author").setText("琼瑶");
book.addElement("publish").setText("芒果台出版社");
book.addElement("price").setText("34.5");
//创建一个文档的输出格式对象
OutputFormat fmt = OutputFormat.createPrettyPrint();//创建漂亮的格式
fmt.setEncoding("utf-8");//设置编码
File file = new File("src/java/bk.xml");
FileWriter fw = new FileWriter(file);
//xml文件输出流
XMLWriter writer = new XMLWriter(fw,fmt);//装饰器模式
writer.write(document);
writer.flush();
writer.close();
}
}
Android pull解析
反射reflect
*.java源文件编译为.class字节码文件
* 类加载机制:将一个类装载到jvm虚拟机等待执行的过程(字节码文件的加载过程)
* 1.加载 先去父类找,如果找到了就只加载父类,没找到去子类找,这时父类和子类都加载,加载顺序是先父类再子类(如果是A->B->C的继承关系,AC具有相同属性,B没有,这时候不会跳过B,会先加载A,再加载B再加载C),先静态快再静态属性。
*
* 2.验证(连接操作)
* 3.准备(连接操作)为静态成员变量赋默认值
* 4.解释(连接操作)
*
* 5.初始化(对类中静态成分执行初始化,为静态变量赋值,执行静态的初始化块)
* 将这些方法放到栈内存的方法区中
* 6.使用(调用成员变量)
* 7.卸载
反射:一个正在运行的类通过反射机制获取到类中的具体信息(包含在Class实例中)
获取Class类对象的三种方法:
方法一:调用类的class属性获取。默认不初始化
Class class1 = Student.class;
方法二:通过实例对象的getClass()方法获取
Student stu = new Student();
Class class1 = stu.getClass();
方法三:通过类加载器加载
默认不初始化
Student.class.getClassLoader().loadClass("com.wan.reflect.Student");
默认初始化
Class.forName("com.wan.reflect.Demo2");
不初始化
Class.forName("com.wan.reflect.Demo2",false,Demo2.class.getClassLoader());
Demo
Class clz = Class.forName("com.wan.reflect.Student",false,com.wan.reflect.Student.class.getClassLoader());
Object obj = clz.newInstance();//利用Class实例化对象(前提是被实例化的对象所在类必须包含默认的无参构造器)
((Student)obj).setSno(10);
Field[] fields = clz.getFields();//获取类中公开属性
fields = clz.getDeclaredFields();//获取类中所有属性
for (Field f:fields) {
//属性-属性类型-访问修饰符类型(protected,private,public,默认0)
System.out.println(f + "------" + f.getType()+"------"+f.getModifiers());
}
System.out.println("-=-=-=--=-=-=-=-=-=-=-");
Field field = clz.getDeclaredField("sno");//获取其中某一个属性对象
System.out.println(field.getName());//获取属性名
System.out.println(field.getType());//获取类型
System.out.println(field.get(obj));//获取当前属性在指定对象上的值
field.set(obj, 11);//设置指定对象的改属性值
System.out.println(field.get(obj));
System.out.println("-=-=-=--=-=-=-=-=-=-=-");
//获取方法
Method[] methods = clz.getDeclaredMethods();
for (Method m:methods) {
System.out.println(m);
}
//获取指定方法(通过方法名,属性类型获取方法对象)
Method method = clz.getMethod("setSex",clz.getDeclaredField("sex").getType());
System.out.println("指定method:"+method);
//执行方法
method.invoke(obj, "未知");
System.out.println("obj:"+obj);
Method method1 = clz.getMethod("getSex");
//执行方法并获取返回值
Object r = method1.invoke(obj);
System.out.println(r);
System.out.println("-=-=-=--=-=-=-=-=-=-=-");
//获取构造器
Constructor[] constructors = clz.getDeclaredConstructors();
for (Constructor constructor:constructors) {
System.out.println(constructor);
}
}
f.getModifiers()//访问修饰符类型
Spring反射原理:
- 解析XML, <beans>根节点,<bean>对象,<property>属性,<text>属性值
- 创建bean工厂,传bean的id获取bean对象
对象克隆
public class ObjectClone {
public static <T> T copy(Object source, Class<T> T){
//获取指定对象的Class对象
if (source != null){
Class<T> clz = T;
try {
//创建新对象
T newObj = clz.newInstance();
//获取当前包中所有属性
Field[] fields = clz.getDeclaredFields();
for (Field f:fields) {
//获取set get方法的名字
String method_set_name = "set" + f.getName().substring(0,1).toUpperCase() + f.getName().substring(1);
String method_get_name = "get" + f.getName().substring(0,1).toUpperCase() + f.getName().substring(1);
//通过方法名和参数类型获得方法对象
Method method_set = clz.getMethod(method_set_name, f.getType());
Method method_get = clz.getMethod(method_get_name);
//将源对象的值赋给新对象
Object field_value = method_get.invoke(source);
method_set.invoke(newObj, field_value);
}
return newObj;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
public static void main(String[] args) {
System.out.println(ObjectClone.copy(new Student(1,"王老五",13,"化学系"),Student.class));
System.out.println(ObjectClone.copy(new Test(),Test.class));
}
}
解析beans,Spring解析bean原理
public class BeanFactory {
//初始化一个map集合存储所有的bean对象
private Map<String, Object> beans;
public BeanFactory() {
}
//根据beans文件解析
public BeanFactory(String config){
try {
beans = new HashMap<String, Object>();
//创建解析器
SAXReader reader = new SAXReader();
//解析配置文件获取document文件
Document document = reader.read(config);
//获取所有bean节点
List<Node> list = document.selectNodes("beans/bean");
if (list != null){
for (Node node:list) {
//获取bean节点中的id和class属性值
String id = node.valueOf("@id");
String clzName = node.valueOf("@class");
//加载指定类路径获取Class对象
Class clz = Class.forName(clzName);
//创建实例
Object obj = clz.newInstance();
//将实例装进map,键为id
beans.put(id, obj);
//获取bean节点下的所有属性节点
List<Node> props = node.selectNodes("property");
//循环属性节点
for (Node n:props) {
//获取每个属性节点的name属性名---value属性值---ref关联
String pName = n.valueOf("@name");
String pValue = n.valueOf("@value");
String pRef = n.valueOf("@ref");
//根据属性名获取set方法名字
String method_set_name = "set" + pName.substring(0,1).toUpperCase() + pName.substring(1);
//根据set方法的名字和属性类型获取set方法
Method method_set = clz.getMethod(method_set_name, clz.getDeclaredField(pName).getType());
//如果有关联直接去map中取数据,否则运行set方法将value值设给属性
if ("".equals(pRef)){
Class c = method_set.getParameterTypes()[0];
//根据属性的类型将String转换为相应类型值后再set
method_set.invoke(obj, Utils.getValue(c.getName(),pValue));
}else {
method_set.invoke(obj, beans.get(pRef));
}
}
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public Object getBean(String id){
return beans == null ? null : beans.get(id);
}
public static void main(String[] args) {
BeanFactory bf = new BeanFactory("src/java/beans.xml");
UserService us = (UserService)bf.getBean("userService");
us.register();
}
}
转换为相应类型:
public class Utils {
public static Object getValue(String type, String value){
if ("int".equals(type)){
return Integer.parseInt(value);
}else if ("short".equals(type)){
return Short.parseShort(value);
}else if ("long".equals(type)){
return Long.parseLong(value);
}else if ("float".equals(type)){
return Float.parseFloat(value);
}else if ("double".equals(type)){
return Double.parseDouble(value);
}else if ("char".equals(type)){
return value.charAt(0);
}else if ("byte".equals(type)){
return Byte.parseByte(value);
}else if ("boolean".equals(type)){
return Boolean.parseBoolean(value);
}else {
return value;
}
}
}
知识点:
一、Java只有两种成员变量与对象无关
- 基本数据类型
- 静态成员(静态属性,静态方法)
- Java中所有类都是Class类实例。Class代表的是jvm中正在执行的一个类的实例,
Class中包含了当前实例的运行信息,内部构造(成员变量,方法,注解,实现接口。。。)
- Object是所有类的父类。Object也是Class类的一个实例
- DI/IOC(控制反转):程序员需要手动new对象的操作交给了框架来做了,spring利用反射机制读取xml文件,利用反射实现对象,property值也通过反射set方法注入到对象里面。