一、什么是Servlet?
Servlet 是在服务器上运行来响应客户端请求的一种java组件。Servlet与具体的客户服务端协议无关,但Servlet常用于HTTP协议,所以,“Servle”t常被用于“HTTP Servlet”的意思。
Servlet使用的java软件包:javax.servlet(基本Servlet框架)和javax,servlet.http(HTTP Servlet)
HTTP Servlets典型应用包括:
1.通过提交HTML表单操作存储数据。
2.提供动态内容,如将从数据库中查询到的结果返回给客户端
3.管理无状态的HTTP上的有状态的信息,如一个为多个同时存在的客户管理购物车并映射每一个请求到正确的客户的在线购物系统
二、Servlets 和 CGI(Commone Gateway Interface)
最早用来产生动态网页服务的方法便是CGI,CGI是一种与语言无关的接口,此种接口允许服务器启动通过环境变化来获取与此次请求有关信息的外部程序。每一个请求都通过CGI程序或者CGI脚本由单独的线程响应。
Servlets相比CGI的几个优势:
1.Servlet中,每个请求由一个轻量级的Java线程处理,不用为每一个请求启动新的系统线程。
2.一个Servlet在请求期间会驻留在内存中。
3.响应所有并发的请求只需要唯一一个实例,节省了内存并可以使Servlet管理持久数据显得更快捷。
三、Servlet 生命周期
Servlet 的生命周期就是指创建 Servlet 实例之后其存在的时间以及何时消失
生命周期的 3个方法为:init()、service()、destroy()
1.装载servlet类以及其他可能使用到的类
2.调用init(ServletConfig config)方法加载配置信息,初始化servlet
3.调用service(doGet/doPost)方法处理业务逻辑,service方法在初始化前不会被调用
4.调用destroy方法销毁不再使用的servlet
四、Servlet的部署
1.用myeclipse建立好web工程,写好HelloClientServlet.java类
1import java.io.*;
2import javax.servlet.*;
3import javax.servlet.http.*;
4
5public class HelloClientServlet extends HttpServlet
6{
7 //doGet() 方法处理客户端作出的 GET 请求。
8 public void doGet(HttpServletRequest req,
9 HttpServletResponse res)
10 throws ServletException, IOException
11 {
12 res.setContentType("text/html");
13 PrintWriter out = res.getWriter();
14 out.println("<HTML><HEAD><TITLE>Hello Client!</TITLE>"+
15 "</HEAD><BODY>Hello Client!</BODY></HTML>");
16 out.close();
17 }
18
19 //doPost() 方法处理客户端作出的 POST 请求。
20 public void doPost(HttpServletRequest req,
21 HttpServletResponse res)
22 throws ServletException, IOException
23 {
24 doGet(req,res);
25 }
26}
2.web.xml文件中配置Servlet
1<!-- 第一个servlet程序配置 -->
2<servlet>
3<servlet-name>firstServlet</servlet-name>
4<servlet-class>HelloClientServlet的包路径</servlet-class>
5</servlet>
6<!-- 第一个servlet程序映射 -->
7<servlet-mapping>
8<servlet-name>firstServlet</servlet-name><!-- 必须与配置中的servlet-name相同 -->
9<url-pattern>/first.do</url-pattern>
10</servlet-mapping>
3.发布到本机web服务器(使用Tomcat5.5)中,通过http://localhost:服务器端口号/工程名/first.do启动servlet。
五、javax.servlet 包的接口介绍
ServletConfig
用来封装web.xml中对当前Servlet的配置信息
getInitParameter()---可以获取初始化参数
ServletContext
代表当前Servlet运行的上下文环境,Web容器会为每一个Web工程创建一个对应ServletContext对象
setAttribute()
getAttribute()
removeAttribute()
ServletRequest
为Servlet所发送的请求,用ServletRequest封装
setAttribute()
getAttribute()
removeAttribute()
getParameter()
常用子接口HttpServletRequest
ServletResponse
Servlet对客户段所做的响应,用ServletResponse描述
getWriter():获取PrintWriter输出流给客户发送的响应内容
setContentType:设置响应内容的响应类型和字符集信息
sendRedirect:设置重新请求路径
子接口HttpServletResponse
六、过滤器(Filter)
1.Servlet 过滤器是小型的 Web 组件,它们拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。
2.生命周期
初始化----当容器第一次加载该过滤器时, init() 方法将被调用。
过滤----doFilter() 方法被容器调用,同时传入分别指向这个请求/响应链中的ServletRequest 、 ServletResponse 和 FilterChain 对象的引用
销毁----容器紧跟在垃圾收集之前调用 destroy() 方法
3.编写字符编码过滤器
(1)实现Filter接口中的三个方法:
init() ----这个方法在容器实例化过滤器时被调用
doFilter() ----与 servlet 拥有一个 service() 方法(这个方法又调用 doPost() 或者 doGet() )来处理请求一样,过滤器拥有单个用于处理请求和响应的方法―― doFilter()。
destroy() ---这个方法执行任何清理操作,这些操作可能需要在自动垃圾收集之前进行
1import java.io.IOException;
2
3import javax.servlet.Filter;
4import javax.servlet.FilterChain;
5import javax.servlet.FilterConfig;
6import javax.servlet.ServletException;
7import javax.servlet.ServletRequest;
8import javax.servlet.ServletResponse;
9
10public class CharacterEncodingFilter implements Filter
11{
12
13 private String encode;
14
15 public void destroy()
16 {
17 this.encode = null;
18 }
19
20 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
21 throws IOException, ServletException
22 {
23 if(encode!=null)
24 {
25 request.setCharacterEncoding(encode);
26 response.setCharacterEncoding(encode);
27 }
28 // 将资源链到下一Filter, 如果这是最后一个Filter, 则将资源链到目的位置.
29 chain.doFilter(request, response);
30 }
31
32 public void init(FilterConfig config) throws ServletException
33 {
34 encode = config.getInitParameter("encode");
35 System.out.println("CharacterEncodingencode="+encode);
36 }
37
38}
(2)web.xml文件中配置字符编码过滤器
1<!-- 字符编码过滤器配置 -->
2<filter>
3<filter-name>encodeFilter</filter-name>
4<filter-class>CharacterEncodingFilter全路径</filter-class>
5<init-param>
6<param-name>encode</param-name>
7<param-value>utf-8</param-value>
8</init-param>
9</filter>
10<!-- 字符编码过滤器映射,/*过滤所有请求 -->
11<filter-mapping>
12<filter-name>encodeFilter</filter-name>
13<url-pattern>/*</url-pattern>
14</filter-mapping>
七、监听器(ServletContextListener)
1.ServletContext相关监听接口
(1)javax.servlet.ServletContextListener:监听WEB应用,当应用开始的时候它会调用contextInitialized()方法,当应用关闭的时候,它同样会调用contextDestroyed()方法
(2)javax.servlet.ServletContextAttributeListener:用于监听WEB应用属性改变的事件,包括:增加属性、删除属性、修改属性
2.HttpSession相关监听接口
(1)javax.servlet.http.HttpSessionListener:监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。
(2)avax.servlet.http.HttpSessionBindingListener:
注意:HttpSessionBindingListener接口是唯一不需要再web.xml中设定的Listener
当我们的类实现了HttpSessionBindingListener接口后,只要对象加入Session范围(即调用HttpSession对象的setAttribute方法的时候)或从Session范围中移出(即调用HttpSession对象的removeAttribute方法的时候或Session Time out的时候)时,容器分别会自动调用下列两个方法:
void valueBound(HttpSessionBindingEvent event)
void valueUnbound(HttpSessionBindingEvent event)
(3)avax.servlet.http.HttpSessionAttributeListener:监听HttpSession中的属性的操作。
当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。
3.写一个统计在线用户的例子
(1)建立CunterListstener.java类
1import javax.servlet.http.HttpSessionEvent;
2import javax.servlet.http.HttpSessionListener;
3
4public class CunterListstener implements HttpSessionListener
5{
6 public static int count;
7
8 public void sessionCreated(HttpSessionEvent arg0)
9 {
10 count++;
11 }
12
13 public void sessionDestroyed(HttpSessionEvent arg0)
14 {
15 if(count>0) count--;
16 }
17}
(2)建立index.jsp,查看在线人数
1<%@ page language="java" pageEncoding="UTF-8"%>
2<html>
3 <head>
4 <title>站点计数监听器</title>
5 </head>
6
7 <body>
8 <h1>站点计数监听器</h1>
9 <hr>
10 当前在线人数:<%=CunterListener.count%>
11 </body>
12</html>
3.在web.xml文件中配置监听器
1<!-- 配置监听器 -->
2<listener>
3 <listener-class>CunterListstener全路径</listener-class>
4</listener>
4.发布工程到Tomcat上,进入index.jsp网页 ,看到网页内容: 当前在线人数:1。代表的是只有自己在线。
九、Cookie
Cookie 用于存储 Web 服务器发送给客户端的信息。服务器通过设置响应标题中的 Set-Cookie 方法来发送 cookie。
javax.servlet.http.Cookie类方法:
getComment/setComment 获取/设置Cookie的注释。
getDomain/setDomain 获取/设置Cookie适用的域。
getMaxAge/setMaxAge 获取/设置Cookie过期之前的时间,以秒计。
getName/setName 获取/设置Cookie的名字。
getPath/setPath 获取/设置Cookie适用的路径。
getSecure/setSecure 获取/设置一个boolean值,表示是否Cookie只能通过加密的连接(即SSL)发送。
getValue/setValue 获取/设置Cookie的值。
getPath()返回的如果不指定路径,Cookie将返回给当前页面所在目录及其子目录下的所有页面。这里的方法可以用来设定一些更一般的条件。例如,someCookie.setPath("/"),此时服务器上的所有页面都可以接收到该Cookie。
如果不设置Cookie的过期时间,则Cookie只在当前会话内有效,即在用户关闭浏览器之前有效,而且这些Cookie不会保存到磁盘上。
通过HttpServletResponse的addCookie方法加入。
1Cookie userCookie = new Cookie("userName", "hackiller");
2response.addCookie(userCookie);
由于HttpServletRequest的getCookies方法返回的是一个Cookie对象的数组,因此通常要用循环来访问这个数组查找特定名字,然后用getValue检查它的值。
1//获取指定名字的Cookie值
2public static String getCookieValue(Cookie[] cookies,String cookieName,String defaultValue)
3{
4 for(int i=0; i<cookies.length; i++)
5 {
6 Cookie cookie = cookies[i];
7 if (cookieName.equals(cookie.getName())) return(cookie.getValue());
8 }
9 return(defaultValue);
10}
自动保存的Cookie,Cookie能够在浏览器退出的时候自动保存下来
1import javax.servlet.http.Cookie;
2
3public class MyCookie extends Cookie
4{
5 public static final int COOKIE_MAX_AGE = 60*60*24*7;//一周
6 public MyCookie(String cookieName, String cookieValue)
7 {
8 super(cookieName, cookieValue);
9 //设置Cookie的过期时间为一周
10 setMaxAge(COOKIE_MAX_AGE);
11 }
12}
十、Servlet 通信方法
(1)Servlet 使用 RequestDispatcher 接口的 forward() 和include() 方法访问网络资源
将请求从一个 Servlet 转送到同一个服务器上的另一个 Servlet
public void forward (ServletRequest req, ServletResponse res);
在一个 Servlet 中包含另一个 Servlet 的内容
public void include (ServletRequest req, ServletResponse res);
使用javax.servlet.http.HttpServlet.getServletContext()方法创建RequestDispatcher对象,用于访问另一个 Servlet 的内容
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher("/usersServlet2");
(2)Servlet 上下文
将所有 Servlet 所共有的属性和资源存储于 ServletContext 接口对象。处理上下文属性的方法为:
public Object getAttribute(String name);
返回 Servlet 容器属性名称。如果该名称没有属性则返回 null
public void setAttribute(String name, Object object);
将对象绑定到 Servlet 上下文中给定的属性名称
public void removeAttribute(String name);
删除给定名称的属性