历史回顾
DBUtils
DBCP数据源获取DataSource
InputStream is = 类名.class.getClassLoader().getResourceAsStream(属性文件);
Properties p = new Properties();
p.load(is);
ds = BasicDataSourceFactory.createDataSource(p);
Druid
同上~
ds = DruidDataSourceFactory.createDataSource(p);
C3P0
ComboPooledDataSource ds = new ComboPooledDataSource ();
操作sql语句
QueryRunner qr = new QueryRunner(ds);
DML(数据库操纵语言)
insert into
update
delete
DDL(数据库定义语言)
create | alter | drop | show | use | desc查询表结构
DQL(数据库查询语言)
select
DCL(数据库权限控制语言)
DBUtils 的Query操作
ResultSetHandler 接口
ArrayHandler 查询单个数组
ArrayListHandler 查询集合
BeanHandler 查询单个对象
BeanListHandler 查询对象集合
ScalarHandler 返回单个列值(聚合函数使用居多)
事务:
开启 connection.setAutoCommint(false);
提交事务 connection.commit();
事务回滚 connection.rollback();
Servlet与Tomcat关系
在创建web工程的时候,默认是需要导入服务器的Jar文件到项目中,为什么要导入呢?
这里有对web工程的一些支持jar包,如果不导入很多功能是无法实现的
例如:
servlet-api.jar 支持Servlet 环境
el-api.jar 对EL表达式的支持
jsp-api.jar 对JSP文件的支持
....
Servlet实际是Tomcat的一个组件(Servlet依赖Tomcat运行)
其本质Servlet就是一个接口,这个接口标准被实现之后才有了现在应用的Servlet功能
我们要使用Servlet实现前后端交互通常要使我们自定义的类继承HttpServlet类,那么HttpServlet和Servlet之间又是什么关系呢?
HttpServlet extends GenericServlet implements Servlet
Tomcat为什么要自带Servlet.Jar
原因是Servlet运行必须需要一个服务器的环境,如果不自带就需要单独导包,Tomcat为了大家方便自动集成到里面,所以Servlet接口并不是tomcat提供的,但是他会完美支持并运行这个接口下所有的实现类。
Servlet中的方法介绍
重写Servlet接口中方法
init :是一个初始化的方法,用来初始化Servlet
service:服务,这个方法用来执行Servlet服务 数据的接收以及页面的跳转。(所有操作都在service中进行)
Service方法可以接收任意请求方法类型的数据(get/post)。
destory:销毁,这是一个Servlet销毁的时候执行的方法。
doGet 接收get请求信息
doPost 接收Post请求信息
doDelete....
Do系列的方法都是从Service方法根据不同的请求类型拆分出来的。
我们在写代码的时候,要么写doGet/doPost 要么写Service 不能都写。
关于Servlet生命周期【面试题】
生命周期 : 从创建到销毁的一个过程。
指Servlet创建到销毁的过程。
Servlet的生命周期一共分为三个阶段
第一阶段:初始化阶段
初始化是有Tomcat执行的
共初始化1次。
·第一个请求数据会初始化。
·或者配置load-on-startup 时只要值>0 会在Tomcat启动的时候直接初始化。
第二阶段:运行阶段
只要初始化了之后Service()方法可以运行N次。
第三阶段:销毁阶段
只销毁1次。
- 服务器关闭会执行销毁
- 当前java类重新编辑并保存后会执行销毁然后创建新的Servlet
Get与Post请求的区别
Get和Post可以分别写出,效果和service() 是一样的,如果单独写Get和Post的话,建议在get中调用post方法并传入参数,这样不管是get还是post方法都会归入post执行。
表单中get方法与post方法请求的区别
get方式传参会将表单中的信息使用URL拼接的方式显示到浏览器的地址栏中,不安全
post传参不会暴露信息
get方式属于URL参数传递信息会以 ? 的形式进行拼接,多个参数使用 & 进行拼接
post会将信息放在请求主体中,这样的信息是不会暴露的。
get传参数有长度限制,超过限制后直接报错。
post传参长度不受限制。
get方式传递参数浏览器会直接缓存数据,无论多重要的信息浏览都会缓存
Post方式浏览器不会直接缓存到重要信息,比较安全。
GET唯一的好处就是比post快。
url-pattern
在web.xml中是暴露请求地址的配置,页面会直接请求暴露的这个地址,如果匹配会向Servlet中请求,如果找不到直接404错误,from表单中的action里填写的内容必须和url-pattern标签之间的内容保持一致
404 : 资源未发现(路径错误)
500 : 服务端异常 90%是Java类中空指针。
url-pattern 常见的几种书写方式
/路径 (最常见的)
注意如果在from表单中的action中也写”/”的话意思是转向上一层目录,也就是直接到了项目名那里,没有指定具体的HTML页面就会报404异常
/路径/路径...
/* 通配的形式一般不用
*.do 这种通配的形式是可以使用,后缀可以自定义 (还是可以使用的)
XML
XML头信息 必须存在的
<?xml > 声明当前文件是XML文件
version 声明当前XML版本 1.0
encoding 编码格式 声明当前XML中的编码格式
XML中发现了一些特殊的信息,这些信息叫“约束” ,法律法规。
XML定义标签时的规范
HTML不区分大小写,但是XML大小写敏感。
XML中标签不能使用关键字 例如:XML 、version等...
XML中标签需要正确嵌套 开始标签和结束标签
XML中定义标签不能以数字开头
HTML中可以有多个根目录约束不严格可以有多个根(HTML)标签,XML只能有一个唯一的一个根标签。
创建一个XML文件
XML是作为数据传输使用的类型。
<?xml version="1.0" encoding ="utf-8" ?>
<!-- 根节点 -->
<books>
<book xh ="1">
<book_name bm="石头记">红楼梦</book_name>
<book_author>曹雪芹</book_author>
<book_price>500</book_price>
</book>
<book xh ="2">
<book_name bm="教育资料">金瓶梅</book_name>
<book_author>佚名</book_author>
<book_price>9.9</book_price>
</book>
<book xh ="3">
<book_name>坏蛋是怎样炼成的</book_name>
<book_author>六道</book_author>
<book_price>88</book_price>
</book>
</books>
数据传输的时候可以直接将整个文件传到指定的位置,但是读取文件的时候需要使用Java中解析文件的技术-dom4J。xml是一个属性文件,读取他的内容和properties很像,都是需要先获取字节输入流然后。。。
import java.io.InputStream;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Before;
import org.junit.Test;
//从xml中读取信息
public class dom4J {
Document doc = null;
@Before
public void dom() throws Exception {
//1.定义一个解析器。类似于c3p0等从properties文件中读取信息一样,我们也需要借助流来从xml读取信息
SAXReader reader = new SAXReader();
//2.获取xml文件的输入流对象
InputStream is = dom4J.class.getClassLoader().getResourceAsStream("book.xml");
//3.把输入流传入解析器中,获取book文件的document对象
doc = reader.read(is);
}
@Test//获取根节点的名称
public void t01() {
Element root = doc.getRootElement();
System.out.println(root.getName());
}
@Test//获取根节点下的子节点,要获取子节点首先要获取根节点,然后一级一级往下找
public void t02() {
Element root = doc.getRootElement();
@SuppressWarnings("unchecked")
List<Element> list = root.elements();
for(Element e:list) {
//获取子节点的名称
System.out.println(e.getName());
//获取当前book标签的属性 -根据索引获取属性对象
Attribute attr = e.attribute(0);
System.out.println(attr.getName()+":"+attr.getValue());
//可以直接根据属性名称获取值
String value = e.attributeValue("xh");
System.out.println(value+"---");
}
}
@Test//获取书名
public void t03() {
//首先获取根标签
Element root = doc.getRootElement();
//然后获取下一级节点的对象
@SuppressWarnings("unchecked")
List<Element> list = root.elements();
for(Element e:list) {
//再获取他下一级的标签的对象
@SuppressWarnings("unchecked")
List<Element> list2 = e.elements();
for(Element e2:list2) {
//打印这一级标签中的所有内容
String text = e2.getText();
System.out.println(text);
//打印所有属性为bm的值,通过判断过滤掉了为null的值
String value = e2.attributeValue("bm");
if(null != value) {
System.out.println("别名为:"+value);
}
}
}
}
}
XPath技术
Dom4J为了让解析XML更加方便采用的全局搜索这样的一个功能,需要导包这个技术是依赖Dom4J
Dom4J提供两个方法给XPath使用
doc.selectNodes(); //检索节点返回集合
doc.selectSingleNode(); //检索节点返回单个对象
xpath需要先使用Dom4J获取当前的Document对象才能继续操作。
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Before;
import org.junit.Test;
public class xpathDemo {
Document doc = null;//因为要给下面的方法使用,所以先定义为成员变量
@Before
public void bf() throws Exception {
InputStream is = xpathDemo.class.getClassLoader().getResourceAsStream("book.xml");//获取输入流
SAXReader reader = new SAXReader();//获取解析器
doc = reader.read(is);//将输入流传入解析器
}
@Test //根据当前标签路径取值
public void t01() {
//xpath最重要的就是表达式的书写,类似于SQL语句中的选择器
Node node = doc.selectSingleNode("/books");//当明确返回的个数为1个时可以使用selectSingleNode
System.out.println(node.getName());
}
@Test //获取书名
public void t02() {
@SuppressWarnings("unchecked")
List<Element> list = doc.selectNodes("/books/book/book_name");
for(Element e:list) {
System.out.println(e.getText());
}
}
@Test //更简单的方式获取书名
public void t03() {
@SuppressWarnings("unchecked")
List<Element> list = doc.selectNodes("//book_name");//双斜线可以忽略层级关系直接找到对应标签
for(Element e:list) {
System.out.println(e.getText());
}
}
@Test //获取书名+作者+价钱
public void t04() {
@SuppressWarnings("unchecked")
List<Element> list = doc.selectNodes("//book/*");//双斜线可以忽略层级关系直接找到对应标签
for(Element e:list) {
System.out.println(e.getText());
}
}
@Test //取book下子元素中第二个元素
public void t05() {
@SuppressWarnings("unchecked")
List<Element> list = doc.selectNodes("//book/*[2]");//双斜线可以忽略层级关系直接找到对应标签
for(Element e:list) {
System.out.println(e.getText());
}
}
@Test //获取书的别名
public void t06() {
@SuppressWarnings("unchecked")
List<Element> list = doc.selectNodes("//book/*[1]");//双斜线可以忽略层级关系直接找到对应标签
for(Element e:list) {
if(null != e) {
System.out.println(e.attributeValue("bm"));
}
}
}
@Test //获取别名为石头记的书名
public void t07() {
Node node = doc.selectSingleNode("//book_name[@bm='石头记']");//双斜线可以忽略层级关系直接找到对应标签
System.out.println(node.getText());
}
@Test //统计一共有几本书
public void t08() {
@SuppressWarnings("unchecked")
List<Element> list = doc.selectNodes("//book");//双斜线可以忽略层级关系直接找到对应标签
System.out.println(list.size());
}
}
总结
Servlet详解
生命周期
Servlet的生命周期一共分为三个阶段:
第一个阶段为初始化阶段,此阶段共初始化一次,默认是第一次请求的时候初始化,如果配置了load-on-startup 值只要大于0 会在服务器启动的时候直接初始化。
第二个阶段为运行阶段,这个阶段可以请求无数次,调用service方法。
第三个阶段为销毁阶段,次阶段共销毁一次,默认是服务器关闭的时候销毁。如果项目中类或者资源文件发生改变导致重新编译,那么会执行销毁操作。
Get和post区别
get请求是一个不安全的请求,传递的参数信息是直接拼接到URL中,这样会导致信息泄露并且长度有限制,浏览器也会默认缓存请求信息。 唯一好处是速度快。
post 请求是安全的请求,长度不受限制并且浏览器不会泄露数据,坏处是比get慢一点。
XML
Dom4J解析步骤
1.先定义一个解析器 new SaxReader();
2.获取XML文件输入流信息
3.调用解析器的.read(流)返回一个Document对象。
4.先读取到根节点然后顺藤摸瓜即可。
Xpath
前三步同上
4.两个方法+表达式
doc.selectNodes(表达式);
doc.selectSingleNode(表达式);