servlet
简介
Servlet
是一个专门用来接收客户端发送过来的请求的小
web
程序。并且它还可以把数据回传给客户端
要编写一个
Servlet
小程序,这个程序的类必须要实现
Servlet
接口。
servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
要实现此接口,可以编写一个扩展
javax.servlet.GenericServlet
的一般
servlet,或者编写一个扩展 javax.servlet.http.HttpServlet
的
HTTP servlet。
此接口定义了初始化
servlet 的方法、为请求提供服务的方法和从服务器移除 servlet 的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:
1.
构造
servlet,然后使用 init
方法将其初始化。
2.
处理来自客户端的对
service
方法的所有调用。
3.
从服务中取出
servlet,然后使用 destroy
方法销毁它,最后进行垃圾回收并终止它。
Servlet
:
1
、接受浏览器发送过来的消息。
2
、给浏览器返回消息。浏览器认识
html
。可以动态去输出
html
7.2
、
servlet
快速入门
7.2.2
、手动编写
servlet
实现
写
servlet
做两件事
1
、实现
servlet
接口。 由
sun
公司定义的一个接口。
(
定义一个规范
)
2
、把类部署到
web
服务器中(
tomcat
)。
sun
公司定义一个
servlet
的规范。定义了
servlet
应该有哪些方法,以及方法需要的参数。
1
、实现
servlet
接口(javax.servlet.Servlet
)
2
、重写
service
方法
(service
方法每次请求都会调用一次
)
当浏览器输入地址,访问
servlet
的时候,
servlet
会执行
servcie
方法。
3
、在
Web
Content/WEB-INF/web.xml
中配置
servlet
的访问路径 。浏览器访问
servlet
的路径
web.xml
(新建
web
工程的时候,
eclipse
自动创建出来的)的位置:
在
web.xml
的根标签
web-app
下,直接书写如下内容。
4
、把项目部署到
tomcat
中,去启动
tomcat
。在地址栏中输入信息,访问
servlet
控制台打印:
解析
url
到
servlet
访问细节
(***
理解
)
访问过程分析:
7.2.6
、模拟
Get
请求和
Post
请求的分发
1
)修改代码如下:
/**
* 而因为service是具体业务处理方法。所以不同的
servlet
业务不同。所以把
service方法给我们留下了
*/
public
void
service(ServletRequest
req
, ServletResponse
res
)
throws
ServletException, IOException {
// 将servletRequest对象强转成为 HttpServletRequest对象
HttpServletRequest
httpRequest
= (
HttpServletRequest
)
req
;
// 获取请求的方式
String
method
=
httpRequest
.getMethod();
// get请求获取到"GET" ,post请求获取到"POST"字符串
System.
out
.println(
"请求的方式:"
+
method
);
// 根据请求的方式 执行不同的方法去做不同的处理
if
(
"GET"
.equals(
method
)) {
doGet();
}
else
if
(
"POST"
.equals(
method
)) {
doPost();
}
}
public
void
doPost() {
System.
out
.println(
"这是POST请求的处理方法"
);
}
public
void
doGet() {
System.
out
.println(
"这是GET请求的处理方法"
);
}
2
)准备
html
页面表单内容如下(分别测试
get
请求和
post
请求):
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
>
<
title
>
Insert title here
</
title
>
</
head
>
<
body
>
<
form
action
=
"http://127.0.0.1:8080/web06/helloServlet2"
method
=
"get"
>
用户名
:
<
input
name
=
"username"
type
=
"text"
/><
br
/>
密码
:
<
input
name
=
"password"
type
=
"password"
/>
<
br
/>
<
input
type
=
"submit"
/>
</
form
>
</
body
>
</
html
>
测试
get
请求的打印如下:
测试
post
请求的打印如下:
7.2.7
、继承
HttpServlet
类实现我们自己的
Servlet
程序
1)
继承
httpServlet
实现的
Servlet
类的代码如下:
package
com.atguigu.servlet;
import
java.io.IOException;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
/**
* 继承HttpServlet
*
@author
wzg
*
*/
public
class
HelloServlet3
extends
HttpServlet {
@Override
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
System.
out
.println(
"这是继承HttpServlet实现的Servlet类,doGet方法"
);
}
@Override
protected
void
doPost(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
System.
out
.println(
"这是继承HttpServlet实现的Servlet类,doPost方法"
);
}
}
2)
在
web.xml
文件中的配置
<
servlet
>
<!-- 给
servlet
起别名
-->
<
servlet-name
>
HelloServlet3
</
servlet-name
>
<!-- 告诉
tomcat
这个别名对应的是哪个具体的实现类
-->
<
servlet-class
>
com.atguigu.servlet.HelloServlet3
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<!-- 告诉
tomcat
当前配置的访问路径对应哪一个
Servlet
-->
<
servlet-name
>
HelloServlet3
</
servlet-name
>
<!-- 配置
servlet
的访问路径
http://ip:端口号/工程名/资源路径
http://127.0.0.1:8080/web06/helloServlet3
-->
<
url-pattern
>
/helloServlet3
</
url-pattern
>
</
servlet-mapping
>
3
)准备
html
页面表单内容如下(分别测试
get
请求和
post
请求):
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
>
<
title
>
Insert title here
</
title
>
</
head
>
<
body
>
<
form
action
=
"http://127.0.0.1:8080/web06/helloServlet
3
"
method
=
"get"
>
用户名
:
<
input
name
=
"username"
type
=
"text"
/><
br
/>
密码
:
<
input
name
=
"password"
type
=
"password"
/>
<
br
/>
<
input
type
=
"submit"
/>
</
form
>
</
body
>
</
html
>
测试
get
请求的打印如下:
测试
post
请求的打印如下:
Servlet
生命周期
servlet
的生命周期。
什么时候创建一个
servlet
?
什么时候去销毁一个
servlet
?
Servlet
的生命周期
1.
先调用
Servlet
的构造方法
2.
调用
init
方法 初始化
Servlet
3.
调用
Servlet
中的
service
方法 处理请求操作
4.
调用
destory
方法 执行
Servlet
销毁的操作
init
方法
:当服务器创建一个
serlvet
的时候,会去调用
init
方法。
当我们第一次去访问一个
servlet
的时候,会去创建这个
servlet
对象。并且只会创建一次。
当我们继承
HttpServlet
类实现
Servlet
程序,重写
init(Servletconfig config)
方法的时候,一定要在里面写上。
super
.init(
config
);
否则后面调用
getServletContext()
方法就会报空指针异常
@Override
public
void
init(ServletConfig
config
)
throws
ServletException {
super
.init(
config
);
//
一定要写上,因为在父类的方法中。这里保存了
ServletConfig
的引用
}
@Override
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException,
IOException {
getServletContext();
//
如果没有
super.init(config)
调用。这里就会
报空指针异常
}
Eclipse
创建
Servlet
程序(重点
*****
)
1
)通过
Eclipse
自动新建一个
Servlet
程序
2
)修改
Servlet
的访问
url
地址
3
)勾选需要生成的
Servlet
方法
4)
修改
doGet
方法和
doPost
方法后的代码内容如下:
在
web.xml
文件中自动生成的配置信息如下:
5
)准备
html
页面表单内容如下(分别测试
get
请求和
post
请求):
<!
DOCTYPE
html
PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
>
<
title
>
Insert title here
</
title
>
</
head
>
<
body
>
<
form
action
=
"http://127.0.0.1:8080/web06/helloServlet
4
"
method
=
"get"
>
用户名
:
<
input
name
=
"username"
type
=
"text"
/><
br
/>
密码
:
<
input
name
=
"password"
type
=
"password"
/>
<
br
/>
<
input
type
=
"submit"
/>
</
form
>
</
body
>
</
html
>
测试
get
请求的打印如下:
测试
post
请求的打印如下:
Servlet
类的继承体系:
ServletConfig
类
ServletConfig
类,见名知义。它是
Servlet
类的配置文件类。封装了
Servlet
的配置文件的信息。
它常用的功能有三个。
1.
获取
Servlet
在
web.xml
文件中配置的
Servlet
名称(也就是
servlet-name
的值
<
servlet-name
>ConfigServlet
</
servlet-name
>
)。
2.
获取
Servlet
初始化信息。(
web.xml
文件中
<Servlet>
标签中
<
init-param
>
的初始化信息
)
3.
获取
ServletContext
域对象
1) Servlet
中的示例代码:
/**
*
init
是初始化方法。
* 一个
Servlet
对应一个
ServletConfig对象
*/
public
void
init(ServletConfig
_config
)
throws
ServletException {
super
.init(
config
);
// 获取
config
对象
ServletConfig
config
=
_config
;
System.
out
.println(
config
);
// 它常用的功能有三个。
// 1.获取
Servlet
在
web.xml文件中配置的
Servlet
名称(也就是
servlet
-name的值<servlet-name>ConfigServlet</servlet-name>)。
String
s
ervlet_name
=
config
.getServletName();
System.
out
.println(
"servlet-name ==>> "
+
s
ervlet_name
);
// 2.获取
Servlet
初始化信息。(
web.xml文件中<Servlet>标签中 <init-
param
>的初始化信息 )
String
param_value
=
config
.getInitParameter(
"username"
);
System.
out
.println(
"username 的值:"
+
param_value
);
// 3.获取ServletContext域对象
// ServletContext它是一个域对象,并且一个Web工程对应一个ServletContext
ServletContext
context
=
config
.getServletContext();
System.
out
.println(
context
);
}
2) web.xml
文件中的配置信息:
<
servlet
>
<
servlet-name
>
ConfigServlet
</
servlet-name
>
<
servlet-class
>
com.atguigu.servlet.ConfigServlet
</
servlet-class
>
<!-- 给
servlet
添加初始化参数
-->
<
init-param
>
<!--
param
-name 是初始化参数的名 -->
<
param-name
>
username
</
param-name
>
<!--
param
-value 是初始化参数的值 -->
<
param-value
>
root
</
param-value
>
</
init-param
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
ConfigServlet
</
servlet-name
>
<
url-pattern
>
/configServlet
</
url-pattern
>
</
servlet-mapping
>
3)
在浏览器中输入访问地址
http://127.0.0.1:8080/day07/configServlet
访问测试:
4)
控制台打印信息
servletContext
说明
(ServletContext
对应一个
Web
工程
,
重
*****
点
)
什么是
ServletContext
?
第一:
ServletContext
是一个接口。
第二:
ServletContext
是一个域对象!
第三:每个
Web
工程,都对应一个
ServletContext
对象!
ServletContext
有什么作用?
第一:
ServletContext
可以获取
web.xml
文件中的配置上下文参数
第二:
ServletContext
可以获取
web
工程在服务器的工程名
第三:
ServletContext
可以获取
web
工程中文件夹或文件在服务器硬盘上的绝对路径
第四:
ServletContext
可以设置、获取
web
工程的全局属性
9.1
、
ServletContext
获取在
Web.xml
中配置的全局参数
1) Servlet
中的示例代码:
package
com.atguigu.servlet;
import
java.io.IOException;
import
javax.servlet.ServletConfig;
import
javax.servlet.ServletContext;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
/**
*
Servlet
implementation class ContextServlet
*/
public
class
ContextServlet
extends
HttpServlet {
private
static
final
long
serialVersionUID
= 1L;
protected
void
doGet(HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException, IOException {
// 获取ServletConfig对象
ServletConfig
config
= getServletConfig();
// 获取
Servlet
的上下文对象
ServletContext
context
=
config
.getServletContext();
// 获取web.xml文件中配置的参数的值
// 正确。ServletContext只能获取context-
param
配置的参数
String
passwordValue
=
context
.getInitParameter(
"password"
);
System.
out
.println(
"获取context-param参数:"
+
passwordValue
);
// ServletContext无法获取
Servlet
中配置的
init
-
param
参数
String
usernameValue
=
context
.getInitParameter(
"username"
);
System.
out
.println(
"获取servlet配置的init-param参数:"
+
usernameValue
);
}
protected
void
doPost(HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException, IOException {
}
}
2) web.xml
中的配置信息
<!-- 配置由ServletContext获取的参数 -->
<
context-param
>
<!-- 配置参数的名 -->
<
param-name
>
password
</
param-name
>
<!-- 配置参数的值 -->
<
param-value
>
root
</
param-value
>
</
context-param
>
<
servlet
>
<!-- 配置
Servlet
中的别名
-->
<
servlet-name
>
ContextServlet
</
servlet-name
>
<!-- 配置
Servlet
的全类名
-->
<
servlet-class
>
com.atguigu.servlet.ContextServlet
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<!-- 配置
Servlet
的别名
-->
<
servlet-name
>
ContextServlet
</
servlet-name
>
<!-- 配置
Servlet
的访问路径
-->
<
url-pattern
>
/contextServlet
</
url-pattern
>
</
servlet-mapping
>
3
) 控制台的打印信息:
9.2
、
ServletContext
对象获取布署后的工程名
(
常
*
用
)
projectPath
得到的结果:
/day07
9.3
、
ServletContext
获取工程目录或文件在服务器硬盘上的绝对路径(重
**
点)
1
)工程文件的目录图
2
)获取工程中目录和文件的硬盘绝对路径代码:
// 获取ServletConfig对象
ServletConfig
config
= getServletConfig();
// 获取
Servlet
的上下文对象
ServletContext
context
=
config
.getServletContext();
//获取/表示的路径表示从http://127.0.0.1:8080/工程名/ 所表示的硬盘绝对路径
// /也就是WebContent下的内容
String
path
=
context
.getRealPath(
"/"
);
System.
out
.println(
"/的硬盘路径:"
+
path
);
//获取/
imgs
表示的路径
// /
imgs
也就是表示
WebContent目录下的
imgs
目录,发布后的硬盘绝对路径。
String
imgspath
=
context
.getRealPath(
"/imgs"
);
System.
out
.println(
"/imgs的硬盘路径:"
+
imgspath
);
//获取/
imgs
表示的路径
// /
imgs
也就是表示
WebContent目录下的
imgs
目录里
wrong.png文件,发布后的硬盘绝对路径。
String
wrongpath
=
context
.getRealPath(
"/imgs/wrong.png"
);
System.
out
.println(
"/imgs/wrong.png的硬盘路径:"
+
wrongpath
);
3)
控制台打印:
9.4
、
ServletContext
设置全局共享属性(重
****
点)
我们可以创建两个
Servlet
程序。分别是:
ContextAttrServlet1
和
ContextAttrServlet2.
a)
在
ContextAttrServlet1
中直接通过
ServletContext
获取一个没有设置的属性值。
b)
然后在
ContextAttrServlet2
中,通过
ServletContext
设置一个全局的属性值。
c)
然后通过不同的访问顺序测试
ServletContext
对象管理的全局共享属性。
1) ContextAttrServlet1
的代码
<
servlet
>
<
servlet-name
>
ContextAttrServlet1
</
servlet-name
>
<
servlet-class
>
com.atguigu.servlet.ContextAttrServlet1
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
ContextAttrServlet1
</
servlet-name
>
<
url-pattern
>
/contextAttrServlet1
</
url-pattern
>
</
servlet-mapping
>
2) ContextAttrServlet2
的代码
<
servlet
>
<
servlet-name
>
ContextAttrServlet2
</
servlet-name
>
<
servlet-class
>
com.atguigu.servlet.ContextAttrServlet2
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
ContextAttrServlet2
</
servlet-name
>
<
url-pattern
>
/contextAttrServlet2
</
url-pattern
>
</
servlet-mapping
>
3)
访问测试过程:
3.
最后再访问
http://127.0.0.1:8080/day07/contextAttrServlet1
由于
contextAttrServlet2
中已经设置了属性值,这时候再访问可以获取到值。
4)
控制台打印信息: