JavaWeb
JDBC
简介
JDBC就是使用Java语言操作关系型数据库的一套API
快速入门
0.创建工程,导入驱动jar包
mysql-connector-java-5.1.48.jar
1.注册驱动
Class.forName("com.mysql.jdbc.Driver" ); (可不写)
2.获取连接
Connection conn = DriverManager.getConnection(url, username, password);
3.定义SQL语句
String sql =“update...” ;
4.获取执行SQL对象
Statement stmt = conn.createStatement();
5.执行SQL
stmt.executeUpdate(sql);
6.处理返回结果
7.释放资源
API详解
DriverManager
DriverManager(驱动管理类)作用:
-
注册驱动:告诉程序该使用哪一个数据库驱动iar
static void registerDriver(Driver driver) :
注册与给定的驱动程序 DriverManager写代码使用:
class.forName( "com.mysql.jdbc.Driver");
通过查看源码发现:在
com.mysql.jdbc.Driver
类中存在静态代码块static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException( "Can't register driver!"); } } // 注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
-
获取数据库连接
static Connection getConnection (String url,string user,String password)
参数
- url: 连接路径
语法:
jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
示例:
jdbc:mysql://127.0.0.1:3306/数据库名称
细节:
-
如果连接的是本机mysql服务器,并且mysqI服务默认端口是3306,则url可以简写为:
jdbc:mysql:///数据库名称?参数键值对
-
配置useSSL=false参数,禁用安全连接方式,解决警告提示
-
user: 用户名
-
password: 密码
Connection
Connection(数据库连接对象)作用:
-
获取执行SQL的对象
-
普通执行SQL对象
Statement createStatement()
-
预编译SQL的执行SQL对象:防止SQL注入
PreparedStatement prepareStatement (sql)
-
执行存储过程的对象
CallableStatement prepareCall (sql)
-
-
事务管理
MySQL事务管理
开启事务:
BEGIN; / START TRANSACTION;
提交事务:
COMMIT;
回滚事务:
ROLLBACK;
MySQL默认自动提交事务
JDBC事务管理:Connection接口中定义了3个对应的方法
开启事务:
setAutoCommit(boolean autoCommit):
true为自动提交事务; false为手动提交事务,即为开启事务提交事务:
commit()
回滚事务:
rollback()
Statement
Statement 作用:
执行SQL语句
int executeUpdate(sql):
执行DML、DDL语句
返回值:
(1)DML语句影响的行数
(2)DDL语句执行后,执行成功也可能返回0
ResultSet executeQuery(sql):
执行DQL语句
返回值:
ResultSet 结果集对象
ResultSet
ResultSet(结果集对象)作用:
封装了DQL查询语句的结果
ResultSef stmt.executeQuery(sql):
执行DQL语句,返回ResultSet对象
获取查询结果
boolean next():
(1)将光标从当前位置向前移动一行 (2)判断当前行是否为有效行
返回值:
true:有效行,当前行有数据
false:无效行,当前行没有数据
xxx getXxx(参数): 获取数据
xxx: 数据类型; 如: int getInt(参数) ; String getString(参数)
参数:
int: 列的编号,从1开始.
String: 列的名称
使用步骤
-
游标向下移动一行,并判断该行否有数据:next()
-
获取数据: getXxx(参数)
//循环判断游标是否是最后一行末尾 while(rs.next()){ // 获取数据 rs.getXxx(参数); }
接口常用方法
方法名称 | 功能描述 |
---|---|
next() | 将游标从当前位置向下移一行 |
absolute(int row) | 将游标移动到此 ResultSet对象的指定行 |
afterLast() | 将游标移动到此 ResultSet对象的末尾,即最后一行之后 |
beforeFirst() | 将游标移动到此 ResultSet对象的开头,即第一行之前 |
previous() | 将游标移动到此 ResultSet对象的上一行 |
last() | 将游标移动到此 ResultSet对象的最后一行 |
PreparedStatement
接口常用方法
方法名称 | 功能描述 |
---|---|
executeUpdate() | 在此PreparedStatement对象中执行SQL语句,该语句必须是一个DML语句或者是无返回内容的SQL语句,比如DDL语句 |
executeQuery() | 在此PreparedStatement对象中执行SQL查询,该方法返回的是ResultSet对象 |
setlnt(int parameterIndex, int x) | 将指定参数设置为给定的int值 |
setFloat(int parameterIndex,float x) | 将指定参数设置为给定的float值 |
setString(int parameterlndex,String x) | 将指定参数设置为给定的String值 |
setDate(int parameterlndex, Date x) | 将指定参数设置为给定的Date值 |
addBatch() | 将一组参数添加到此PreparedStatement对象的批处理命令中 |
setCharacterStream(int parameterlndex,java.io.Reader reader,int length) | 将指定的输入流写入数据库的文本字段 |
setBinaryStream(int parameterlndex,java.io.InputStream x, int length) | 将二进制的输入流数据写入到二进制字段中 |
需要注意的是,setDate()方法可以设置日期内容,但参数Date的类型是java.sql.Date,而不是java.util.Date。在通过setter()方法为SQL语句中的参数赋值时,可以通过参数与SQL类型相匹配的方法(例如,如果参数类型为Integer,那么应该使用setInt()方法),也可以通过setObject()方法设置多种类型的输入参数。通过setter()方法为SQL语句中的参数赋值,具体示例代码如下所示:
String sql = "INSERT INTO users(id,name,email) VALUES(?,?,?)";
PreparedStatement preStmt = conn.prepareStatement(sql);
preStmt.setlnt(1,1); //使用参数与SQL类型相匹配的方法
preStmt.setString(2, "zhangsan"); //使用参数与SQL类型相匹配的方法
preStmt.setObject(3, "zs@sina.com");//使用setObject()方法设置参数
preStmt.executeUpdate();
数据库连接池
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,当应用程序访问数据库时并不是直接创建Connection,而是向连接池“申请”一个Connection。如果连接池中有空闲的Connection,则返回一个链接给应用程序,否则应用程序需要创建新的Connection。使用完毕后,连接池会将Connection回收,重新放入连接池以供其他的线程使用,从而减少创建和断开数据库连接的次数,提高数据库的访问效率。
DBCP数据库连接池
BasicDataSource类的常用方法
方法名称 | 功能描述 |
---|---|
void setDriverClassName(String driverClassName) | 设置连接数据库的驱动名称 |
void setUrl(String url) | 设置连接数据库的路径 |
void setUsername(String username) | 设置数据库的登录账号 |
void setPassword(String password) | 设置数据库的登录密码 |
void setlnitialSize(int initialSize) | 设置数据库连接池初始化的连接数目 |
void setMinldle(int minldle) | 设置数据库连接池最小闲置连接数目 |
Connection getConnection() | 从连接池中获取一个数据库连接 |
C3P0数据库连接池
ComboPooledDataSource类的常用方法
方法名称 | 功能描述 |
---|---|
void setDriverClass() | 设置连接数据库的驱动名称 |
void setJdbcUrl() | 设置连接数据库的路径 |
void setUser() | 设置数据库的登录账号 |
void setPassword() | 设置数据库的登录密码 |
void setMaxPoolSize() | 设置数据库连接池最大连接数目 |
void setMinPoolSize() | 设置数据库连接池最小连接数目 |
void setlnitialPoolSize() | 设置数据库连接池初始化的连接数目 |
Connection getConnection() | 从数据库连接池中获取一个连接 |
HTTP
概念
HTTP是HyperText Transfer Protocol的缩写,即超文本传输协议。它是一种请求/响应式的协议,客户端在与服务器建立连接后,就可以向服务器发送请求,这种请求被称作HTTP请求,服务器接收到请求后会做出响应,称为HTTP响应。
HTTP协议的特点
-
HTTP协议支持客户端(浏览器就是一种Web客户端)/服务器模式。
-
简单快速,客户端向服务器请求服务时,只需传送请求方式和路径。常用的请求方式有GET、POST等,不同的请求方式规定的客户端
与服务器联系的类型也不同。HTTP比较简单,使得HTTP服务器的程序规模小,因而通信速度很快。
-
灵活,HTTP允许传输任意类型的数据,正在传输的数据类型由Content-Type加以标记。
-
无状态,HTTP是无状态协议。无状态是指协议对于事务处理没有记忆能力,如果后续处理需要前面的信息,则必须重新传输,这样
可能导致每次连接传送的数据量增大。
HTTP消息
当用户在浏览器中访问集个URL地址、单击网页的某个超链接或者提交网页上的form表单时,刘览器都会向服务器发送请求数据,即HTTP请求消息。服务器接收到请求数据后,会将处理后的数据发送给客户端,即HTTP响应消息。HTTP请求消息和HTTP响应消息统称为HTTP消息。
HTTP请求行
HTTP请求行位于请求消息的第1行,它包括三个部分,分别是请求方式、资源路径以及所使用的HTTP版本,
具体示例如下:
GET/index.html HTTP/1.1
GET
是请求方式,index.html
是请求资源路径,HTTP/1.1
是通信使用的协议版本。需要注意的是,请求行中的每个部分需要用空格分隔,最后要以回车换行结束。
HTTP请求方式
请求方式 | 含义 |
---|---|
GET* | 请求获取请求行的URI所标识的资源 |
POST(推荐)* | 向指定资源提交数据,请求服务器进行处理(如提交表单或者上传文件) |
HEAD | 请求获取由URI所标识资源的响应消息头 |
PUT | 将网页放置到指定URL位置(上传/移动) |
DELETE | 请求服务器删除URI所标识的资源 |
TRACE | 请求服务器回送收到的请求信息,主要用于测试或诊断 |
CONNECT | 保留将来使用 |
OPTIONS | 请求查询服务器的性能,或者查询与资源相关的选项和需求 |
POST方法
在实际开发中,通常都会使用POST方式发送请求,原因主要有以下两个∶
( 1 ) POST传输数据大小无限制
由于GET请求方式是通过请求参数传递数据的,因此最多可传递2KB的数据。而POST请求方式是通过实体内容传递数据的,因此可以传递数据的大小没有限制。
( 2 ) POST比GET请求方式更安全
由于GET请求方式的参数信息都会在URL地址栏明文显示,而POST请求方式传递的参数隐藏在实体内容中,用户是看不到的,因此POST比GET请求方式更安全。
HTTP请求消息头
在HTTP请求消息中,请求行之后,便是若干请求消息头。请求消息头主要用于向服务器传递附加消息,例如,客户端可以接收的数据类型、压缩方法、语言以及发送请求的超链接所属页面的URL地址等信息。
请求消息头中可以看出,每个请求消息头都是由一个头字段名称和一个值构成,头字段名称和值之间用冒号( : )和空格分隔,每个请求消息头之后使用一个回车换行符标志结束。需要注意的是,头字段名称不区分大小写,但习惯上将单词的第一个字母大写。
Accept
Accept头字段用于指出客户端程序(通常是浏览器)能够处理的MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)类型。例如,如果浏览器和服务器同时支持png类型的图片,则浏览器可以发送包含image/png的Accept头字段,服务器检查到Accept头中包含image/png这种MIME类型,可能在网页中的img元素中使用png类型的文件。MIME类型有很多种,例如,下面的这些MIME类型都可以作为Accept头字段的值。
Accept: text/html,表明客户端希望接受HTML文本。
Accept: image/gif,表明客户端希望接受GIF图像格式的资源。
Accept: image/*,表明客户端可以接受所有image格式的子类型。
Accept:*/*,表明客户端可以接受所有格式的内容。
Accept-Encoding
Accept-Encoding头字段用于指定客户端能够进行解码的数据编码方式,这里的编码方式通常指的是某种压缩方式。在Accept-Encoding头字段中,可以指定多个数据编码方式,它们之间以逗号分隔,具体示例: Accept-Encoding: gzip,compress
gzip和compress这两种格式是最常见的数据编码方式。在传输较大的实体内容之前,对其进行压缩编码,可以节省网络带宽和传输时间。服务器接收到这个请求头后,使用其中指定的一种格式对原始文档内容进行压缩编码,然后再将其作为响应消息的实体内容发送给客户端,并且在Content-Encoding响应头中指出实体内容所使用的压缩编码格式。浏览器在接收到这样的实体内容之后,需要对其进行反向解压缩。
Host
Host头字段用于指定资源所在的主机名和端口号,格式与资源完整URL中的主机名和端口号部分相同,具体示例:
Host: www.itcast.cn : 80
由于浏览器连接服务器时默认使用的端口号为80,所以“www.itcast.cn”
后面的端口号信息“:80”
可以省略。需要注意的是,在HTTP1.1中,浏览器和其他客户端发送的每个请求消息中必须包含Host请求头字段,以便Web服务器能够根据Host头字段中的主机名区分客户端所要访问的虚拟Web站点。当浏览器访问Web站点时,会根据地址栏中的URL地址自动生成相应的Host请求头。
Referer
浏览器向服务器发出的请求,可能是直接在浏览器中输入URL地址而发出的,也可能是单击一个网页上的超链接而发出的。对于第一种直接在浏览器地址栏中输入URL地址的情况,浏览器不会发送Referer请求头。而对于第二种情况,例如在一个页面中包含一个指向远程服务器的超链接,当单击这个超链接向服务器发送GET请求时,浏览器会在发送的请求消息中包含Referer头字段,如下所示:
Host: www.itcast.cn : 80
Referer头字段非常有用,常被网站管理人员用来追踪网站的访问者是如何导航进入网站的。同时Referer头字段还可以用于网站的防盗链。
盗链
假设一个网站的首页中想显示一些图片信息,而在该网站的服务器中并没有这些图片资源它通过在Html文件中使用标签链接到其他网站的图片资源,将其展示给浏览者,这就是盗链。盗链的网站提高了自己网站的访问量,却加重了被链接网站服务器的负担,损害了其合法利益。所以,一个网站为了保护自己的资源,可以通过Referer头检测出从哪里链接到当前的网页或资源,一旦检测到不是通过本站的链接进行的访问,可以阻止访问或者跳转到指定的页面。
HTTP响应状态行
HTTP响应状态行位于响应消息的第一行,它包括3个部分,分别是HTTP版本、—个表示成功或错误的整数代码(状态码)和对状态码进行描述的文本信息。HTTP响应状态行具体示例如下:
HTTP/1.1 200 OK
HTTP 1.1是通信使用的协议版本,200是状态码,OK是状态描述,说明客户端请求成功。需要注意的是,请求行中的每个部分需要用空格分隔,最后要以回车换行结束。
状态码
状态代码由3位数字组成,表示请求是否被理解或被满足。HTTP响应状态码的第一个数字定义了响应的类别,后面两位没有具体的分类。第一个数字有5种可能的取值。
1xx 表示请求已接收,需要继续处理
2xx 表示请求已成功被服务器接收、理解并接受
3xx 为完成请求,客户端需要进一步细化请求
4xx 客户端请求有错误
5xx 服务器出现错误
状态码 | 说明 |
---|---|
200 | 表示服务器成功处理了客户端的请求。客户端的请求成功,响应消息返回正常的请求结果 |
302 | 表示请求的资源临时从不同的URI响应请求,但请求者应继续使用原有位置来进行以后的请求。例如,在请求重定向中,临时URI应该是响应的Location头字段所指向的资源 |
304 | 如果客户端有缓存的文档,它会在发送的请求消息中附加一个If-Modified-Since请求头,表示只有请求的文档在If-Modified-Since指定的时间之后发生过更改,服务器才需要返回新文档。状态码304表示客户端缓存的版本是最新的,客户端应该继续使用它。否则,服务器将使用状态码200返回所请求的文档 |
404 | 表示服务器找不到请求的资源。例如,访问服务器不存在的网页经常返回此状态码 |
500 | 表示服务器发生错误,无法处理客户端的请求。大部分情况下,是服务器的CGI、ASP、JSP等程序发生了错误,一般服务器会在相应消息中提供具体的错误信息 |
HTTP响应消息头
在HTTP响应消息中,第一行为响应状态行,紧接着是若干响应消息头,服务器通过响应消息头向客户端传递附加信息,包括服务程序名、被请求资源需要的认证方式、客户端请求资源的最后修改时间、重定向地址等信息。
Location
Location头字段用于通知客户端获取请求文档的新地址,其值为一个使用绝对路径的URL地址。Location响应头字段示例如下所示:
Location: http://www.itcast.org
Location头字段和大多数3xx状态码配合使用,以便通知客户端自动重新连接到新的地址请求文档。由于当前响应并没有直接返回内容给客户端,所以使用Location头的HTTP消息不应该有实体内容,
由此可见,在HTTP消息头中不能同时出现Location和Content-Type这两个头字段。
Server
Server头字段用于指定服务器软件产品的名称,具体示例如下:
Server: Apache-Coyote/1.1
Refresh
Refresh头字段用于告诉浏览器自动刷新页面的时间,它的值是一个以秒为单位的时间数,具体示例如下所示:
Refresh : 3
上面所示的Refresh头字段用于告诉浏览器在3秒后自动刷新此页面。
在Refresh头字段的时间值后面还可以增加一个URL参数,时间值与URL之间用分号( ; )分隔,用于告诉浏览器在指定的时间值后跳转到其他网页。例如,告诉浏览器3秒后跳转到www.itcast.cn
网站,具体示例如下:
Refresh : 3;url=http://www.itcast.cn
Servlet
概述
Servlet是运行在Web服务器端的Java应用程序,它使用Java语言编写。与Java程序的区别是,Servlet对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持。在Java Web应用方面,Servlet的应用占有十分重要的地位,它在Web请求的处理功能方面也非常强大。
Servlet容器
Servlet由Servlet容器提供,Servlet容器是指提供了Servlet功能的服务器 。Servlet容器将Servlet动态地加载到服务器上。与HTTP协议相关的Servlet使用HTTP请求和HTTP响应与客户端进行交互。因此,Servlet容器支持所有HTTP协议的请求和响应。
Servlet的请求首先会被HTTP服务器(如Apache)接收,HTTP服务器只负责静态HTML页面的解析,对于Servlet的请求转交给Servlet容器,Servlet容器会根据web.xml
文件中的映射关系,调用相应的Servlet, Servlet将处理的结果返回给Servlet容器,并通过HTTP服务器将响应传输给客户端。
Servlet特点
Servlet使用Java语言编写,它不仅具有Jia语言的优点,而且还对Web的相关应用进行了封装,同时Servlet容器还提供了对应用的相关扩展,无论是在功能、性能、安全等方面都十分优秀。
功能强大
Servlet采用Java语言编写,它可以调用Java API中的对象及方法,此外,Servlet对象对Web应用进行了封装,提供了Servlet对Web应用的编程接口,还可以对HTTP请求进行相应的处理,如处理提交数据、会话跟踪、读取和设置HTTP头信息等。由于Servlet既拥有Java提供的API,而且还可以调用Servlet封装的Servlet API编程接口,所以,它在业务功能方面十分强大。
可移植
Java语言是跨越平台的,所谓跨越平台是指程序的运行不依赖于操作系统平台,它可以运行到多个系统平台中,如目前常用的操作系统Windows、Linux和UNIX等。
性能高效
Servlet对象在Servlet容器启动时被初始化,当Servlet对象第一次被请求时,Seervlet容器将Servlet对象实例化,此时Servlet对象驻存于内存中。如果存在多个请求,Servlet不会再被实例化,仍然由第一次被实例化的Servlet对象处理其他请求。每一个请求是一个线程,而不是一个进程。
安全性高
Servlet使用了Java的安全框架,同时Servlet容器还可以为Servlet提供额外的安全功能,它的安全性是非常高的。
可扩展
Java语言是面向对象的编程语言, Servlet由Java语言编写,所以它具有面向对象的优点。在业务逻辑处理中,可以通过封装、继承等特性扩展实际的业务需要。
Servlet接口
针对Servlet技术的开发,SUN公司提供了一系列接口和类,其中最重要的是javax.servlet.Servlet接口。Servlet就是一种实现了Servlet接口的类,它由Web容器负责创建并调用,用于接收和响应用户的请求。
Servlet接口的方法
方法声明 | 功能描述 |
---|---|
void init(ServletConfig config) | Servlet实例化后,Servlet容器调用该方法完成初始化工作 |
ServletConfig getServletConfig() | 用于获取Servlet对象的配置信息,返回Servlet的ServletConfig对象 |
String getServletInfo() | 返回一个字符串,其中包含关于Servlet的信息,例如,作者、版本和版权等信息 |
void service(ServletRequest request , ServletResponse response) | 负责响应用户的请求,当容器接收到客户端访问Servlet对象的请求时就会调用此方法。容器会构造一个表示客户端请求信息的ServletRequest对象和一个用于响应客户端的ServletResponse对象作为参数传递给service()方法。在service()方法中,可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息 |
void destroy() | 负责释放Servlet对象占用的资源。当服务器关闭或者Servlet对象被移除时,Servlet对象会被销毁,容器会调用此方法 |
Servlet接口中的生命周期的方法
在Servlet接口中的5个方法中,其中init()、**service()和destroy()**这三个方法可以表现Servlet的生命周期,它们会在某个特定的时刻被调用。需要注意的是,Servlet容器指的就是Web服务器。
Servlet接口的实现类
针对Servlet接口,SUN公司提供了两个默认的接口实现类:GenericServlet和HttpServlet。GenericServlet是一个抽象类,该类为Servlet接口提供了部分实现,它并没有实现HTTP请求处理。HttpServlet是GenericServlet的子类,它继承了GenericServlet的所有方法,并且为HTTP请求中的POST、GET等类型提供了具体的操作方法。
Servlet配置
若想让Servlet正确地运行在服务器中并处理请求信息,必须进行适当的配置,关于Servlet的配置主要有两种方式,分别是通过Web应用的配置文件web.xml来完成配置和使用**@Webservlet注解**的方式完成。
使用web.xml配置Servlet
在web.xml文件中,通过<servlet>
标签进行注册,在<servlet>
标签下包含若干个子元素。
属性名 | 类型 | 描述 |
---|---|---|
String | 指定该Servlet的名称,一般与Servlet类名相同,要求唯一 | |
String | 指定该Servlet类的位置,包括包名与类名 | |
String | 指定该Servlet的描述信息 | |
String | 指定该Servlet的显示名 |
把Servlet映射到URL地址,使用<servlet-mapping>
标签进行映射,使用<servlet-name>
子标签指定要映射的Servlet名称,名称要和之前在<servlet>
标签下注册的相同;使用<url-pattern>
子标签映射URL地址,地址前必须加“/”,否则访问不到。
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class >web.controller.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlet/HelloServlet</url-pattern>
</servlet-mapping>
@WebServlet注解属性*
@WebServlet注解用于代替web.xml文件中的<servlet>
等标签,该注解将会在项目部署时被容器处理,容器将根据具体的属性配置将相应的类部署为Servlet。为此,@WebServlet注解提供了一些属性(了解)。
属性声明 | 功能描述 |
---|---|
String name | 指定Servlet的name属性,等价于。如果没有显式指定,则该Servlet的取值即为类的全限定名。 |
String[] value | 该属性等价于urlPatterns属性。urlPatterns和value属性不能同时使用。 |
String[] urlPatterns | 指定一组Servlet的URL匹配模式。等价于标签。 |
int loadOnStartup | 指定Servlet的加载顺序,等价于标签。 |
WebInitParam[] | 指定一组Servlet初始化参数,等价于标签。 |
boolean asyncSupported | 声明Servlet是否支持异步操作模式,等价于标签。 |
String description | Servlet的描述信息,等价于标签。 |
String displayName | Servlet的显示名,通常配合工具使用,等价于标签。 |
使用注解方式配置Servlet
使用@WebServlet注解将HelloServlet类标注为一个Servlet。@WebServlet注解中的name属性值用于指定servlet的name属性,等价于<Servlet-name>
,如果没有设置@WebServlet的name属性,其默认值是Servlet的类完整名称。urlPatterns属性值用于指定一组servlet的url的匹配模式,等价于<url-pattern>
标签。如果需要在**@WebServlet注解**中设置多个属性,属性之间用逗号隔开。通过@WebServlet注解能极大地简化了Servlet的配置步骤,降低了开发人员的开发难度。
Servlet生命周期
初始化阶段
当客户端向Servlet容器发出HTTP请求访问Servlet时,Servlet容器首先会解析请求,检查内存中是否已经有了该Servlet对象,如果有,直接使用该Servlet对象; 如果没有,就创建Servlet实例对象,然后通过调用init()方法完成Servlet的初始化。需要注意的是,在Servlet的整个生命周期内,它的init()方法只被调用一次。
运行阶段
这是Servlet生命周期中最重要的阶段,在这个阶段,Servlet容器会为客户端请求创建代表HTTP请求的ServletRequest对象和代表HTTP响应的ServletResponse对象,然后将它们作为参数传递给Servlet的service()方法。service()方法从ServletRequest对象中获得客户端请求信息并处理该请求,通过ServletResponse对象生成响应结果。在Servlet的整个生命周期内,对于Servlet的每一次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponse对象,也就是说,service()方法在Servlet的整个生命周期中会被调用多次。
销毁阶段
当服务器关闭或web应用被移除出容器时,Servlet随着web应用的销毁而销毁。在销毁Servlet之前,Servlet容器会调用Servlet的destroy()方法,以便让Servlet对象释放它所占用的资源。在Servlet的整个生命周期中,destroy()方法也只被调用一次。
需要注意的是,Servlet对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭,或web应用被移除出容器时Servlet对象才会销毁。
ServletConfig接口
在Servlet运行期间,经常需要一些配置信息,例如,文件使用的编码等,这些信息都可以在@WebServlet注解的属性中配置。当Tomcat初始化一个Servlet时,会将该Servlet的配置信息封装到一个ServletConfig对象中,通过调用init(ServletConfig config)方法将ServletConfig对象传递给Servlet。ServletConfig定义了一系列获取配置信息的方法。
方法说明 | 功能描述 |
---|---|
String getInitParameter(String name) | 根据初始化参数名返回对应的初始化参数值 |
Enumeration getInitParameterNames() | 返回一个Enumeration对象,其中包含了所有的初始化参数名 |
ServletContext getServletContext() | 返回一个代表当前Web应用的ServletContext对象 |
String getServletName() | 返回Servlet的名字 |
ServletContext接口
获取Web应用程序的初始化参数
当servlet容器启动,会为每个Web应用创建一个唯一的ServietContext对象代表当前Web应用。ServletContext对象不仅封装了当前Web应用的所有信息,而且实现了多个Servlet之间数据的共享。
在web.xml文件中,可以配置Servlet的初始化信息,还可以配置整个Web应用的初始化信息。Web应用初始化参数的配置方式具体如下所示。
<context-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</context-param>
<context-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</context-param>
实现多个Servlet对象共享数据
由于一个Web应用中的所有Servlet共享同一个ServletContext对象,所以ServletContext对象的域属性可以被该Web应用中的所有Servlet访问。ServletContext接口中定义了用于增加、删除、设置ServletContext域属性的四个方法。
方法说明 | 功能描述 |
---|---|
Enumcration getAttributcNames() | 返回一个Enumeration对象,该对象包含了所有存放存ServletContext中的所有域属性名 |
Object getAttibute(String name) | 根据参数指定的属性名返回一个与之匹配的域属性值 |
void removeAttribute(String name) | 根据参数指定的域属性名,从ServletContext中删除匹配的域属性 |
void setAttribute(String name,Object obj) | 设置ServletContext的域属性,具中name是域属性名,obj是域属性值 |
读取Web应用下的资源文件
ServletContext接口定义了一些读取Web资源的方法,这些方法是依靠Servlet容器来实现的。Servlet容器根据资源文件相对于Web应用的路径,返回关联资源文件的IO流、资源文件在文件系统的绝对路径等。
发送状态码相关的方法
HttpServletResponse接口定义的状态码方法
当Servlet向客户端回送响应消息时,需要在响应消息中设置状态码,状态码代表着客户端请求服务器的结果。为此,HttpServletResponse接口定义了3个发送状态码的方法。
setStatus(int status)方法
setStatus(int status)方法用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,所以,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。例如,正常情况下,
Web服务器会默认产生一个状态码为200的状态行。
sendError(int sc)方法
sendError(int sc)方法用于发送表示错误信息的状态码,例如,404状态码表示找不到客户端请求的资源。
sendError(int code ,String message)方法
sendError(int code, String message)方法除了设置状态码,还会向客户端发出一条错误信息。服务器默认会创建一个HTML格式的错误服务页面作为响应结果,其中包含参数message指定的文本信息,这个HTML页面的内容类型为“text/html”,保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明那么这个声明的错误页面会将优先建议的message参数服务于客户端。
发送响应消息头相关的方法
https://www.bilibili.com/video/BV1sL4y1q7FN?p=50&t=39.3
发送响应消息体相关的方法
getWriter()方法*
getWriter()方法所获取的字符输出流对象为PrihtWriter类型。由于PrintWriter类型的对象可以直接输出字符文本内容,所以,要想输出内容为字符文本的网页文档,需要调用getWriter()方法。
getOutputStream()方法
getOutputStream()方法所获取的字节输出流对象为ServletOutputStream类型。由于ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。所以,要想输出二进制格式的响应正文,就需要调用getOutputStream)方法。
实现请求重定向
在某些情况下,针对客户端的请求,一个Servlet类可能无法完成全部工作。这时,可以使用请求重定向来完成。所谓请求重定向,指的是Web服务器接收到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。
sendRedirect()方法
为了实现请求重定向,HttpServletResponse接口定义了一个sendRedirect()方法,该方法用于生成302响应码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL。
sendRedirect()方法的完整声明如下所示:
public void sendRedirect(java.lang.String location)
throws java.io.IOException
需要注意的是,参数location可以使用相对URL,Web服务器会自动将相对URL翻译成绝对URL ,再生成Location头字段。
sendRedirect()方法的工作原理
中文输出乱码问题
由于计算机中的数据都是二进制形式存储的,所以,当传输文本时,就会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,就会导致乱码问题。
解决
第一种
//设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8");
//通知浏览器使用utf-8解码
response.setHeader("Content-Type" ,"text/html;charset=utf-8");
第二种*
//包含第一种方式的两个功能
response.setContentType("text/html;charset=utf-8");
https://burns.blog.csdn.net/article/details/124614007?spm=1001.2014.3001.5506
获取请求行信息的相关方法
HttpServletRequest接口获取请求行的相关方法
方法声明 | 功能描述 |
---|---|
int getRemotePort() | 该方法用于获取请求客户端网络连接的端口号 |
String getLocalAddr() | 该方法用于获取Web服务器上接收当前请求网络连接的IP地址 |
String getLocalName() | 该方法用于获取Web服务器上接收当前网络连接IP所对应的主机名 |
int getLocalPart() | 该方法用于获取Web服务器上接收当前网络连接的端口号 |
String getServerName() | 该方法用于获取当前请求所指向的主机名,即HTTP请求消息中Host头字段所对应的主机名部分 |
int getServerPort() | 该方法用于获取当前请求所连接的服务器端口号,即如果HTTP请求消息中Host头字段所对应的端口号部分 |
String getScheme() | 该方法用于获取请求的协议名,例如http.https或ftp |
StringBuffer getRequestURL() | 该方法用于获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等信息,但不包括后面的查询参数部分。注意,getRequestURL()方法返回的结果是StringBuffer类型,而不是String类型,这样更便于对结果进行修改 |
获取请求消息头的相关方法
String getHeader(String name)
该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,getHeader()方法返回null;如果请求消息中包含有多个指定名称的头字段,aetHeader()方法返回其中第一个头字段的值
Enumeration getHeaders(String name)
该方法返回一个Enumeration集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成。在多数情况下,一个头字段名在请求消息中只出现一次,但有时候可能会出现多次
请求转发
getRequestDispatcher()方法
Servlet之间可以相互跳转,利用Servlet的跳转可以很容易地把一项任务按模块分开,例如,使用一个Servlet实现用户登录,然后跳转到另外一个Servlet实现用户资料修改。Servlet的跳转要通过RequestDispatcher接口的实例对象实现。HttpServletRequest接口提供了getRequestDispatcher()方法用于获取RequestDispatcher对象,getRequestDispatcher()方法的具体格式如下所示。
RequestDispatcher getRequestDispatcher(String path)
getRequestDispatcher()方法返回封装了某条路径所指定资源的RequestDispatcher对象。其中,参数path必须以“/”开头,用于表示当前Web应用的根目录。需要注意的是,WEB-INF目录中的内容对RequestDispatcher对象也是可见的。因此,传递给
getRequestDispatcher(String path)方法的资源可以是 WEB-INF目录中的文件。
forward()方法
获取到RequestDispatcher对象后,如果当前Web资源不想处理请求,RequestDispatcher接口提供了一个forward()方法,该方法可以将当前请求传递给其他Web资源对这些信息进行处理并响应给客户端,这种方式称为请求转发。 forward()行法的具体格式如下所示。
forward(ServletRequest request,ServletResponse response)
forward()方法用于将请求从一个Servlet传递给另一个Web资源。在Servlet中,可以对请求做一个初步处理,然后通过调用forward()方法,将请求传递给其他资源进行响应。需要注意的是,该方法必须在响应提交给客户端之前被调用,否则将抛出
IllegalStateException异常。
获取请求参数
ServletRequest中获取请求参数的方法 (RequestDemo6 例子)
方法声明 | 功能描述 |
---|---|
String getParameter(String name) | 该方法用于获取某个指定名称的参数值,如果请求消息中没有包含指定名称的参数,getParameter()方法返回null ;如果指定名称的参数存在但没有设置值,则返回一个空串;如果请求消息中包含有多个该指定名称的参数,getParameter()方法返回第一个出现的参数值 |
String[] getParameterValues(String name) | 该方法用于返回一个String类型的数组,HTTP请求消息中可以有多个相同名称的参数(通常由一个包含有多个同名的字段元素的form表单生成),如果要获得HTTP请求消息中的同一个参数名所对应的所有参数值,那么就应该使用getParameterValues()方法 |
Enumeration getParameterNames() | 该方法用于返回一个包含请求消息中所有参数名的Enumeration对象,在此基础上,可以对请求消息中的所有参数进行遍历处理 |
Map getParameterMap() | 该方法用于将请求消息中的所有参数名和值装入进一个Map对象中返回 |
通过Request对象传递数据
setAttribute()方法
setAttribute()方法用于将一个对象与一个name关联后存储进ServletRequest对象中,其完整声明定义如下。
public void setAttribute(String name,Object o);
setAttribute()方法的参数列表的第一个参数接收的是一个String类型的name,第二个参数接收的是一个object类型的对象o。需要注意的是,如果ServletRequest对象中已经存在指定名称的属性,setAttribute()方法将会先删除原来的属性,然后再添加新的属性。如果传递给setAttribute()方法的属性值对象为null,则删除指定名称的属性,这时的效果等同于removeAttribute()方法。
getAttributeNames()方法
getAttributeNames()方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理。getAttributeNames()方法声明如下:
public Enumeration getAttributeNames();
需要注意的是,只有属于同一个请求中的数据才可以通过ServletRequest对象传递数据。
会话
在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话。在打电话过程中,通话双方会有通话内容,同样,在客户端与服务器交互的过程中,也会产生一些数据。例如,用户甲和乙,分别登录了购物网站,甲购买了一个iPhone手机,乙购买了一个iPad,当这两个用户结账时,Web服务器需要对用户甲和乙的信息分别进行保存。为了保存会话过程中产生的数据,Servlet提供了两个用丁保存会话数据的对象,分别是Cookie和Session。
Cookie
在现实生活中,当顾客在购物时,商城经常会赠送顾客一张会员卡,卡上记录用户的个人信息(姓名,手机号等)、消费额度和积分额度等。顾客一旦接受了会员卡,以后每次光临该商场时,都可以使用这张会员卡,商场也将根据会员卡上的消费记录计算会员的优惠额度和累加积分。在Web应用中,Cookie的功能类似于会员卡,当用户通过浏览器访问Web服务器时,服务器会给客户端发送一些信息,如用户信息和商品信息,这些信息都保存在Cookie中。这样,当该浏览器再次访问服务器时,会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确l地响应。
服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。Set-Cookie头字段中设置的Cookie的具体示例如下:
Set-Cookie: user=itcast; Path=/;
user表示Cookie的名称,itcast表示Cookie的值,Path表示Cookie的属性。Cookie必须以键值对的形式存在,Cookie属性可以有多个,属性之间用分号“;”和空格分隔。
Cookie API
构造方法
Cookie类有且仅有一个构造方法,具体语法格式如下∶
public Cookie(java.lang.String name,java.lang.String value);
在Cookie的构造方法中,参数name用于指定Cookie的名称,value用于指定Cookie的值。需要注意的是,Cookie一旦创建,它的名称就不能再更改,Cookie的值可以为任何值,创建后允许被修改。
Cookie类常用方法
方法声明 | 功能描述 |
---|---|
String getName() | 用于返回Cookie的名称 |
void setValue(String newValue) | 用于为Cookie设置一个新的 |
String getValue() | 用于返回Cookie的值 |
void setMaxAge(int expiry) | 用于设置Cookie在浏览器客户机上保持有效的秒数 |
int getMaxAge() | 用于返回Cookie在浏览器客户机上保持有效的秒数 |
void setPath(String uri) | 用于设置该Cookie项的有效目录路径 |
String getPath() | 用于返回该Cookie项的有效目录路径 |
void setDomain(String pattern) | 用于设置该Cookie项的有效域 |
String getDomain() | 用于返回该Cookie项的有效域 |
void setVersion(int v) | 用于设置该Cookie项采用的协议版本 |
int getVersion() | 用于返回该Cookie项采用的协议版本 |
void setComment(String purpose) | 用于设置该Cookie项的注解部分 |
String getComment() | 用于返回该Cookie项的注解部分 |
void setSecure(boolean flag) | 用于设置该Cookie项是否只能使用安全的协议传送 |
boolean getSecure() | 用于返回该Cookie项是否只能使用安全的协议传送 |
Session
当人们去医院就诊时,就诊病人需要办理医院的就诊卡,就诊卡上只有卡号,没有其他信息。但病人每次去该医院就诊时,只要出示就诊卡,医多人员便可根据卡号查询到病人的就诊信息。Session技术类似医院办理就诊卡和医院为每个病人保留病历档案的过程。当浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性,Session对象就相当于病历档案,ID就相当于就诊卡号。当客户端后续访问服务器时,只要将ID传递给服务器,服务器就能判断出该请求是哪个客户端发送的,从而选择与之对应的Session对象为其服务。
Session还具有更高的安全性,它将关键数据保存在服务器。cookie则是将数据存在客户端的浏览器中。因此cookie是较为危险的,若客户端遭遇黑客攻击,cookie信息容易被窃取,数据也可能被篡改,而运用Session可以有效避免这种情况的发生。
HttpSession API
getSession()方法
Session是与每个请求消息紧密相关的,为此,HttpServletRequest定义了用于获取Session对象的getSession()方法,该方法有两种重载形式,具体如下:
public HttpSession getSession(boolean create)//第一个
public HttpSession getSession()//第二个(用的多)
第一个getSession(boolean create)
方法根据传递的参数判断是否创建新的HttpSession对象,如果参数为true,则在相关的HttpSession对象不存在时创建并返回新的HttpSession对象,否则不创建新的HttpSession对象,而是返回null。
*第二个getSession()方法相当于第一个方法参数为true时的情况,在相关的HttpSession对象不存在时总是创建新的HttpSession对象。需要注意的是,由于getSession()方法可能会产生发送会话标识号的Cookie头字段,所以必须在发送任何响应内容之前调用getSession()方法。
方法声明 | 功能描述 |
---|---|
String getId() | 用于返回与当前HttpSession对象关联的会话标识号 |
long getCreationTime() | 用于返回Session创建的时间,这个时间是创建Session的时间与1970年1月1日00:00:00之间时间差的毫秒表示形式 |
long getLastAccessedTime() | 用于返回客户端最后一次发送与Session相关请求的时间,这个时间是发送请求的时间与1970年1月1日00:00:00之间时间差的毫秒表示形式 |
void setMaxInactiveInterval(int interval) | 用于设置当前HttpSession对象可空闲的以秒为单位的最长时间,也就是修改当前会话的默认超时间隔 |
boolean isNew() | 判断当前HttpSession对象是否是新创建的 |
void invalidate() | 用于强制使Session对象无效 |
ServletContext getServletContext() | 用于返回当前HttpSession对象所属于的Web应用程序对象,即代表当前Web应用程序的ServletContext对象 |
void setAttribite(String name,Object value) | 用于将一个对象与一个名称关联后存储到当前的HttpSession对象中 |
String getAttribute() | 用于从当前HttpSession对象中返回指定名称的属性对象 |
void removeAttribute(String name) | 用于从当前HttpSession对象中删除指定名称的属性 |
Session生命周期
Session失效—“超时限制”判断Session是否生效
Web服务器采用**“超时限制”判断客户端是否还在继续访问。在一定时间内,如果某个客户端一直没有请求访问,那么,Web服务器就会认为该客户端已经结束请求,并且将与该客户端会话所对应的HttpSession对象变成垃圾对象,等待垃圾收集器将其从内存中彻底清除。
反之,如果浏览器超时后,再次向服务器发出请求访问,那么,Web服务器会创建一个新的HttpSession对象,并为其分配一个新的ID属性**。
Session失效—强制Session失效
invalidate()方法,该方法可以强制使Session对象失效,具体用法如下所示:
HttpSession session = request.getSession();
session.invalidate();//注销该request的所有session
有时默认的Session失效时间并不能满足我们的需求。这时我们需要自定义Session的失效时间,自定义Session的失效时间有3种:
第1种:
在项目的web.xml文件中配置Session的失效时间,具体代码如下所示:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
需要注意的是,在web.xml配置的Session失效时间默认是分钟,所以上述代码设置Session失效时间为30分钟。
第2种:
在Servlet程序中手动设置Session的失效时间,具体代码如下所示:
session.setMaxInactiveInterval(30 * 60);//设置单位为秒,设置为-1永不过期
第3种:
上述代码设置了Session的失效时间为30分钟,如果将值设置为-1,则该Session永不过期。在<Tomcat安装目录>\conf\web.xml文件中,可以找到如下一段配置信息
<session-config>
<session-timeout>30</session-timeout>
</session-config>
JSP
JSP全名是Java Server Pages,即Java服务器页面。它是Servlet更高级别的扩展在JSP文件中,HTML代码与Java代码共同存在,其中,HTML代码用来实现网页中静态内容的显示,Java代码用来实现网页中动态内容的显示。最终,JSP文件会通过Web服务器的Web容器编译成一个Servlet,用来处理各种请求。
JSP特征
跨平台
由于JSP是基于Java语言的,它可以使用Java API,所以它也是跨平台的,可以应用于不同的系统中,如Windows、Linux等。当从一个平台移植到另一个平台时,JSP和JavaBean的代码并不需要重新编译,这是因为Java的字节码是与平台无关的,这也符合了Java语言“一次编译,到处运行”的特点。
业务代码相分离
在使用JSP技术开发Web应用时,可以将界面的开发与应用程序的开发分离开。开发人员使用HTML设计界面,使用JSP标签和脚本动态生成页面上的内容。在服务器端,JSP容器负责解析JSP标签和脚本程序,生成所请求的内容,并将执行结果以HTML页面的形式返回给浏览器。
组件重用
JSP中可以健用JavaBean编写业务组件,也就是使用一个JavaBean封装业务处理代码或者作为一个数据存储模型,在JSP页面中,甚至在整个项目中,都可以重复使用这个JavaBean ,同时,JavaBean也可以应用到其他Java应用程序中。
预编译
预编译就是在用户第一次通过浏览器访问JSP页面时,服务器将对JSP页面代码进行编译,并且仅执行一次编译。编译好的代码将被保存,在用户下一次访问时,会直接执行编译好的代码。这样不仅节约了服务器的CPU资源,还大大提升了客户端的访问速度。
JSP运行原理
JSP工作模式
JSP的工作模式是请求/响应模式,客户端首先发出HTTP请求,JSP程序收到请求后进行处理并返回处理结果。一个JSP文件第一次被请求时,JSP容器把该JSP文件转换成为一个Servlet ,而这个容器本身也是一个Servlet。
JSP页面的基本构成
一个JSP页面可以包括指令标识、HTML代码、JavaScript代码、嵌入的Java代码、注释 和 JSP动作标识等内容。
JSP脚本元素
JSP脚本元素是指嵌套在"<%”和“%>”之中的一条或多条Java程序代码。通过JSP脚本元素可以将Java代码嵌入HTML页面中,所有可执行的Java代码,都可以通过JSP脚本执行。JSP脚本元素主要包含如下三种类型:
JSP Scriptlets
JSP Scriptlets是一段代码片段。所谓代码片段,就是在JSP页面中嵌入的Java代码或脚本代码。代码片段将在页面请求的处理期间被执行,通过Java代码可以定义变量或流程控制语句等;而脚本代码可以应用JSP的内置对象在页面输出内容、处理请求和访问session会话等。JSP Scriptlets的语法格式如下所示:
<%java代码(变量、方法、表达式等)%>
声明标识
在JSP Scriptlets中可以进行属性的定义,也可以输出内容,但是它不可以进行方法的定义。如果想在脚本元素中定义方法,可以使用声明标识。声明标识用于在JSP页面中定义全局变量或方法,它以"<%!"开始,以“%>”结束。通过声明标识定义的变量和方法可以被整个JSP页面访问,所以通常使用该标识定义整个JSP页面需要引用的变量或方法。
声明标识的语法格式如下所示:
<%!
定义变量或方法等
%>
JSP表达式
JSP表达式( expression )用于向页面输出信息,它以“<%=”开始,以“%>"结束,其基本的语法格式如下所示:
<%=expression %>
上述语法格式中,参数expression可以是任何Java语言的完整表达式,该表达式的最终运算结果将被转换成一个字符串。
page指令
在JSP页面中,经常需要对页面的某些特性进行描述,例如,页面的编码方式,JSP页面采用的语言等,这些特性的描述可以通过page指令实现。page指令的具体语法格式如下所示:
<%@ page 属性名1="属性值1" 属性名2="属性值2”...%>
page用于声明指令名称,属性用来指定JSP页面的某些特性。page指令还提供了一系列与JSP页面相关的属性。
include指令
在实际开发时,有时需要在JSP页面中包含另一个JSP页面,这时,可以通过include指令实现,include指令的具体语法格式如下所示:
<%@ include file="被包含的文件地址"%>
include指令只有一个file属性,用于指定要包含文件的路径。需要注意的是,插入文件的路径一般不以“/”开头,而是使用相对路径。
使用include指令的常见问题
-
被引入的文件必须遵循JSP语法,其中的内容可以包含静态HTML、JSP脚本元素和JSP指令等普通JSP页面所具有的一切内容。
-
除了指令元素之外,被引入的文件中的其他元素都被转换成相应的Java源代码,然后插入进当前JSP页面所翻译成的Servlet源文件中,插入位置与include指令在当前JSP页面中的位置保持一致。
-
file属性的设置值必须使用相对路径,如果以 “/” 开头,表示相对于当前Web应用程序的根目录(注意不是站点根目录); 否则,表示相对于当前文件。需要注意的是,这里的file属性指定的相对路径是相对于文件 ( file ) ,而不是相对于页面 ( page )。
-
在应用include指令进行文件包含时,为了使整个页面的层次结构不发生冲突,建议在被包含页面中将
<html>
,<body>
等标签删除,因为在包含页面的文件中已经指定了这些标签。
taglib指令
在JSP文件中,可以通过taglib指令标识该页面中所使用的标签库,同时引用标签库,并指定标签的前缀。在页面中引用标签库后,就可以通过前缀来引用标签库中的标签。taglib指令的具体语法格式如下:
<%@ taglib prefix="tagPrefix" uri="tagURI"%>
prefix:用于指定标签的前缀,该前缀不能命名为jsp、 jspx、java、sun、servlet和sunw。
uri:用于指定标签库文件的存放位置。
在页面中引用JSTL中的核心标签库,示例代码如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core”%>
包含文件元素<jsp:include>
在JSP页面中,<jsp:include>
动作元素用于向当前页面引入其他的文件,被引入的文件可以是动态文件,也可以是静态文件。<jsp:include>
动作元素的具体语法格式如下所示:
<jsp:include page="URL" flush="true|false”/>
page :用于指定被引入文件的相对路径。例如,指定属性值为top.jsp,则表示将当前JSP文件相同文件夹下的top.jsp文件引入到当前JSP页面中。
flush : flush属性用于指定是否将当前页面的输出内容刷新到客户端,默认情况下,flush属性的值为false。
include指令与jsp:include动作元素的区别
在应用include指令包含文件时,由于被包含的文件最终会生成一个文件,所以在被包含文件、包含文件中不能有重复的变量名或方法;而在应用<jsp:include>
动作元素包含文件时,由于每个文件是单独编译的,所以被包含文件和包含文件中的重名变量和方法是不冲突的。
注意: <jsp:include>
动作元素对包含的动态文件和静态文件的处理方式是不同的,如果被包含的是静态文件,则包含页面执行后,在使用了<jsp:include>
动作元素的位置将会输出被包含文件的内容。如果<jsp:include>
动作元素包含的是一个动态文件,那么JSP编译器将编译并执行被包含文件。
请求转发元素<jsp:forward>
<jsp:forward>
动作元素可以将当前请求转发到其他Web资源(HTML页面、JSP页面和Servlet等),执行请求转发之后,当前页面将不再执行,而是执行该元素指定的目标页面。<jsp:forward>
具体语法格式如下所示:
<jsp:forward page="relativeURL"/>
page属性用于指定请求转发到的资源的相对路径,该路径的目标文件必须是当前应用中的内部资源。
隐式对象
在JSP页面中,有一些对象需要频繁使用,如果每次都重新创建这些对象则会非常麻烦。为了简化Web应用程序的开发,JSP2.0规范中提供了9个隐式(内置)对象,它们是JSP默认创建的,可以直接在JSP页面中使用。
名称 | 类型 | 描述 |
---|---|---|
out | javax.servlet.jspJspWriter | 用于页面输出 |
request | javax.servlet.http.HttpServletRequest | 得到用户请求信息 |
response | javax.servlet.http.HttpServletResponse | 服务器向客户端的回应信息 |
config | javax.servlet.ServletConfig | 服务器配置,可以取得初始化参数 |
session | javax.servlet.http.HttpSession | 用来保存用户的信息 |
application | javax.servlet.ServletContext | 所有用户的共享信息 |
page(基本不用) | java.lang.Object | 指当前页面转换后的Servlet类的实例 |
pageContext | javax.servlet.jsp.PageContext | JSP的页面容器 |
exception | java.lang.Throwable | 表示JSP页面所发生的异常,在错误页中才起作用 |
out对象
在JSP页面中,需要向客户端发送文本内容,向客户端发送文本内容可以使用out对象实现。out对象是javax.servlet.jsp.JspWriter
类的实例对象,它的作用与ServletResponse.getWriter()
方法返回的PrintWriter对象非常相似,都是用来向客户端发送文本形式的实体内容。不同的是,out对象的类型为JspWriter,它相当于带缓存功能的PrintWriter。
在JSP页面中,通过out隐式对象写入数据相当于将数据插入到 JspWriter对象的缓冲区中,只有调用了**ServletResponse.getWriter()**方法,缓冲区中的数据才能真正写入到Servlet引擎所提供的缓冲区中。
pageContext对象
在JSP页面中,使用pageContext对象可以获取JSP的其他8个隐式对象。pageContext对象是**javax.servlet.jsp.PageContext
类的实例对象,它代表当前JSP页面的运行环境**,并提供了一系列用于获取其他隐式对象的方法。
exception对象
在JSP页面中,经常需要处理一些异常信息,处理异常信息可以通过exception对象实现。exception对象是**java.lang.Exception
类的实例对象,它用于封装JSP中抛出的异常信息。需要注意的是,exception对象只有在错误处理页面才可以使用,即page指令**中指定了属性<%@ page isErrorPage="true"%>
的页面。
EL*
EL全称为Expression Language,即表达式语言。它是JSP 2.0引入的一个新内容。EL可以简化JSP开发中的对象引用,从而规范页面代码,增加程序的可读性及可维护性。EL为不熟悉Java语言页面开发的人员提供了一个开发JavaWeb应用的新途径。
语法
EL的语法非常简单,都是以“${”符号开始,以“}”符号结束的,具体格式如下
${表达式}
**“${表达式}”**中的表达式必须符合EL语法要求。
小提示:
由于EL的语法以“KaTeX parse error: Expected '}', got 'EOF' at end of input: …头,如果在JSP网页中要显示“{"字符串,必须在前面加上 “\” 符号,即“\${
”,或者写成“KaTeX parse error: Expected '}', got 'EOF' at end of input: {{}",也就是用表达式输出“${**"符号
EL基本语法的特点
-
EL可以与JavaScript语句结合使用。
-
EL可以自动进行类型转换。如果想通过EL获取两个字符串数值(如numberl和number2)的和,可以直接通过“+”符号进行连接
(如${number1+number2} )。
-
EL不仅可以访问一般变量,还可以访问JavaBean中的属性、嵌套属性和集合对象。
-
在EL中,可以执行算术运算、逻辑运算、关系运算和条件运算等。
-
在EL中,可以获取pageContext对象,进而获取其他内置对象。
-
在使用EL进行除法运算时,如果除数为0,则返回表示无穷大的Infinity,而不返回错误。
-
在EL中,可以访问 JSP的作用域( request、session、application以及page )。
标识符
在EL中,经常需要使用一些符号标记一些名称,如变量名、自定义函数名等,这些符号被称为标识符。EL中的标识符可以由任意的大小写字母、数字和下划线组成,为了避免出现非法的标识符,在定义标识符时还需要遵循以下规范:
- 不能以数字开头。
- 不能是EL中的关键字,如and、or、gt等。
- 不能是EL隐式对象,如pageContext。
- 不能包含单引号 ( ’ )、双引号 ( " )、减号 ( - ) 和正斜线 ( / ) 等特殊字符。
变量
EL中的变量就是一个基本的存储单元,EL中的变量不用事先定义就可以直接使用。EL可以将变量映射到一个对象上,具体示例如下所示:
${product}
在上述示例中,product就是一个变量,通过表达式${product}就可以访问变量product的值。
empty运算符
在EL中,判断对象是否为空,可以通过empty运算符实现,该运算符是一个前缀( prefix )运算符,即empty运算符位于操作数前方,用来确定一个对象或变量是否为null或空。empty运算符的语法
格式如下:
${empty
expression}
在上述语法格式中,expression用于指定要判断的变量或对象。
EL中pageContext对象的用法
为了获取JSP页面的隐式对象,可以使用EL中的pageContext隐式对象。pageContext隐式对象用法示例代码如下∶
${pageContext.response.characterEncoding}
pageContext对象用于获取response对象中的characterEncoding属性。
Web域相关对象
在EL中提供了4个用于访问作用域范围的隐式对象,即pageScope(小域)、requestScope、sessionScope和applicationScope(大域)。应用这4个隐式对象指定所要查找的标识符的作用域后,系统将不再按照默认的顺序( page、Request、session及application )查找相应的标识符。它们与JSP中的page、request、session及application内置对象类似,只不过这4个隐式对象只能用于获取指定范围内的属性值,而不能获取其他相关信息。
访问环境信息的隐式对象
获取客户端传递的请求参数
在JSP页面中,经常需要获取客户端传递的请求参数,为此,EL提供了param和paramValues两个隐式对象,这两个隐式对象专门用于获取客户端访问JSP页面时传递的请求参数。
param
param对象用于获取请求参数的某个值,它是Map类型,与request.getParameter()方法相同,在使用EL获取参数时,如果参数不存在,返回的是空字符串,而不是null。param对象的语法格式比较简单,具体示例如下:
${param.num}
paramValues
如果一个请求参数有多个值,可以使用paramValues对象获取请求参数的所有值,该对象返回请求参数所有值组成的数组,如果要获取某个请求参数的第一个值,可以使用如下代码︰
${paramValues.nums[0]}
Cookie对象
在JSP开发中,经常需要获取客户端的Cookie信息,为此,在EL中,提供了Cookie隐式对象,该对象是一个集合了所有Cookie信息的Map集合,Map集合中元素的键为各个Cookie的名称,值则为对应的Cookie对象。cookie对象用法示例如下:
//获取cookie对象的信息
${cookie.userName}
//获取cookie对象的名称
${cookie.userName.name}
//获取cookie对象的值
${cookie.userName.value}
initParam对象
JSTL(标签库)
虽然JSTL叫做标准标签库,但实际上它是由5个功不同的标签库组成。这5个标签库分别是核心标签库*、国际化/格式化标签库、SQL标签库、XML标签库和函数标签库。在使用这些标签库之前,必须在JSP页面的顶部使用<%@taglib%>
指令定义引用的标签库和访问前缀。
核心标签库
使用核心标签库的taglib指令格式如下:
<%@taglib prefix="c" url= "http://java.sun.com/jsp/jstl/core" %>
核心标签库主要用于完成JSP页面的常用功能,包括JSTL的表达式标签、URL标签、流程控制标签。例如,用于输出文本内容的<c:out>
标签、用于条件判断的<c:if>
标签、用于迭代循环的<c:forEach>
标签等。
<c:out>
标签
该标签可以将一段文本内容或表达式的结果输出到客户端。如果<c:out>
标签输出的文本内容中包含需要进行转义的特殊字符,例如 >、< 、& 、’ 、"等, <c:out>
标签会默认对它们进行HTMIL编码转换后再输出。
<c:out>
标签两种语法格式
语法1︰没有标签体的情况
<c:out value= "value" [default="defaultValue"]
[escapeXml= "{true|false}"]/>
语法2:有标签体的情况
<c:out value= "value" [escapeXml="{truelfalse}"]>
defaultValue
</c:out>
- value属性用于指定输出的文本内容。
- default属性用于指定当value属性为null时所输出的默认值,该属性是可选的(方括号中的属性都是可选的)。
- escapeXml属性用于指定是否格>、<、&'、"拿特殊字符进行HTML编碓转换后再进行输出,默认值为true.
需要注意的是,只有当value属性值为null时,<c:out>
标签才会输出默认值如果没有指定默认值,则默认输出空字符串。
<c:remove>
移除标签
<c:remove>
标签用于移除指定的JSP范围内的变量,其语法格式如下:
<c:remove var="name" [scope=”范围”]/>
<c:remove>
标签参数含义如下:
var:用于指定要移除的变量名。
scope :用于指定变量的有效范围,可选值有page、request、session和application,默认值为page。如果在该标签中没有指定变量的有效范围,那么将分别在page、request、session和application的范围内查找要移除的变量并移除。例如,在一个页面中,存在不同范围的两个同名变量,当不指定范围时移除该变量,这两个范围内的变量都将被移除。因此,在移除变量时,最好指定变量的有效范围。
流程控制标签
<c:if>
标签
在程序开发中,经常需要使用if语句进行条件判断,如果要在JSP页面中进行条件判断,就需要使用Core标签库提供的<c:if>
标签,该标签专门用于完成JSP页面中的条件判断,它有两种语法格式。
语法1∶没有标签体的情况
<cif test="testCondition" var= "result"
[scope="{page|request|session|application}"]/>
语法2∶有标签体的情况,在标签体中揩定要输出的内容
<c:if test="testCondition" var="result"
[scope="{page|request|session|application}"]>
body content
</c:if>
test属性用于设置逻辑表达式。
var属性用于指定逻辑表达式中变量的名字。
scope属性用于指定var变量的作用范围,默认值为page。
<c:choose>
标签
<c:choose>
标签没有属性,在它的标签体中只能嵌套一个或多个**<c:when>
标签,零个或一个<c:otherwise>
**标签,并且同一个<c:choose>
标签中所有的<c:when>
子标签必须出现在<c:otherwise>
子标签之前,其语法格式如下:
<c:choose>
Body content(<when> and <otherwise>subtags)
</c:choose>
<c:when>
标签
<c:when>
标签只有一个test属性,该属性的值为布尔类型。test属性支持动态值,其值可以是一个条件表达式,如果条件表达式的值为true,就执行这个<c:when>
标签体的内容,其语法格式如下: (相当于if)
<c:when test="testCondition">
Body content
</c:when>
<c:otherwise>
标签 (相当于else)
循环标签
<c:forEach>
标签
<c:forEach>
标签有两种语法格式,具体如下:
语法1∶迭代包含多个对象的集合
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
语法2∶迭代指定范围内的集合
<c:forEach [var= "varName"] [varStatus="varStatusName"] begin="begin"end="end" [step="step"]>
body content
</c:forEach>
var属性:用于将当前迭代到的元素保存到page域中的名称。
items属性:用于指定将要迭代的集合对象。
varStatus属性:用于指定将当前迭代状态信息的对象保存到page域中的名称
begin属性:用于指定从集合中第几个元素开始进行迭代,begin的索引值从0开始,如果没有指定items属性,就从begin指定的值开始迭 代,直到迭代结束为止。
step属性:用于指定迭代的步长,即迭代因子的增量。
URL相关标签
<c:url>
标签
语法1∶没有标签实体的情况
<c:url value="value" [context="context"] [var="varName"]
[scope="{page|request|session|application}"]>
语法2∶有标签实体的情况,在标签体中指定构造URL参数
<c:url value="value" [context="context"][var="varName"][scope="{page|request|session|application}"]>
<c:param>标签
</c:url>
value属性:用于指定构造的URL。
context属性:用于指定导入同一个服务器下其他Web应用的名称。
var属性:用于指定将构造的URL地址保存到域对象的属性名称。
scope属性:用于将构造好的URL保存到域对象中。
<c:param>
标签
<c:redirect>
标签 (重定向)
JavaBean
特点
JavaBean是一个遵循特定写法ava类,它是为了和JSP页面传输数据、简化交互过程而产生的。JavaBean通常具有如下特点:
- JavaBean必须具有一个无参的构造函数。
- 属性必须私有化。
- 私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵守一定的命名规范。
种类
JavaBean起初的目的是将可以重复使用的代码进行打包。在传统的应用中,JavaBean主要用于实现一些可视化界面,如一个窗体、按钮、文本框等,这样的JavaBean称之为可视化的JavaBean。
随着技术的不断发展与项目的需求,JavaBean的功能与应用范围也在不断扩展,目前JavaBean主要用于实现一生业务逻辑或封装一些业务对象,由于这样的JavaBean并没有可视化的界面,所以又称之为非可视化的JavaBean。
注意:可视化的JavaBean一般应用于Swing程序中,Java Web开发中并不会采用,JavaWeb开发使用非可视化的JavaBean,实现一些业务逻辑或封装一些业务对象。
<jsp:useBean>
标签和<jsp:getProperty>
标签操作Java类
<jsp:useBean>
标签和<jsp:getProperty>
标签之所以能够操作Java类,是因为我们编写的Java类遵循了JavaBean规范。<jsp:useBean>
标签用于获取类的实例,基内部是通过调用类的默认构造方法实现的,所以,JavaBean需要有一个默认的无参构造方法;
<jsp:getProperty>
标签获取JavaBean中的属性,其内部是通过调用属性的getter方法法实现的,所以,JavaBean规范要求为属性提供公共的( public )类型访问方法。只有严格遵循JavaBean规范,才能对其更好地应用,因此,在编写JavaBean时要遵循指定的JavaBean规范。
解决中文乱码问题
JSP开发模型
JSP Model1
JSP Model1采用JSP+JavaBean的技术,将页面显示和业务逻辑分开。其中,JSP实现流程控制和页面显示,JavaBean对象封装数据和业务逻辑。
JSP Model2
JSP Model2架构模型采用JSP+Servlet+ JavaBean的技术,此技术将原本JSP页面中的流程控制代码提取出来,封装到Servlet中,实现了页面显示、流程控制和业务逻辑的分离。实际上JSP Model2模型就是MVC ( Model-View-Controller,模型-视图-控制器)设计模式,其中控制器的角色由Servlet实现,视图的角色由JSP页面实现,模型的角色是由JavaBean实现。JSP Model2的工作原理如下图所示。
由上图可知,Servlet充当了控制器的角色,它首先接收浏览器发送的请求,然后根据请求信息实例化JavaBean对象,由JavaBean对象完成数据库操作并将操作结果进行封装,最后选择相应的JSP页面将响应结果显示在浏览器中。
MVC设计模式
模型
**模型( Model )**负责管理应用程序机业务数据、定义访问控制以及修改这些数据的业务规则。当模型的状态发生改变时,它会通知视图发生改变,并为视图提供查询模型状态的方法。
视图
**视图( View )**负责与用户进行交互,它从模型中获取数据向用户展示,同时也能将用户请求传递给控制器进行处理。当模型的状态发生改变时,视图会对用户界面进行同步更新,从而保持与模型数据的一致性。
控制器
**控制器( Controller )**负责应用程序中处理用户交互的部分,它从视图中读取数据,控制用户输入,并向模型发送数据。
在上图中,当控制器接收到用户的请求后,会根据请求信息调用模型组件的业务方法,对业务方法处理完毕后,再根据模型的返回结果选择相应的视图组件显示处理结果和模型中的数据。
Filter
在Servlet高级特性中,Filter被称为过滤器,Filter基本功能就是对Servlet容器调用Servlet的过程进行拦截,它位于客户端和处理程序之间,能够对请求和响应进行检查和修改。Filter在Web应用中的拦截过程如下图所示。
作用
Filter除了可以实现拦截功能,还可以提高程序的性能,在Web开发时,不同的Web资源中的过滤操作可以放在同一个Filter中完成,这样可以不用多次编写重复代码,从而提高了程序的性能。
Filter相关API
Filter接口
方法声明 | 功能描述 |
---|---|
init(FilterConfig filterConfig) | init()方法是Filter的初始化方法,创建Filter实例后将调用init()方法。该方法的参数filterConfig用于读取Filter的初始化参数。 |
doFilter(ServletRequest request,ServletResponse response,FilterChain chain) | doFilter()方法完成实际的过滤操作,当客户的请求满足过滤规则时,Servlet容器将调用过滤器的doFilter()方法完成实际的过滤操作。doFilter()方法有多个参数,其中,参数request和response为Web服务器或Filter链中的上一个Filter传递过来的请求和响应对象;参数chain代表当前Filter链的对象。 |
destroy() | 该方法用于释放被Filter对象打开的资源,例如关闭数据库和 IO流。destroy()方法在Web服务器释放Filter对象之前被调用。 |
FilterConfig接口
FilterConfig接口用于封装Filter的配置信息,在Filter初始化时,服务器将FilterConfig对象作为参数传递给Filter对象的初始化方法。
方法声明 | 功能描述 |
---|---|
String getFilterName() | 返回Filter的名称。 |
ServletContext getServletContext() | 返回FilterConfig对象中封装的ServletContext对象。 |
String getInitParameter(String name) | 返回名为name的初始化参数值。 |
Enumeration getInitParameterNames() | 返回Filter所有初始化参数的枚举。 |
Filter生命周期
创建阶段
Web服多器启动时候会创建Filter实例对象,并调用**init()**方法,完成对象的初始化。需要注意的是,在一次完整的请求当中,Filter对象只会创建一次,init()方法也只会执行一次。
执行阶段
当客户端请求目标资源时,服务器会筛选出符合映射条件的Filter,并按照类名的的先后顺序依次执行doFilter()方法。例如MyFilter01优先MyFilter02执行。在一次完整的请求当中,doFilter()方法可以执行多次。
销毁阶段
服务器关闭时,Web服务器调用destroy()方法销毁Filter对象。
@WebFilter注解
@WebFilter注解的属性filterName用于设置Filter的名称,urlPattern属性用于匹配用户请求的URL,例如“/MyServlet”,表示过滤器MyFilter会拦截发送到/MyServlet资源的请求。这个URL还可以使用通配符“*****”表示,例如,“*.do”匹配所有以“.do”结尾的Servlet路径。
Filter映射
Filter拦截的资源需要在Filter实现类中使用注解@WebFilter进行配置,这些配置信息就是Filter映射。Filter的映射方式可分为两种:使用通配符“*”拦截用户所有请求和拦截不同访问方式的请求。
@WebFilter注解有一个特殊的属性dispatcherTypes,它可以指定过滤器的转发模式dispatcherTypes属性有4个常用值,REQUEST、INCLUDE、FORWARD和ERROR。
Filter链
Filter链的拦截
在一个Web应用程序中可以注册多个Filter,每个Filter都可以针对某一个URL的请求进行拦截。如果多个Filter都对同一个URL的请求进行拦截,那么这些Filter就组成一个Filter链。Filter链使用FilterChain对象表示,FilterChain对象提供了一个doFilter()方法,该方法的作用是让Filter链上的当前过滤器放行,使请求进入下一个Filter。
当浏览器访问Web服务器中的资源时需要经过两个过滤器Filter1和Filter2,首先Filter1会对这个请求进行拦截,在Filter1过滤器中处理好请求后,通过调用Filter1的doFilter()方法将请求传递给Filter2,Filter2将用户请求处理后同样调用doFilter()方法,最终将请求发送给目标资源。当Web服务器对这个请求做出响应时,响应结果也会被过滤器拦截,拦截顺序与之前相反,最终响应结果被发送给客户端。
Listener
在Web程序开发中,经常需要对某些事件进行监听,以便及时作出处理,如监听鼠标单击事件、监听键盘按下事件等。为此,Servlet提供了监听器(Listener ),专门用于监听Servlet事件。
Listener在监听过程中会涉及几个重要组成部分,具体如下。
(1)事件∶用户的一个操作,如单击一个按钮、调用一个方法、创建一个对象等。
(2)事件源︰产生事件的对象。
(3)事件监听器:负责监听发生在事件源上的事件。
(4)事件处理器︰监听器的成员方法,当事件发生的时候会触发对应的处理器(成员方法)。
注意:当用户执行一个操作触发事件源上的事件时,该事件会被事件监听器监听到,当监听器监听到事件发生时,相应的事件处理器就会对发生的事件进行处理。
Linstener的API
Web应用中的Listener就是一个实现了特定接口的Java程序,专门用于监听Web应用程序ServletContext、HttpSession和ServletRequest等域对象的创建和销毁过程,以及这些域对象属性的修改,并且感知绑定到HttpSession域中某个对象的状态变化。
Listener中的8种Servlet事件监听器可以分为三类,具体如下。
( 1 ) 用于监听域寸象创建和销毁的监听器:ServletContextListener接口、HttpSessionListener接口和ServletRequestListener接口。
( 2 ) 用于监听域对象属性增加和删除的监听器:ServletContextAttributeListener接口、HttpSessionAttributeListener接口和ServletRequestAttributeListener接口.
( 3 ) 用于监听绑定到HttpSession域中某个对象状态的事件监听器:HttpSessionBindingListener接口和HttpSessionActivationListener接口。
文件上传的原理
要实现Web开发中的文件上传功能,通常需完成两步操作∶一是在Web项目的页面中添加上传输入项,二是在Servlet中读取上传文件的数据,并保存到目标路径中。
由于大多数文件的上传都是通过表单的形式提交给服务器的,因此,要想在程序中实现文件上传功能,首先要创建一个用于提交上传文件的表单页面。在表单页面中,需要使用<input type="file">
标签在jsp页面中添加文件上传输入项。
<input type="file">
标签
标签的使用需要注意以下两点:
- 必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
- 必须把将表单页面的method属性设置为post方式,enctype属性设置为"multipart/form-data"类型。
示例代码如下∶
<%--指定表单数据的enctype属性以及提交方式--%>
<form enctype="multipart/form-data" method="post">
<%--指定标记的类型和文件域的名称--%>
选择上传文件:<input type="file" name="myfile"/><br/>
</form>
FileItem接口
Fileltem接口主要用于封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem对象。Commons-FileUpload组件在处理文件上传的过程中,将每一个表单域(包括普通的文本表单域和文件域)封装在一个Fileltem对象中。
为了便于讲解,在此将Fileltem接口的实现类称为Fileltem类,FileItem类实现了序列化接口Serializable,因此,Fileltem类支持序列化操作。
FileItem类的方法
方法声明 | 功能描述 |
---|---|
boolean isFormField() | isFormField()方法用于判断Fileltem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通文本表单字段则返回true,否则返回false。 |
String getName() | getName()方法用于获取文件上传字段中的文件名。如果Fileltem类对象对应的是普通文本表单字段,getName()方法将返回null,否则,只要浏览器将文件的字段信息传递给服务器,getName()方法就会返回一个字符串类型的结果,如C:\Sunset.jpg。 |
String getFieldName() | getFieldName()方法用于获取表单字段元素描述头的name属性值,也是表单标签name属性的值。例如“name=file1”中的“file |
ServletFileUpload类*
方法声明 | 功能描述 |
---|---|
ServletFileUpload() | 构造一个未初始化的ServletFileUpload实例对象 |
ServletFileUpload(FileltemFactory fileItemFactory) | 根据参数指定的FileltemFactory对象创建一个ServletFileUpload对象 |
在文件上传过程中,在使用第一个构造方法创建ServletFileUpload对象时,需要在解析请求之前调用setFileItemFactory()方法设置fileltemFactory属性。
ServletFileUpload类是Apache组件处理文件上传的核心高级类,通过调用parseRequest(HttpServletRequest)方法可以将HTML中每个表单提交的数据封装成一个Fileltem对象,然后以List列表的形式返回。