1 常用解字符集
1.1 常见字符编码表
GBK:
- 中文双字节
UNICODE:
- java使用这个表
- <mark>全部字符都采用双字节(包括英文、中文)</mark>
UTF-8:
- 底层基于UNICODE。
- <mark>解决UNICODE英文也用双字节的问题</mark>。
1.2 测试
@Test
public void test01() throws UnsupportedEncodingException {
String str = "我爱你中国";
byte[] bs ;
System.out.println("length:"+(bs=str.getBytes("gbk")).length+", content:"+Arrays.toString(bs)); //10, gbk中文使用双字节
System.out.println("length:"+(bs=str.getBytes("UNICODE")).length+", content:"+Arrays.toString(bs)); //12, UNICODE
System.out.println("length:"+(bs=str.getBytes("utf-8")).length+", content:"+Arrays.toString(bs)); //15
System.out.println("length:"+(bs=str.getBytes("ISO-8859-1")).length+" , content:"+Arrays.toString(bs)); //5
}
2 读取属性文件
2.1 什么是属性文件
<mark>properties文件一般用来作为程序的配置文件</mark>,
例如,连接数据库时,需要知道数据库服务器的地址,用户名,密码等…
…
这些连接信息,可以存储在properties配置文件中,<mark>便于修改维护</mark>
<mark>java提供了专门的工具,来读写这种格式的数据</mark>
<mark>java.util.Properteis 类</mark>
2.2 jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/yhmisdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.username=root
jdbc.password=root
2.3 格式
-
属性文件是纯文本类型,本质就是txt文件
-
<mark>#后面代表单行注释,尽量不要在属性文件中出现中文</mark>
-
每行都是kv结构,中间用=号分割
-
<mark>key不能重复,文件不报错</mark>,读取后的集合中只有最后一个的值
2.4 练习1:创建测试类
package cn.edut.tarena.day11;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Scanner;
import org.junit.Test;
//这个类用来测试属性文件的读取
public class Test02_properties {
//单元测试方法:@Test + public +void + 无参
@Test//注解@
public void test01() throws IOException {
//0、获得当前类的目录
System.out.println(Test02_properties.class.getResource(""));
System.out.println(Test02_properties.class.getResource("/"));
//1、加载属性文件
InputStream is = Test02_properties.class.getResourceAsStream("/jdbc.properties");
// “/” 根目录
//1.1 Scanner打印到控制台
Scanner sc = new Scanner(is);
while(sc.hasNext()) {
System.out.println(sc.nextLine() );
}
//2、解析
Properties prop = new Properties();
is = Test02_properties.class.getResourceAsStream("/jdbc.properties"); // 文件回到开始位置;
prop.load(is);
//3、 获取
String name = prop.getProperty("name");
System.out.println("获取name:"+name);
String age = prop.getProperty("age");
System.out.println("获取age:"+age);
//4.关闭流
is.close();
sc.close();
}
}
3 读取XML文件
3.1 什么是XML
可扩展标记语言<>,标准<mark>通用标记</mark>语言的子集,简称XML。
是一种用于标记电子文件使其具有<mark>结构性</mark>的标记语言。
3.2 格式
- <mark>开始</mark>标签和<mark>结束</mark>标签匹配,如: <select></select>
- 标签<mark>可以嵌套</mark>,如: <select><sql></sql></select>
- 每个标签都<mark>可以设置属性</mark>,属性名和属性值用=连接,如: <selectid=""resultType=""></select>
- 想要获取xml中存在的数据,<mark>通常使用Dom4j技术实现</mark>,由于是第三方的开源技术,<mark>使用时需要单独导入jar包</mark>
上面就有 <select></select>标签,它有属性id和resultType,还有值“SELECT * FROM tb_order”。而txt文件就是全部读入。
评价:xml被后期出现的json技术所取代,所以了解会用即可,不必深究。
3.3 什么是Dom4j
<mark>Dom4j,全称DOM API for Java</mark>。 <mark>是一个Java的XML API,是jdom的升级品,用来读写XML文件的</mark>。
dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,<mark>可以在SourceForge上找到它</mark>。
在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。
如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。
这已经是必须使用的jar包。
<mark>Dom4j是第三方开源API,利用SAXReader对象把xml数据,读取在内存中,组织成一个树状结构,再用不同对象来表示其他节点。</mark>
Document
--Element
--getRootElement()
--element()
--Attribute
3.4 练习1:创建spring.xml文件
一些网页的配置数据:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
</beans>
3.5 练习2:利用Dom4j读取xml
开发环境准备:
复制“dom4j-1.6.1.jar”进Project =》 Build Path add =》
代码:
package cn.edut.tarena.day11;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
//这个类用来测试dom4j解析xml
public class Test03_XML {
//单元测试方法
@Test
public void test001() throws DocumentException {
//1. 加载文件
InputStream is = Test03_XML.class.getResourceAsStream("/spring.xml");
//2.解析xml
SAXReader read = new SAXReader();
Document doc = read.read(is); //读取
//获取根节点beans
Element root = doc.getRootElement(); //<beans>节点
//4. 获取beans里面的所有bean元素
List<Element> elementList = root.elements();
//查看类型
System.out.println("查看类类型:");
System.out.print(elementList.getClass());
System.out.println("是ArrayList吗? "+ (elementList instanceof ArrayList));
System.out.println(elementList.get(0).getClass());
System.out.println("\n获取节点信息:");
for(Element e :elementList ) {
System.out.println("路径:"+e.getPath());
System.out.println("id="+e.attribute("id").getText()+"\nclass="+e.attributeValue("class"));
System.out.println("------------");
}
}
}
xml内容:
结果:
4 JSON
4.1 概念
JSON(<mark>JavaScript Object Notation, JS 对象简谱</mark>) 是一种轻量级的<mark>数据交换格式</mark>。XML替代TXT一统江湖数十载,可最终也敌不过岁月,JSON出现后它的风光不在,JSON已经成为主流开发方式,雄霸世界。
后面课程中要讲的RESTFul请求访问形式其核心就是JSON,后面要讲的SpringMVC框架、京淘电商、SpringCloud微服务都离不开JSON.
这么牛,说的都想马上看看它,它真这么厉害吗?
4.2 Jackson
我们<mark>JVM内部传输的是java对象</mark>
<mark>但网络间</mark>,异构系统间就无法直接传输java对象,早期j2ee体系中为支持这点,特别异构开发语言,就发布了WebService规范,<mark>其核心使用xml</mark>
<mark>但xml标签过多</mark>,与业务无关,造成网络传输时大量带宽的浪费。
这中间就<mark>出现了很多著名的转化工具类</mark>。
有谷歌的gson,有阿里的fastjson,但都不尽人意,实际使用中都有坑,大家百度自知。
<mark>目前很稳定的还是jackson json</mark>,包括SpringBoot一度整合用fastjson,最终在2.x版本时又换回来,其强大可见一般。
利用jackson就可以轻松实现Java对象与JSON字符串的转换。
那对于开发者也带来一个新的问题,如何把java对象转换为json或者把json转换为java对象呢?
4.3 ObjectMapper常用方法
Jackson中有个<mark>ObjectMapper类</mark>很是实用,<mark>用于Java对象与JSON的互换</mark>。
常<mark>用于序列化和反序列化</mark>,
<mark>序列化是</mark>指 将程序中的java对象序列化成二进制文件保存到磁盘中永久存储。
<mark>反序列化是</mark>指 将磁盘存储的二进制文件解析成java对象在程序中使用。
- 把json串转化成Java对象/反序列化
ObjectMapper.readValue(json串,对象);
- 把Java对象转换成Json串/序列化
ObjectMapper.writeValueAsString(对象);
4.4 创建Person.java
/** * <p>创建 Human类</p> * 含参构造、无参构造 * Override toString() * get、set方法 * @author Administrator * */
class Human implements Serializable{
/** * json序列化似乎不需要Serializable接口 */
private static final long serialVersionUID = 1L;
private String name ;
private int age ;
private String address ;
//构造方法 source -- 倒数第三个 -- ok
public Human() {};
public Human(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
//默认是查看对象的地址值,如果要查看属性的值,重写toString()
//Source -- toString() -- ok
@Override
public String toString() {
return "Human [name=" + name + ", age=" + age + ", address=" + address + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
4.5 序列化
Json实现
@Test//序列化:从java对象变成json串 -- ObjectMapper
public void test001() throws JsonProcessingException {
System.out.println("Json实现对象序列化:");
//1. 创建Human对象
Human p1 = new Human("小明",18,"广东省广州市朝阳区新建北路");
//2.把java对象变成json
ObjectMapper mapper = new ObjectMapper();
//把指定的对象p变成json串
String json = mapper.writeValueAsString(p1);
System.out.println(json);
//3.序列化输出成文件
//要先创建文件
mapper.writeValue(new File("D:\\e\\1.txt"), json);
}
控制台
ObjectOutputStream实现(Java内置类)
@Test
public void test002() throws IOException {
System.out.println("ObjectOutputStream实现对象序列化:");
//1. 创建Human对象
Human p1 = new Human("小明",18,"广东省广州市朝阳区新建北路");
//2. 对象序列化
ObjectOutputStream oos = new ObjectOutputStream(System.out);
oos.writeObject(p1);
}
控制台:
4.6 反序列化
json转化为java对象
@Test
public void test003() throws JsonParseException, JsonMappingException, IOException {
System.out.println("Json实现反序列化:");
String s = "{\"name\":\"小明\",\"age\":18,\"address\":\"广东省广州市朝阳区新建北路\"}";
ObjectMapper om = new ObjectMapper();
Human man = om.readValue(s,Human.class) ;
System.out.println(man.toString());
}
∗∗注意!∗∗
使用Json实现序列化、反序列化时,<mark>对象必须实现 public 的get、set方法。</mark>
(或者把对应的属性public)
否则会报错:(因为json无法获取到该属性)
5 扩展
5.1 了解 BIO、NIO、AIO的区别
阻塞IO,BIO 就是传统的 java.io 包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的有点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
非阻塞IO,NIO,也叫new io,对比传统的同步阻塞IO操作,实际上NIO是同步非阻塞IO 。NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
异步IO,AIO 是 Java 1.7 之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的 IO 操作方式,所以人们叫它 AIO(Asynchronous IO),异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。但目前还不够成熟,应用不多。