1. 什么是servlet
servlet Servlet是javax.servlet.Servlet包中定義的一個(gè)接口.它聲明了servlet生命周期中不可少的三個(gè)方法init,service和destory(),每個(gè)servlet必須實(shí)現(xiàn)這三個(gè)方法,而且服務(wù)器在特定的時(shí)刻調(diào)用.
2.生命周期
容器加載 -> 初始化 init (僅一次) -> 進(jìn)入服務(wù) service (Get/Post 請(qǐng)求)-> 銷毀 destroy -> 容器卸載
執(zhí)行過程
- 客戶端發(fā)出請(qǐng)求http://localhost:8080/hello
- 根據(jù)web.xml文件的配置,找到<url-pattern>子元素的值“/hello”的<servlet-mapping>元素
讀取<servlet-mapping>元素的<servlet-name>子元素的值,由此確定Servlet的名字為”HelloServlet”
找到<servlet-name>值為HelloServlet的<servlet>元素
讀取<servlet>元素的<servlet-class>子元素的值,由此確定Servlet的類名為com.kaishengit.web.HelloServlet。
到Tomcat安裝目錄/webapps/Demo1/WEB-INF/classes/cn/itcast目錄下查找到HelloServlet.class文件
客戶端發(fā)出請(qǐng)求,容器產(chǎn)生request和response對(duì)象,容器根據(jù)url找到合適的servlet并分配線程進(jìn)行訪問,service根據(jù)請(qǐng)求頭調(diào)用doXX方法,servlet使用相應(yīng)對(duì)象通過容器對(duì)客戶端做出響應(yīng),service方法執(zhí)行結(jié)束,然后調(diào)用destory()方法,訪問線程和request、response對(duì)象被銷毀。

Servlet的執(zhí)行過程.jpg
細(xì)節(jié)
- 由于客戶端是通過URL地址訪問web服務(wù)器中的資源,所以Servlet程序若想被外界訪問,必須把servlet程序映射到一個(gè)URL地址上,這個(gè)工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
- <servlet>元素用于注冊(cè)Servlet,它包含有兩個(gè)主要的子元素:<servlet-name>和<servlet-class>,分別用于設(shè)置Servlet的注冊(cè)名稱和Servlet的完整類名。
一個(gè)<servlet-mapping>元素用于映射一個(gè)已注冊(cè)的Servlet的一個(gè)對(duì)外訪問路徑,它包含有兩個(gè)子元素:<servlet-name>和<url-pattern>,分別用于指定Servlet的注冊(cè)名稱和Servlet的對(duì)外訪問路徑。例如:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!--
配置Servlet
servlet-name 名字自定義
servlet-class Servlet類的完全限定名
-->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.kaishengit.web.HelloServlet</servlet-class>
</servlet>
<!--
servlet-name 名字自定義,但是必須和<servlet>節(jié)點(diǎn)中的<servlet-name>值相同
url-pattern 客戶端請(qǐng)求的路徑名稱,必須以/開頭
-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.kaishengit.web.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<!--
重要提示?。?!修改web.xml文件必須要重啟容器,才能生效
歡迎頁(yè)面配置,優(yōu)先級(jí)是從上倒下越來越低,如果都找不到,則顯示404錯(cuò)誤頁(yè)面
常見的HTTP狀態(tài)碼:
200 正常響應(yīng)
404 訪問的資源不存在
500 服務(wù)器異常
-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>main.jsp</welcome-file>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
</web-app>
Servlet重要的四個(gè)生命周期方法
- 構(gòu)造方法: 創(chuàng)建servlet對(duì)象的時(shí)候調(diào)用。默認(rèn)情況下,第一次訪問servlet的時(shí)候創(chuàng)建servlet對(duì)象 只調(diào)用1次。證明servlet對(duì)象在tomcat是單實(shí)例的。
- init方法: 創(chuàng)建完servlet對(duì)象的時(shí)候調(diào)用。只調(diào)用1次。
- service方法: 每次發(fā)出請(qǐng)求時(shí)調(diào)用。調(diào)用n次。
- destroy方法: 銷毀servlet對(duì)象的時(shí)候調(diào)用。停止服務(wù)器或者重新部署web應(yīng)用時(shí)銷毀servlet對(duì)象。
只調(diào)用1次。
偽代碼演示servlet的生命周期
Tomtcat內(nèi)部代碼運(yùn)行:
```
1)通過映射找到到servlet-class的內(nèi)容,字符串: gz.itcast.a_servlet.FirstServlet
2)通過反射構(gòu)造FirstServlet對(duì)象
2.1 得到字節(jié)碼對(duì)象
Class clazz = class.forName("gz.itcast.a_servlet.FirstServlet");
2.2 調(diào)用無參數(shù)的構(gòu)造方法來構(gòu)造對(duì)象
Object obj = clazz.newInstance(); ---1.servlet的構(gòu)造方法被調(diào)用
3)創(chuàng)建ServletConfig對(duì)象,通過反射調(diào)用init方法
3.1 得到方法對(duì)象
Method m = clazz.getDeclareMethod("init",ServletConfig.class);
3.2 調(diào)用方法
m.invoke(obj,config); --2.servlet的init方法被調(diào)用
4)創(chuàng)建request,response對(duì)象,通過反射調(diào)用service方法
4.1 得到方法對(duì)象
Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
4.2 調(diào)用方法
m.invoke(obj,request,response); --3.servlet的service方法被調(diào)用
5)當(dāng)tomcat服務(wù)器停止或web應(yīng)用重新部署,通過反射調(diào)用destroy方法
5.1 得到方法對(duì)象
Method m = clazz.getDeclareMethod("destroy",null);
5.2 調(diào)用方法
m.invoke(obj,null); --4.servlet的destroy方法被調(diào)用
```
(重點(diǎn)圖)用時(shí)序圖來演示servlet的生命周期

image.png
常用類
HttpServletRequest
- 是JSP的內(nèi)置對(duì)象之一,jsp中叫做request
- 用于接受客戶端請(qǐng)求,可以獲取客戶端一些數(shù)據(jù)
- getParameter(String name) 獲取URL或者form表單中的值
- setAttribute(String name,Object value)向跳轉(zhuǎn)目標(biāo)對(duì)象傳值
- getAttribute(String name) 獲取傳值
- getRequestDispatcher(String path) 獲取RequestDispatcher對(duì)象,使用RequestDispatcher進(jìn)
行請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)
HttpservletResponse
- 給客戶端做出響應(yīng)
-
sendRedirect(String urlName) ,以重定向方式,跳轉(zhuǎn)指定路徑中
image.png
重定向和請(qǐng)求轉(zhuǎn)發(fā)的區(qū)別
- 重定向跳轉(zhuǎn)是使用url重寫的方式進(jìn)行值的傳遞,值顯示在url的地址欄中
- 請(qǐng)求轉(zhuǎn)發(fā)使用HttpServletRequest對(duì)象的setAttribute方法進(jìn)行值傳遞,值不會(huì)顯示在地址
欄中 - 重定向傳值方式傳遞適合不敏感數(shù)據(jù)以及簡(jiǎn)單的字符串、數(shù)字等基本類型
- 請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)傳值方式適合傳遞敏感數(shù)據(jù)以及對(duì)象、數(shù)組、集合等類型的數(shù)據(jù)
- 重定向跳轉(zhuǎn)后瀏覽器的地址欄中顯示的是跳轉(zhuǎn)目標(biāo)的URL(地址欄會(huì)發(fā)生改變)
- 請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)后地址欄不會(huì)顯示跳轉(zhuǎn)目標(biāo)的URL(地址欄不會(huì)發(fā)生改變)
- 重定向跳轉(zhuǎn)不會(huì)引起表單的重復(fù)提交
- 請(qǐng)求轉(zhuǎn)發(fā)跳轉(zhuǎn)會(huì)引起表單的重復(fù)提交
-
重定向跳轉(zhuǎn)本質(zhì)上是服務(wù)器產(chǎn)生302響應(yīng),客戶端再次向服務(wù)器發(fā)出二次請(qǐng)求
image.png
會(huì)話技術(shù)
- Cookie 技術(shù): 會(huì)話數(shù)據(jù)保存在瀏覽器客戶端
- Session技術(shù): 會(huì)話數(shù)據(jù)保存在服務(wù)端
Cookie核心技術(shù)
Cookie類:用于存儲(chǔ)會(huì)話數(shù)據(jù)
- 構(gòu)造cookie對(duì)象
Cookie(java.lang.String name, java.lang.String value)
- 設(shè)置cookie
void setPath(java.lang.String uri) :設(shè)置cookie的有效訪問路徑
void setMaxAge(int expiry) : 設(shè)置cookie的有效時(shí)間
void setValue(java.lang.String newValue) :設(shè)置cookie的值
- 發(fā)送cookie到瀏覽器端保存
void response.addCookie(Cookie cookie) : 發(fā)送cookie
- 服務(wù)器接受cookie
Cookie[] request.getCookies() : 接收cookie
設(shè)置
package com.kaishengit.web;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SetCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("playId","1002");
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setMaxAge(60 * 60 * 24 * 7);
cookie.setHttpOnly(true); //
resp.addCookie(cookie);
Cookie cookie2 = new Cookie("productId","2908");
cookie2.setDomain("localhost");
cookie2.setPath("/");
cookie2.setMaxAge(60 * 60 * 24 * 7);
resp.addCookie(cookie2);
System.out.println("set cookie success!");
}
}
獲取Cookie
package com.kaishengit.web;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class GetCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
if(cookies != null) {
for(Cookie cookie : cookies) {
System.out.println(cookie.getName() + " -> " + cookie.getValue());
}
}
System.out.println("get cookie success!");
}
}
JQuery Cookie插件:
Cookie插件:
Cookie原理
- 服務(wù)器創(chuàng)建cookie對(duì)象,把會(huì)話數(shù)據(jù)存儲(chǔ)到cookie對(duì)象中
new Cookie("name","value");
2.服務(wù)器發(fā)送cookie信息到瀏覽器
response.addCookie(cookie);
舉例: set-cookie: name=eric (隱藏發(fā)送了一個(gè)set-cookie名稱的響應(yīng)頭)
- 瀏覽器得到服務(wù)器發(fā)送的cookie,然后保存在瀏覽器端。
- 瀏覽器在下次訪問服務(wù)器時(shí),會(huì)帶著cookie信息
舉例: cookie: name=eric (隱藏帶著一個(gè)叫cookie名稱的請(qǐng)求頭)
- 服務(wù)器接收到瀏覽器帶來的cookie信息
request.getCookies();
記住賬號(hào)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
</head>
<body>
<div class="container">
<c:if test="${not empty param.callback}">
<div class="alert alert-danger">請(qǐng)登錄再繼續(xù)</div>
</c:if>
<c:if test="${not empty message }">
<div class="alert alert-danger">${message }</div>
</c:if>
<form method="post" id="loginForm">
<div class="form-group">
<label>賬號(hào)</label>
<input type="text" name="username" id="username" class="form-control" value="${username }"/>
</div>
<div class="form-group">
<label>賬號(hào)</label>
<input type="password" name="password" class="form-control"/>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="remeberme" value="remeberme" id="remeberme" />記住賬號(hào)
</label>
</div>
<div>
<button type="button" id="loginBtn" class="btn btn-success">登錄</button>
</div>
</form>
</div>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script src="/static/js/jquery.cookie.js"></script>
<script>
$(function(){
//$("#username").val($.cookie("username"));
$("#loginBtn").click(function(){
/* if($("#remeberme")[0].checked) {
$.cookie("username",$("#username").val(),{ expires: 7, path: '/' });
} */
$("#loginForm").submit();
});
});
</script>
</body>
</html>
服務(wù)端記住賬號(hào)
package com.kaishengit.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import com.kaishengit.entity.Admin;
import com.kaishengit.exception.ServiceException;
import com.kaishengit.service.AdminService;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = "";
Cookie[] cookies = req.getCookies();
if(cookies != null) {
for(Cookie cookie : cookies) {
if(cookie.getName().equals("username")) {
username = cookie.getValue();
break;
}
}
}
req.setAttribute("username", username);
req.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String callback = req.getParameter("callback");
String remeberme = req.getParameter("remeberme");
AdminService adminService = new AdminService();
try {
Admin admin = adminService.login(username, password);
//判斷是否選中了[記住賬號(hào)]框
if(StringUtils.isNotEmpty(remeberme)) {
Cookie cookie = new Cookie("username",username);
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setMaxAge(60 * 60 * 24 * 365 * 100);
cookie.setHttpOnly(true);
resp.addCookie(cookie);
}
//獲取HttpSession
HttpSession session = req.getSession();
session.setAttribute("admin", admin);
if(StringUtils.isEmpty(callback)) {
resp.sendRedirect("/list");
} else {
resp.sendRedirect(callback);
}
} catch (ServiceException e) {
req.setAttribute("message", e.getMessage());
req.setAttribute("username", username);
req.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(req, resp);
}
}
}
Session原理
問題: 服務(wù)器能夠識(shí)別不同的瀏覽者!??!
前提: 在哪個(gè)session域?qū)ο蟊4鏀?shù)據(jù),就必須從哪個(gè)域?qū)ο笕〕觯。。。?/h6>
瀏覽器1:(給s1分配一個(gè)唯一的標(biāo)記:s001,把s001發(fā)送給瀏覽器)
1)創(chuàng)建session對(duì)象,保存會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --保存會(huì)話數(shù)據(jù) s1
瀏覽器1 的新窗口(帶著s001的標(biāo)記到服務(wù)器查詢,s001->s1,返回s1)
1)得到session對(duì)象的會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --可以取出 s1
新的瀏覽器1:(沒有帶s001,不能返回s1)
1)得到session對(duì)象的會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --不可以取出 s2
瀏覽器2:(沒有帶s001,不能返回s1)
1)得到session對(duì)象的會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --不可以取出 s3
代碼解讀:HttpSession session = request.getSession();
- 第一次訪問創(chuàng)建session對(duì)象,給session對(duì)象分配一個(gè)唯一的ID,叫JSESSIONID
new HttpSession();
- 把JSESSIONID作為Cookie的值發(fā)送給瀏覽器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);
- 第二次訪問的時(shí)候,瀏覽器帶著JSESSIONID的cookie訪問服務(wù)器
- 服務(wù)器得到JSESSIONID,在服務(wù)器的內(nèi)存中搜索是否存放對(duì)應(yīng)編號(hào)的session對(duì)象。
if(找到){
return map.get(sessionID);
}
Map<String,HttpSession>]
<"s001", s1>
<"s001,"s2>
- 如果找到對(duì)應(yīng)編號(hào)的session對(duì)象,直接返回該對(duì)象
- 如果找不到對(duì)應(yīng)編號(hào)的session對(duì)象,創(chuàng)建新的session對(duì)象,繼續(xù)走1的流程
結(jié)論:通過JSESSION的cookie值在服務(wù)器找session對(duì)象?。。。?!
總結(jié):
1)會(huì)話管理: 瀏覽器和服務(wù)器會(huì)話過程中的產(chǎn)生的會(huì)話數(shù)據(jù)的管理。
2)Cookie技術(shù):
new Cookie("name","value")
response.addCookie(coookie)
request.getCookies()
3)Session技術(shù)
request.getSession();
setAttrbute("name","會(huì)話數(shù)據(jù)");
getAttribute("會(huì)話數(shù)據(jù)")
監(jiān)聽器
web.ml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 登錄過濾器 -->
<filter>
<filter-name>ValidateFilter</filter-name>
<filter-class>com.kaishengit.web.filter.ValidateServlet</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
適配器模式:AbstractFilter
package com.kaishengit.web.filter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* @author Wgs
* @version 1.0
* @create:2018/05/26
*/
public class FilterServlet implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("FilterServlet.init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterServlet.doFilter");
}
@Override
public void destroy() {
}
}
登陸攔截器
package com.kaishengit.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.kaishengit.entity.Admin;
public class ValidateFilter extends AbstractFilter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1. 獲取用戶訪問的資源地址
String uri = request.getRequestURI();
System.out.println(uri);
if("/".equals(uri) || "/index.jsp".equals(uri) || "/login".equals(uri)
|| uri.startsWith("/static/")) {
filterChain.doFilter(request, response);
} else {
HttpSession session = request.getSession();
Admin admin = (Admin) session.getAttribute("admin");
if(admin != null) {
filterChain.doFilter(request, response);
} else {
response.sendRedirect("/login?callback="+uri);
}
}
}
}
監(jiān)聽器
web.xml
<!--監(jiān)聽器的配置-->
<listener>
<listener-class>com.kaishengit.web.listener.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>com.kaishengit.web.listener.MyHttSessionListener</listener-class>
</listener>
<context-param>
<param-name>userName</param-name>
<param-value>jack</param-value>
</context-param>
HttpSessionListener
package com.kaishengit.web.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session create...");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session destory...");
}
}
ServletContextListener
package com.kaishengit.web.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener init....");
//通過ServletContextEvent對(duì)象來獲取ServletContext對(duì)象
ServletContext servletContext = servletContextEvent.getServletContext();
String userName = servletContext.getInitParameter("userName");
System.out.println(userName);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener destroy....");
}
}
異步驗(yàn)證
image.png
瀏覽器1:(給s1分配一個(gè)唯一的標(biāo)記:s001,把s001發(fā)送給瀏覽器)
1)創(chuàng)建session對(duì)象,保存會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --保存會(huì)話數(shù)據(jù) s1
瀏覽器1 的新窗口(帶著s001的標(biāo)記到服務(wù)器查詢,s001->s1,返回s1)
1)得到session對(duì)象的會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --可以取出 s1
新的瀏覽器1:(沒有帶s001,不能返回s1)
1)得到session對(duì)象的會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --不可以取出 s2
瀏覽器2:(沒有帶s001,不能返回s1)
1)得到session對(duì)象的會(huì)話數(shù)據(jù)
HttpSession session = request.getSession(); --不可以取出 s3
new HttpSession();
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);
if(找到){
return map.get(sessionID);
}
Map<String,HttpSession>]
<"s001", s1>
<"s001,"s2>
1)會(huì)話管理: 瀏覽器和服務(wù)器會(huì)話過程中的產(chǎn)生的會(huì)話數(shù)據(jù)的管理。
2)Cookie技術(shù):
new Cookie("name","value")
response.addCookie(coookie)
request.getCookies()
3)Session技術(shù)
request.getSession();
setAttrbute("name","會(huì)話數(shù)據(jù)");
getAttribute("會(huì)話數(shù)據(jù)")
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 登錄過濾器 -->
<filter>
<filter-name>ValidateFilter</filter-name>
<filter-class>com.kaishengit.web.filter.ValidateServlet</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
package com.kaishengit.web.filter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* @author Wgs
* @version 1.0
* @create:2018/05/26
*/
public class FilterServlet implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("FilterServlet.init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterServlet.doFilter");
}
@Override
public void destroy() {
}
}
package com.kaishengit.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.kaishengit.entity.Admin;
public class ValidateFilter extends AbstractFilter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1. 獲取用戶訪問的資源地址
String uri = request.getRequestURI();
System.out.println(uri);
if("/".equals(uri) || "/index.jsp".equals(uri) || "/login".equals(uri)
|| uri.startsWith("/static/")) {
filterChain.doFilter(request, response);
} else {
HttpSession session = request.getSession();
Admin admin = (Admin) session.getAttribute("admin");
if(admin != null) {
filterChain.doFilter(request, response);
} else {
response.sendRedirect("/login?callback="+uri);
}
}
}
}
<!--監(jiān)聽器的配置-->
<listener>
<listener-class>com.kaishengit.web.listener.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>com.kaishengit.web.listener.MyHttSessionListener</listener-class>
</listener>
<context-param>
<param-name>userName</param-name>
<param-value>jack</param-value>
</context-param>
package com.kaishengit.web.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session create...");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session destory...");
}
}
package com.kaishengit.web.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener init....");
//通過ServletContextEvent對(duì)象來獲取ServletContext對(duì)象
ServletContext servletContext = servletContextEvent.getServletContext();
String userName = servletContext.getInitParameter("userName");
System.out.println(userName);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener destroy....");
}
}

image.png

