JDBC
概念&作用
java data base connectivity(简称jdbc) java数据库连接;
是一种用于执行SQL语句的java API;
sun公司提供的一套规范(接口),类,用来连接到数据库的;
数据库驱动: 两个设备(应用)之间通信的桥梁.
注意
注册驱动:因为Driver类的静态代码中调用了DriverManager.registerDriver()方法,所以 直接加载类即可Class.forName("com.mysql.jdbc.Driver") //加载MySQL驱动
DriverManager(驱动管理类)
注册驱动
DriverManager.registerDriver(new Driver());
此方式不使用,存在两方面不足
1) 硬编码,后期不易于程序扩展和维护
2) 驱动被注册两次。原因:实现类源码,静态代码块已经调用此方法进行注册
获取数据库连接对象
方法:static Connection getConnection(String url, String user, String password)
静态修饰的方法,返回一个Connection接口的对象
url数据库地址:"jdbc:mysql://数据库服务器主机地址:端口号/数据库名"
jdbc是连接数据库的协议。
mysql是jdbc的子协议(用来区分连接的不同的数据库的)
user:与数据库连接的用户名
password:与数据库连接的密码
连接本地可简写:"jdbc:mysql:///数据库名"
Connection(接口,连接数据库)
作用一:创建执行SQL语句的对象
方法:
Statement createStatement() 实际开发不会使用,有sql注入漏洞
CallableStatement prepareCall(String sql) 执行数据库中存储过程
PreparedStatement prepareStatement(String sql)
创建一个 PreparedStatement 对象执行SQL,会对SQL进行预处理,解决SQL注入漏洞
作用二:管理事务
方法:
void setAutoCommit(boolean autoCommit) ;
设置是否自动提交事务;//设置为false,相当于开启事务,后面的execute可以commit或rollback
void commit() 提交事物
void rollback() 回滚事物
事物的核心思想:一组业务逻辑的操作要使用同一个Connection对象;
事物管理的操作步骤:
1.开启事物
2.具体业务逻辑
3.有一步不成功回滚事物
4.都成功,提交事物
Statement 接口(开发不用)
作用一:执行SQL
int executeUpdate(String sql)
执行(insert,update,delete)的SQL语句,返回影响的行数
ResultSet executeQuery(String sql)
执行(select)的SQL语句,返回ResultSet(结果集)
作用二:执行批处理
需在url后添加参数 "rewriteBatchedStatements=true"
addBatch(String sql) //将SQL添加到批处理
clearBatch() //清空此对象的当前SQL命令列表
executeBatch() //将一批命令执行,不会清空批处理
PreparedStatement接口(执行SQL)
继承Statement接口
作用:执行sql语句
int executeUpdate()
执行(insert,update,delete)的SQL语句,返回影响的行数
ResultSet executeQuery()
执行(select)的SQL语句,返回ResultSet(结果集)
setXxx(int,值) 设置?占位符参数。位置从1开始
示例:
String sql = "delete from user where id = ?"; //编写sql语句
pstmt.setInt(1, 4); //对sql语句设置值
模糊查询的时候把 (like '%李') 直接写成(like ?) 在设置参数的时候写("%李")就可以实现了
批处理:
void addBatch() //将SQL添加到批处理
void clearParameters() //清空批处理
prepareStatement对象中,批处理中的sql只执行一次
ResultSet接口(结果集)
作用:结果集对象,通过select语句的查询结果获得;
遍历的方法: boolean next(); 将光标从当前位置向下移一行,没有数据返回false;
获取的方法:
getXXX(int columnIndex);参数传入数据库的列号;
getXXX(String columnName); 参数传入数据库的列名(如果有取别名要写别名)
JDBC释放资源
Connection对象要做到尽量晚创建,尽早释放.
通常有:ResultSet,Statement,Connection。
释放资源的代码写入finally代码块中
标准的释放资源方式:
if(对象!=null){
try{
对象.close();
}catch(SQLException e){
e.printStackTrace();
}
对象=null; //断开引用指向,可以尽早回收不用的资源
}
配置文件
1. 属性文件
格式:扩展名是.properties
内容是: key=value形式存在的
2. XML文件
Properties类(获取属性文件内容)
方法:
void load(InputStream inStream); 传入一个输入流;
参数可以写成: new FileInputStream("配置文件的路径")
得到的是一个键值对类型的数据
getProperty(String key) ; 参数传入键,通过指定的键获取到值;
连接池
概念: 连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。
产生原因: 连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。
自定义连接池
DataSource接口: 连接池接口; 是在in.javax.sql.DataSource包下的;
实现步骤:
1. 编写一个类 实现DataSource接口
2. 创建一个容器(集合)用来存连接对象;
3. 写一个构造方法用来初始化时获得一些连接,并存入定义的容器内
4. 重写DataSource中的getConnection方法,获取容器中的连接并返回;
5. 归还连接; 使用装饰者模式增强Connection中的close方法
开源连接池
Druid连接池
概述: 阿里旗下开源连接池,可以与Spring框架进行快速整合.
DruidDataSource核心类
替换了原来连接部分和释放资源部分
使用步骤:
//代码实现
//导入jar包
//加载连接数据库的配置文件
Properties pr = new Properties();
pr.load(new FileInputStream("配置文件路径"));
//获取连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(pr);
//或取连接
Connection conn = dataSource.getConnection();
Druid配置文件
配置文件的文件名称没有具体规定但是配置文件的Key是规定好的
# 配置文件中的#是注释
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=
#<!-- 初始化连接数量 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
C3P0连接池
使用方法:
//导入jar包
//配置文件
//创建连接池,默认去类路径(src)下查找c3p0-config.xml文件
//可以在括号内传入指定的配置名称,就会去找指定的,传入有误,会去找默认的配置
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//从连接池中获得连接
Connection conn = dataSource.getConnection();
配置文件
文件名称必须是c3p0-config.xml默认才会找到
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web_test4</property>
<property name="user">root</property>
<property name="password">123</property>
<property name="initialPoolSize">5</property><!-- 初始化连接数量 -->
<property name="minPoolSize">5</property><!-- 最小空闲连接 -->
<property name="maxPoolSize">20</property><!-- 最大空闲连接 -->
</default-config>
<!-- This app is massive! -->
<!-- 指定名字的配置
<named-config name="oracle">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web_test4</property>
<property name="user">root</property>
<property name="password">abc</property>
</named-config> -->
</c3p0-config>
DBUtils
DBUtils:封装并简化JDBC,不影响性能。简化JDBC的编程
QueryRunner 类。核心运行类,用于执行CRUD
//执行没有事物的CRUD操作,使用有参构造
QueryRunner(DataSource ds);//构造方法//传入一个连接池对象
int update(String sql,Object… args); //执行增删改
T query(String sql,ResultSetHandler rsh,Object… args); //执行查寻。T为处理的结果集
//代码示例: args是可变参数,给问号设置值的
queryRunner.update("update account set name=?,money=? where id =?", "eee",20000,4);
List<Accout> list = queryRunner.query("select * from account",new ResultSetHandler<List<Accout>>(){})
//批处理
int[] batch(Connection conn,String sql,Object[][] params)
itn[] batch(String sql,Object[][] params)
//有事务管理的CRUD的操作方法
//构造:
QueryRunner();
//方法:
int update(Connection conn,String sql,Object… args);
T query(Connection conn,String sql,ResultSetHandler rsh,Object… args);
DBUtils类 工具类
//事务操作
closeQuietly(Connection conn); //安静的关闭
commitAndCloseQuietly(Connection conn) //提交并安静的关闭,安静的关闭就是自动处理异常
rollbackAndCloseQueitly(Connection conn)//回滚并安静的关闭,安静的关闭就是自动处理异常
ResultSetHandler的实现类(用来封装数据的)
MapHandler//将一条记录封装到一个Map集合中,Map的key是列名,Map的value就是表中列的值。
MapListHandler//将多条记录封装到一个装有Map的List集合中。
//代码示例
QueryRunner queryRunner = new QueryRunner(传入一个连接池对象);
Map<String,Object> map = queryRunner.query("select * from user where id=?",new MapHandler(),1);
List<Map<String,Object>> list = queryRunner.query("select * from user",new MapListHandler());
注意:泛型的类型是<String,Object>因为Map的key是列名,用String类型;Map的value就是表中列的值,值是不确定的所以用Object
BeanHandler//将一条数据封装到一个指定的JavaBean中
BeanListHandler//将每一条数据封装到一个JavaBean中,在将多个JavaBean的实例封装到一个List集合中
//代码示例:
QueryRunner queryRunner = new QueryRunner(传入一个连接池对象);
User user = queryRunner.query("select * from user where id=?",new BeanHandler<User>(User.class),1);
List<User> list = queryRunner.query("select * from user",new BeanListHandler<User>(User.class));
注意:
<User>(User.class)这一部分是根据具体的JavaBean类名定的,要封装到那个类泛型就是那个类;获取字节码就用这个类
表和实体类的名字不一致的话,查询的时候取别名,跟类名一直,就可以查到,否则得不到数据
默认会调用无参构造,JavaBean中要么不初始化构造,要是初始化了构造必须给无参的
ScalarHandler//用来封装单个值的。例如select count(*) from 表名(返回long类型)。
//代码示例:
Object obj = qr.query("select count(*) from user", new ScalarHandler());
//虽然他的返回值是long类型但是想要用long类型来接收要强转
long obj = (long) qr.query("select count(*) from user", new ScalarHandler());
(不怎么用)ColumnListHandler 将结果集指定的列的字段值,封装到一个List集合中
构造 (String columnName)
返回 List<Object>
ArrayHandler//将获取到的一条记录封装到一个Object数组中
//代码示例:
Object[] objs = queryRunner.query("select * from account where id = ?",new ArrayHandler(),1);
ArrayListHandler//将获取到的每一条记录封装到一个Object数组中,在将每一个数组封装到List集合中
List<Object[]> list = queryRunner.query("select * from account",new ArrayListHandler());
BeanUtils
Apache commons提供的一个组件,主要功能简化JavaBean的封装数据的操作
使用:
导入jar包
commons-beanutils-1.8.3.jar
commons-logging-1.1.1.jar
BeanUtils 工具类
setProperty(Object bean,String name,Object vlaue) //给指定Bean对象指定变量 赋值
String getProperty(Object bean,String name) //获取指定对象指定变量 值
populate(Object bean,Map properties) //通过Map批量给指定对象 多个变量赋值。map中找不到对应关系的成员会忽略
注意:setProperty()和getProperty()底层 不是直接操作变量,而是操作有关get和set方法
XML
概述: 可扩展的标记语言,允许用户自定义标签;
作用:
1.软件的配置文件
2.传输和存储数据
语法
基本语法:
必须有关闭标签
区分大小写
属性需要有引号
标签必须正确嵌套
文档声明:
通常在第一行第一列
写法:<?xml 属性名=”属性值” 属性名=”属性值” ...?>
version : 必须要写的. 使用”1.0”
encoding :字符集. 是使用浏览器打开的时候采用的默认的字符集的编码.
standalone :描述XML文档是否需要依赖其他的文件.
注释: <!-- XML的注释 -->
元素(标签)的命名规则:
可以包含字母,数字以及其他字符
不能以数字,标点符号和"xml"(大小写都不行)开头
不能包含空格和冒号(:)
属性的命名规则:
跟元素的名称规范一致;
属性需要使用引号;
特殊字符和CDATA区
特殊字符:
< 小于 > 大于 & 和号(&) &apos 单引号 " 引号
XML的CDATA区:(CDATA:Character Data)(写字符数据)
写法: <![CDATA[具体内容]]>
XML的解析
解析:通过代码完成从XML文档中获得想要的数据
解析的方式:
- DOM解析:Document Object Model.
- SAX解析: Simple Api for XML.
DOM和SAX的区别:
DOM:是一次性将文件加载到内存,形成树形结构进行解析.
缺点: 如果文档特别大,容易导致内存溢出
优点: 可以对XML进行增删改的操作
SAX:事件驱动的方式,一行一行进行解析的
缺点:不能对文档进行增删改的操作
优点:如果文档特大时,不会导致内存溢出
针对这两种解析的方式,不同的公司提供了不同的API的实现.
JAXP :SUN公司提供的一套XML的解析的API.
JDOM :开源组织提供了一套XML的解析的API-jdom.
DOM4J :开源组织提供了一套XML的解析的API-dom4j.
pull :主要应用在Android手机端解析XML.
DOM4J+XPath的结合使用:
//创建解析器(他的底层是融合了DOM和SAX两种方式,取出他们的优点)
SAXReader reader = new SAXReader();
//解析XML返回Document对象.
Document document = reader.read("获得xml文件的任何方式");
//获得节点的方法
List document.selectNodes("xpath表达式");//返回一个List的集合
Node document.selectSingleNode("xpath表达式")//返回一个元素
Element 接口
//属性操作
String attributeValue("属性名") //获取指定属性名的属性值
//元素操作
List<Element> elements() //获取所有的子元素
(String name) //根据指定的元素名称获取子元素
Element element("子标签名") //根据子元素名称获取子元素对象
//文本操作
String elementText("子标签名") //根据子元素名称获取子元素中文本
String getText() //获取当前元素对象的文本
setText() //设置当前元素对象的文本
——xpath表达式
/xxx //分层级查找xxx元素
//xxx //不分层级查找xxx元素
xxx[@属性名] //包含此属性的元素
xxx[@属性名='属性值'] //包含此属性和值的元素
DOM4J的使用
//通过DOM解析实现的代码:
//导入jar包
//创建解析器(他的底层是融合了DOM和SAX两种方式,取出他们的优点)
SAXReader reader = new SAXReader();
//解析XML文档,获得document对象
Document document = reader.read("XML文档的路径");
//必须获得根节点
Element root = document.getRootElement();
//获得根节点后就可以找他下面的子节点和文本了
//查找根节点下的子节点的方法;
//element("指定的元素") 返回的是找到的一个元素
//elements("指定的元素");返回的是所有匹配的元素,放到一个List集合中
Element pElement = root.element("指定的元素"); // 查找的是第一个指定的元素
root.elements("指定的元素").get(指定索引); // 查找的是指定索引的指定元素
//元素.getText(); 获得到指定元素的文本;
XML的约束(了解)
XML的约束的种类及区别
DTD 和 Schema
区别:
1.DTD语法是自成一体的.Schema语法就是XML的语法.
2.Schema的语法就是XML的语法所以更容易被解析器所解析.
3.Schema支持名称空间.
4.Schema有比DTD更加强大的语义和语法的约束.
Schema中的名称空间;
名称空间:一个XML只能引入一个DTD约束文档.使用了Schema约束XML文档,一个XML可以引入多个Schame的约束!!!
名称空间类似于java中的package.通过名称空间区分 标签或属性来自于哪个文档的!!!通常名称空间唯一的不重复的即可.一般情况下使用一个URL地址表示一个名称空间.
一个名称空间对应一个约束,一个xml文件可以有多个名称空间
想用那个名称空间就要在标签上以这个名字开头
Tomcat服务器
软件的架构
C/S架构的软件:
Client/Serever客户端和服务器端的软件;需要在PC端安装的软件
优点:效果炫;速度快(一部分代码写在客户端的)
缺点:服务器端更新,客户端都需要更新
B/S架构的软件:
Rrowser/Serever浏览器端和服务器端的软件.不需要安装,只需要一个浏览器即可.
优点:服务器端更新,客户端不需要进行更新
缺点:效果不炫,所有代码运行都在服务器端,导致服务器压力过大
效果:使用HTML5,CSS3也可以做出
服务器端压力:搭建服务器的集群,AJAX技术;
AJAX技术:可以异步的获取服务端的数据
wed的资源
静态资源: HTML CSS JS 图片...
动态资源: PHP ASP Servlet/JSP
服务器
硬件:一台配置高的电脑
软件:安装服务器的软件
常见的web服务器(中间件)
WebSphere(was): IBM公司研发,收费的大型服务器软件,支持EE的所有的开发规范.
WebLogic: BEA公司研发,收费的大型服务器软件,支持EE的所有的开发规范.
Tomcat: Apache组织研发,免费的小型的服务器软件,支持Servlet/JSP的开发规范.
Apache: 发布PHP的.
IIS: 发布ASP的.
JBoss:
web动态资源目录结构(2.5的规范)
一个动态网站下必须有WEB-INF文件夹,这个文件夹下必须有wed.xml文件
website(假设这个是一个动态网站)
|----- WEB-INF(这个目录(文件夹)必须有)
|----- 静态资源(放根目录下)
|-----web.xml(文件) :必须的(2.5中)
|-----classes :可选的(java类生成的class文件)
|-----lib :可选的(第三方的jar包)
Tomcat的安装&介绍
Tomcat的安装
下载: http://tomcat.apache.org/download-70.cgi
安装: 解压即可
Tomcat的目录结构
bin :tomcat的执行的文件.
conf :tomcat的配置文件.
lib :tomcat运行的需要的jar包.
logs :tomcat的运行的日志文件.(错误信息,启动时间等的一些信息)
temp :tomcat产生临时文件存放的路径.
webapps :tomcat发布的web项目的路径;(web项目发送到此目录下)
work :tomcat运行JSP的时候,JSP翻译成Servlet的代码存放的路径.
backup :备份的文件
server.xml是Tomcat的核心文件,不能瞎改动;
发布wed工程到Tomcat的方式
~方式一:直接将项目copy到webapps下即可;
~方式二:配置tomcat的虚拟路径-不推荐
在tomcat/conf/server.xml文件中进行配置:
在<Host>标签下配置:
<Context path="/取一个虚拟路径" docBase="本地网站存放的路径"/>
*方式三:配置tomcat的虚拟路径-推荐
在tomcat/conf/Catalina/localhost/下创建一个xml文件(xxx.xml)
在这个xml文件中配置<Context docBase="本地网站存放的路径"/>
xxx(xml的文件名)作为虚拟路径的名称.
*方式四:把项目打成.war包,放到webapps下,服务器启动,会自动解压(开发会用);
在eclipse中以war包导出即可
Tomcat常见问题
没有配置JAVA_HOME环境变量引发tomcat一闪消失;
端口号冲突的问题
解决:
1.将占用端口的应用结束
在cmd下输入netstat -ano查看端口使用信息
打开任务管理器结束对应端口的应用程序
PID就是进程的id
2.修改自身应用的端口号
在tomcat/conf/server.xml中进行更改
使用编辑器打开startup.bat文件,在文件的最后写上pause用来暂停窗口,在启动时可以看到错误的信息;
HTTP
HTTP的简介
概念:超文本传输协议;所有www文件必须遵守,用来规定浏览器与服务器之间要遵循的规则
作用:规范浏览器和服务器之间的数据传递
特点:
基于请求和响应的模型:
必须先有请求后有响应
请求和响应必须成对出现
默认端口号是80
版本:
1.0 每次响应后立刻关闭了连接
1.1 现在主要使用.不是每次响应后挂断;等待长时间以后没有请求会自动挂断.
HTTP协议的抓包分析
请求部分
请求行:
*提交方式:
提交方式有很多,常用的有get和post
get和post的区别:
get提交的参数会显示到地址栏,而post不显示
get是有大小限制的,而post没有大小限制
get没有请求体,而post有请求体
get参数在地址的后面: ?name=value&name=value
超链接是get提交方式
默认是get提交
get提交方式: location.href="路径";
提交路径:
协议版本:
请求头:
格式:都是键值对形式显示的,一般一个key对应一个value,也有个别的是一个key对应对个value的
*常用的请求头:
User-Agent :代表客户端浏览器的类型;
作用:文件下载;下载中文时,IE使用URLEncodor进行编码,Firefox(火狐)使用Base64进行编码;
不同的浏览器的编码不同,可以通过查看这个头来确定客户端浏览器的编码,给出指定的编码,从而解决文件下载乱码
Referer :代表的是网页的来源. 防盗链(防止别人盗链接)
If-Modified-Since :通常与响应中的头Last-Modified一起使用查找本地缓存
请求体: 就是POST提交方式提交的参数.
响应部分
响应行:
协议版本
*状态码
200 成功
302 重定向
304 查找本地缓存
404 资源不存在(检查路径)
405 访问的方法不存在
500 服务器内部错误
状态码的描述
响应头:
格式:键值对,一般一个Key对应一个value,也有一个key对应多个value的
*常用的响应头:
Last-Modified 与请求中的If-Modified-Since一起使用查找本地缓存
Content-Dispostion 文件下载的时候使用的一个头信息;
Location 重定向的跳转的路径
Refresh 定时刷新/定时跳转
响应体: 显示浏览器的页面的内容
Servlet
简介
概述:一个运行在WEB服务器上的小的Java程序(类),用来接收和响应从客户端发送过来的请求,通常使用HTTP协议
SUN公司提供的一个动态网页开发技术
作用:处理从客户端浏览器发送的请求,并且可以对请求做出响应
使用:
编写一个类实现Servlet接口
将编写的这个类配置到服务器中;在web的xml里进行配置
配置Servlet
<!--在当前项目下的WEB-INF文件夹下的web.xml中进行配置-->
<!-- 配置Servlet -->
<servlet>
<!-- Servlet的名称 --> 名称随意
<servlet-name>名称</servlet-name>
<!-- Servlet的全路径 -->(全类名)
<servlet-class>要配置的类的全类名</servlet-class>
</servlet>
<!-- Servlet的映射 -->
<servlet-mapping>
<!-- Servlet的名称 -->上下两个名称要一致
<servlet-name>名称</servlet-name>
<!-- Servlet的访问路径 -->可以随意写,访问时候写的路径
<url-pattern>/访问路径</url-pattern>
</servlet-mapping>
<!--url-pattern路径的配置:
1.完全路径匹配 以 / 开始 例如/ServletDemo4
2.目录匹配 以 / 开始 需要以 * 结束(*代表通配符) 例如/* /aaa/*
3.扩展名匹配 以 * 开始,不能用/开始 例如 *.do *.action
执行顺序: 1 > 2 > 3
-->
<!--配置服务器启动时创建Servlet-->
<servlet>
<!--传入的整数越小被创建的优先级就越高;最好从2开始,1默认服务器启动时会创建,用来出输出一些404之类的信息-->
<load-on-startup>正整数</load-on-startup>
</servlet>
<!--全局初始化参数的配置-->
<context-param>
<param-name>名字</param-name>
<param-value>值<param-value>
</context-param>
<!--初始化参数的配置使用这个标签-->
<init-param>
<param-name>名字</param-name>
<param-value>值</param-value>
</init-param>
<!--session存活时间的配置-->
<session-config>
<session-timeout>时间(单位是分钟)</session-timeout>
</session-config>
<!--设置全局的错误友好页面-->
<error-page>
<error-code>错误状态码</error-code>
<location>/要跳转的路径</location>
</error-page>
Servlet接口
void init(ServletConfig config) //初始化;Servlet服务器自动调用,就执行一次
void service(ServletRequest request,ServletResponse response) //接收请求和发出响应。每请求一次,服务器创建一个线程,执行一次
void destroy() //销毁。servlet被移除或服务器关闭时执行一次
ServletConfig getServletConfig() //获取当前servlet的配置对象
ServletContext getServletContext() //获取当前项目ServletContext对象
ServletRequest接口
概述: 用于接收客户端的请求数据;
还有一个子接口: HttpServletRequest
功能一: 获得与客户机相关的信息
*获得请求方式: String getMethod();
*获得客户机的ip地址: Sting getRemoteAddr();
*获得工程名: String getContextPath()
获得请求的路径:
String getRequestURI();从工程下的路径
StringBuffer getRequestURL()获得是带有协议的全路径
功能二: 获得从页面中提交的参数
String getParameter(String name);传入表单名,用于接收一个名称对应一个值的数据
String[] getParameterValues(String neme);传入表单名,用于接收一个名称对应多个值的数据
Map getParameterMap(); 用于接收表单中的所有数据,Map的key是表单提交的参数名称,Map的value是提交参数的值
基本不用(返回一个枚举)Enumeration getParameterNames();用于获取表单中提交的所有的参数的名称;
功能三: 作为域对象存取数据
void setAttribute(String name,Object value);//存数据;存入String类型的名字和Object类型的数据
Object getAttribute(String name);//根据指定的名字获取数据
void removeAttribute(String name);//根据指定的名字删除数据
ServletRequest域对象:
作用范围: 一次请求的范围
创建: 客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象.
销毁: 当服务器对这次请求作出了响应之后
void setCharacterEncoding("编码");设置提交过来的数据的编码;解决post提交中文乱码的方法
ServletResponse接口
概述:代表响应的对象,从服务器向浏览器输出内容
还有一个子接口: HttpServletResponse
响应行操作
void setStatus(int 状态码) //针对于1xx,2xx,3xx
void sendError(int 状态码) //针对于4xx,5xx
响应头操作:
//传进去一个头信息,和一个对应的值
//针对一个key对应多个value的响应头
*addHeader(String key,String value)
addDateHeader(String name,long date)
addIntHeader(String name,int value)
//设置/覆盖响应头,针对一个key对应一个value的响应头
*setHeader(String key,String value)
setDateHeader(String name,long date)
setIntHeader(String name,int value)
示例:
跳转页面,定时刷新的方法:
setHeader("refresh","秒数;url=要跳转的路径");
响应体的操作(向页面输出内容):
ServletOutputStream getOutputStream();字节流的方式(输出流,文件下载使用的多)
PrintWriter getWriter();字符流的方式(输出流)
注意: 这两个方法是互斥的,做出响应的时候只能使用其中一种流响应.
页面跳转: sendRedirect(路径); 设置302重定向;
*ServletContext接口
获得这个类的对象:
在Servlet环境在用: this.getServletContext();得到一个这类的对象
概述:用于存取数据,在整个web工程都可以访问到这个容器的数据(数据共享),是一个域对象
ServletContext是一个域对象.
作用范围:整个web工程.
创建:服务器启动的时候,tomcat服务器为每个web项目创建一个单独ServletContext对象.
销毁:服务器关闭的时候,或者项目从服务器中移除的时候.
作用&方法:
作用一:作为域对象存取数据.
void setAttribute(String name,Object value);//存数据;存入String类型的名字和Object类型的数据
Object getAttribute(String name);//根据指定的名字获取数据
void removeAttribute(String name);//根据指定的名字删除数据
作用二:读取web工程下的文件(读取配置文件固定三步:创建properties对象,load方法读取文件,getProperty()获得文件)
InputStream getResourceAsStream(String path);//根据传入的路径读取文件,返回一个文件的输入流
String getRealPath(String Path);//根据传入的路径,返回一个路径的磁盘绝对路径
作用三:读取全局初始化参数.
String getInitParameter(Sting name)根据指定的名字获得值
Enumeration getInitParameterNames()获得所有的名字,返回一个枚举
作用四:用来获得文件的MIME的类型(文件上传下载使用).
String getMimeType(String file)传入一个文件名,得到他相应的MILE类型
访问方式
访问方式: 协议:ip:端口号/项目名/路径(配置的路径) 访问路径以服务器上的路径为准
web程序是运行在服务器上的
Servlet的生命周期(面试)
默认用户第一次访问Servlet时,服务器创建一个Servlet实例,Servlet中init()方法就会执行;
任何一次请求服务器都会创建一个新的线程执行service()方法,在这个方法内部会根据不同的请求执行不同的doXXX()方法;(get请求调用doGet,post请求调用doPost)
当关闭服务器或从服务器中移除项目时,Servlet的实例就会被销毁,那么destroy()方法就会执行.
Servlet生命周期从始至终只有一个Servlet实例
扩展:单例最好不要定义成员属性,多线程访问的时候,会造成争抢资源,引发线程安全问题;
程序优化的思想
当有一些资源初始化很耗时,并且只在第一次访问时初始化,就可以把这个操作放到服务器启动的时候
路径问题
相对路径: 从自身路径开始找,找的是相对的关系;不能以 / 开始;
./ 当前路径 ../上一级目录
绝对路径: 不需要找位置相对关系;以 / 开始的;
绝对路径中分为客户端路径和服务器端路径:
客户端路径一定要加工程名. /day09/ServletDemo6
服务器端路径不需要加工程名. /ServletDemo6
访问格式:
协议://IP地址:端口号/路径名
类加载器
概念: 类的加载器是用来加载class文件,将class文件加载到内存中
类的加载器读取的是类路径(class在那就加载的是哪)
使用方法: 类名.class.getClassLoader();//获得这个类的加载器
类的加载器对象.getResourceAsStream("路径");//这个方法返回一个InputStream可以用来读取文件
文件下载
手动编写代码完成文件下载的步骤:
1.接收参数
2.完成下载(设置两个头一个流)
设置头Content-Type :文件的MIME的类型.
设置头Content-Disposition :以下载的形式打开文件.
这是固定的: setHeader("Content-Disposition","attachment;filename=文件名");
输入流(路径是服务器上的路径)和输出流(通过响应的方法,这是固定的)
文件下载乱码的解决:
IE浏览器下载中文文件的时候采用的URL的编码.
Firefox浏览器下载中文文件的时候采用的是Base64的编码.
根据客户机不同的浏览器的类型处理中文乱码的问题
request.getHeader("User-Agent");// 通过头获得浏览器的类型
URLEncoder.encode(头信息,编码);设置url的解码
重定向和转发的区别:
1. 重定向的地址栏会发生变化,转发的地址栏不变.
2. 重定向两次请求两次响应,转发一次请求一次响应.
3. 重定向路径需要加工程名,转发的路径不需要加工程名.
4. 重定向可以跳转到任意网站,转发只能在服务器内部进行转发.
转发的方法:request.getRequestDispatcher("不带工程名要跳转的路径").forward(request,response);
重定向的方法: response.sendRedirect("带工程名称的路径");//设置302重定向;
乱码的处理
响应乱码
向浏览器输出中文的乱码的解决方式:
字符流:
*简化的写法:response.setContentType("text/html;charset="UTF-8");
设置浏览器打开的时候的编码
resposne.setHeadet("Content-Type","text/html;charset=UTF-8");
设置response的缓冲区的编码
response.setCharacterEncoding("UTF-8");
字节流(文件下载使用):
设置浏览器默认打开的编码;
resposne.setHeadet("Content-Type","text/html;charset=UTF-8");
设置中文字节取出的时候编码
"中文".getBytes("UTF-8");
请求乱码
无论是GET还是POST提交中文的时候,都会出现乱码.
POST的解决方案:
POST的参数在请求体中,直接到达后台的Servlet.数据封装到Servlet中的request中.request也有一个缓冲区.request的缓冲区也是ISO-8859-1编码.
设置request的缓冲区的编码:
request.setCharacterEncoding(“UTF-8”); 一定要在接收参数之前设置编码
GET的解决方
*3使用String的构造方法
String(byte[] bytes,String charsetName)通过使用指定的charset解码指定的byte数组,构造一个新的String
示例: String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8")
---
会话技术
概述: 用户打开一个浏览器访问了很多页面访问完成后将浏览器关闭,这一过程就是一次会话
常用的会话技术:
Cookie : 将数据保存到客户端浏览器;有大小和个数的限制的
Session : 将数据保存到服务器端浏览器;只要服务器内存足够大是没有限制的
作用: 将一些私有的数据保存到回话技术中
Cookie
Cookie的存活时间:
会话级别的Cookie: 默认的Cookie.关闭浏览器Cookie就会销毁.
持久级别的Cookie: 可以设置Cookie的有效时间.那么关闭浏览器Cookie还会存在. 手动销毁持久性
手动销毁持久级别的Cookie方法:
从新设置一个路径一致,有效期为0的Cookie在存入进去就删除了当前的Cookie;
创建Cookie对象:
Cookie(String name,String value);
获得名字: String getName();
获得值: String getValue();
设置有效路径: setPath(String path);//传进去一个路径(可以用来删除Cookie)
设置有效时间: setMaxAge(int maxAge)//传进入一个int类型的数据(以秒为单位)
设置有效域名: setDomain(String domain);
缺点: 人为可以清除数据
向浏览器保存数据:
使用HttpServletResponse的方法: void addCookie(Cookie cookie);
获得浏览器带来的Cookie:
使用HttpServletRequest的方法: Cookie[] getCookies(); //返回一个Cookie数组
Cookie中存储中文的解决方法:
不能直接存取中文,需要进行编码和解码
方法:
存入的时候: String URLEncoder.encode("指定的中文","指定的编码"); //进行编码
获取的时候: String URLDecoder.decode("要解码的数据","指定的编码"); //进行解码,使用的编码要和存入的一致
HttpSession
执行原理: Session是基于Cookie的,通过Cookie保存Session的id
获取: request.getSession();
销毁: session.invalidate();
HttpSession域对象
创建: 服务器第一次调用getSession(),的时候;
销毁:
1. Session过期;默认过期时间为30分钟;(可以在web.xml中进行配置)
2. 非正常关闭服务器;正常关闭session会序列化到硬盘
3. 手动调用session.invalidate();或销毁
作用范围: 一次会话(多次请求);
因为存session id的是Cookie,cookie的默认存活时间为一次会话,当一次会话结束后
cookie销毁session的id也就没有了,在访问时服务器会默认在创建一个新的
方法:
void setAttribute(String name,Object value);//存数据;存入String类型的名字和Object类型的数据
Object getAttribute(String name);//根据指定的名字获取数据
void removeAttribute(String name);//根据指定的名字删除数据
---
JSP
概述: Java Server Pages(java服务器页面)
JSP = Java代码 + HTML的元素 + JSP内置东西
作用: 动态的网页开发技术
执行过程: JSP会被翻译成Servlet,在编译成class进行执行
嵌入代码的方法:
<% %> : 翻译成类的service方法内部的内容;可以在里面定义变量,类或直接写代码块
<%= %> : 翻译成service方法内部的out.print();尖括号内写什么就输出的是什么;
动态获得项目名的方法:
${ pageCoontext.request.contextPath }
(面试点)静态包含和动态包含的区别?(<%@ include%>和<jsp: include>的区别)
区别: 静态包含相当于代码的copy,直接将被包含的代码复制过来,进行编译执行
动态包含是各自编译,各自执行,最终是包含的执行结果
注释 谨记: 什么样的代码用什么样的注释
JSP的指令
语法: <%@ 指令名称 属性名称="属性值"...%>
三大指令:
page指令 <%@ page%> 设置jsp的
属性:
`errorPage : 设置出现错误后跳转的页面
`isErrorpage : 设置显示JSP的错误信息,默认是false;
*include指令 指示jsp去包含其他页面(静态包含)
用法: <%@ include file="被包含的页面路径"%>
注意: 被包含的页面中只写被包含的内容就行
taglib指令 指示jsp引入标签库
用法: <%@ taglib url="标签的URL的路径" prefix="标签的别名" %>
*JSP的内置对象
概述: 可以直接使用的对象
共有9大内置对象(面试点):
内置对象 真实对象 方法
request HttpServletRequest setAttribute(String name,Object value); getParameter(),
response HttpServletResponse setHeader(String name,String value); getOutputStream(); getWriter();
session HttpSession setAttribute(); getAttribute();
application ServletContext setAttribute(); getAttribute();
page Object toString(); wait();
pageContext PageContext setAttribute();getAttribute();
config ServletConfig getServletName();getServletContext();
out JspWriter write(),print();
exception Throwable getMessage(),getCause();
page内置对象: 真实对象是Object,代表this,就是JSP翻译成Servlet后的类的引用
out内置对象: 向页面输出内容
out和response.getWriter都可以向页面输出,他们是同一个对象吗?有什么区别?
不是,out的真实对象是JspWriter;response获得Writer的是PrintWriter
区别: 所有的响应都只能由response对象来做,out输出的东西也是交由response输出的
pageContext内置对象
作用一: 获得其他8个内置对象
用途: 编写通用性的代码或者框架的时候用到;通过getXXX()方法获得
作用二: 向JSP的四个域中存取数据
方法:
pagetContext.setAttribute("数据的名字","数据的值","域的常量值");//向不同的域中存值
pageContext.getAttribute("数据的名字","域的常量值");//查找不同域的值,先获取最小范围的
常量值的获取通过PageContext.XXX获取;
四个域对象
名字 范围 使用对象 真实对象 常量值
PageScope 当前页面 pageContext pageContext PAGE_SCOPE
RequestScope 一次请求 request HttpServletRequest REQUEST_SCOPE
SessionScope 一次会话 session HttpSession SESSION_SCOPE
ApplicationScpee 整个应用 application ServletContext APPLICATION_SCOPE
JSP的动作标签
作用: 简化代码的编写
*<jsp:forward />用于页面的转发
用法: <jsp:forward page="路径"></jsp:forward>
*<jsp:include />用于页面的包含(动态包含)
用法:<jsp:include page="被包含的路径">
EL表达式
概述: 表达式语言(Expression Language)
作用: 简化JSP的代码
语法: ${ EL表达式 }
功能:
1. 获取数据(JSP的四个域中)
2. 执行运算
3. 操作WEB开发的常用的对象
4. 调用Java中方法:--很少用
EL获取数据
谨记: 用什么名字存到域中就用什么名字取,存的什么类型,取得就是什么类型; 没有获取到数据返回一个空的字符串
点和[]的区别:有索引的用[],没有索引的用点;如果属性名中包含有特殊的字符.必须使用[]
执行运算
在EL表达式中执行的运算:
1.判断对象是否为空:
empty为空, ont empty不为空 也可以用==null或!=null
用法: ${ empty 对象名 }
2.算数运算: + - * /
3.执行逻辑运算(也可以写逻辑运算的英文缩写):
<(lt), <=(le), >(gt), >=(ge), ==(eq),
4.执行关系运算(也可以写英文缩写)
&(adn), |(or), !(not)
5.执行三元运算
示例: ${ n1 < n2 ? "正确":"错误" }
操作WEB开发常用的对象(11个)
pageScope,requestScope,sessionScope,applicationScope - 获取JSP中域中的数据
param,paramValues - 接收参数.
header,headerValues - 获取请求头信息
initParam - 获取全局初始化参数
cookie - WEB开发中cookie
pageContext - WEB开发中的pageContext.
常用的:
获取PageContext中的对象
工程路径:${ pageContext.request.contextPath }
IP地址:${ pageContext.request.remoteAddr }
获取Cookie中的值: ${ cookie.存入的cookie名字.value }
JSTL
概述: JSP Standard Tag Library(JSP标准标签库)
作用: 简化代码,和EL结合替换页面的<%%>
版本:
JSTL1.0 :不支持EL表达式.
JSTL1.1 和 1.2 :支持EL表达式.
JSTL的标签库:包含了五类标签.
core(核心标签),fn(JSTL提供EL函数库),fmt(国际化标签),xml(XML标签),sql(SQL标签)
使用:
1. 引入JSTL的相关的jar包
2. 在页面引入标签库: <%@ taglib url="标签库的路径" prefix="标签库别名" %>
核心标签
JSTL的核心标签也叫c标签
if判断标签:(JSTL中没有没有else)
用法: <c:if test=${ 要判断的数据 }></c:if>
forEach循环标签:
用法: <c:forEach var="遍历出的每个的数据" items="${ 要遍历的数据 }"></c:forEach>
var="遍历出的每个的数据"
items="要遍历的数据"
begin="从哪开始"
end="到哪结束"
step="步进";(比如要遍历1到10,步进是5,得出的就是5和10)
记录遍历的状态:varStatus="名字随便"
varStatus中有两个属性: count代表遍历到第几个 index代表的是当前的索引
示例:<c:forEach var="i" begin="100" end="300" step="5" varStatus="status">
<c:set var="变量名" value="值" scope="域"></c:set> //向域中存数据
<c:out value="值|EL" ></a:out>
default="默认值" //没有时输出一个空字符串
escapeXML="false" //默认对输出内容转义
EL的函数库:
作用: 处理字符串的
语法: ${ fn : 方法名() };//跟java中基本一致
|
|