1.會話:
2.保存會話的數據:
之前學的兩個域對象ServletContext和request都不能實現的原因:
1.ServletContext會發生數據覆蓋的問題
2.如果用request轉發去傳遞數據,可以實現,但是隻運行用戶發生一個請求,來完成數據的保存。會導致用戶體驗差。而如果用戶用兩個request,則又無法實現轉發功能。
所以接下來就是保存會話數據的兩種技術:Cookie,Session(域對象)
Cookie技術:
Session技術:
3.Cookie:
案例1:顯示用戶上次訪問時間:
public class CookieDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("<a href='/day06/servlet/DeleteCookie'>清楚上次訪問時間</a><br/>");
out.print("您上次訪問的時間是:");
//獲得用戶的時間cookie
Cookie[] cookies = request.getCookies();
for(int i=0; cookies!=null && i<cookies.length;i++){
if(cookies[i].getName().equals("lastAccessTime")){
long cookieValue = Long .parseLong(cookies[i].getValue()); //得到用戶的上次訪問時間
Date date = new Date(cookieValue);
out.print(date.toLocaleString());
}
}
//給用戶回送最新的訪問時間
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
cookie.setMaxAge(1+30*24*3600); //保存一個月
cookie.setPath("/day06"); //設置cookie的有效域
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
DeleteCookie.java:
public class DeleteCookie extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
cookie.setMaxAge(0);
cookie.setPath("/day06");
response.addCookie(cookie);
response.sendRedirect("/day06/servlet/CookieDemo1");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
cookie細節:
案例2:顯示商品瀏覽歷史紀錄
//代表首頁的servlet
public class CookieDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//1.輸出網站的所有商品
out.write("本網站有如下商品:<br/>");
Map<String, Book> map = Db.getAll();
for(Map.Entry<String, Book> entry:map.entrySet()){
Book book = entry.getValue();
out.write("<a href='/day06/servlet/CookieDemo1_1?id="+book.getId()+"' target='_blank'>"+book.getName()+"</a><br/>");
}
//2.顯示用戶看過的商品
out.print("<br/>您曾經看過如下商品:<br/>");
Cookie[] cookies = request.getCookies();
for(int i = 0;cookies!=null && i<cookies.length;i++){
if(cookies[i].getName().equals("bookHistory")){
String[] ids = cookies[i].getValue().split("\\."); //不能用逗號分隔,因爲高版本的tomcat中cookie是以逗號區分開的
for(String id:ids){
Book book = (Book) Db.getAll().get(id);
out.print(book.getName()+"<br/>");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
class Db{
private static Map<String,Book> map = new LinkedHashMap();
static{
map.put("1", new Book("1", "javaweb開發", "老張", "一本好書"));
map.put("2", new Book("2", "jdbc開發", "老張", "一本好書"));
map.put("3", new Book("3", "sping開發", "老李", "一本好書"));
map.put("4", new Book("4", "struts開發", "老畢", "一本好書"));
map.put("5", new Book("5", "android", "老張", "一本好書"));
}
public static Map getAll(){
return map;
}
}
class Book{
private String id;
private String name;
private String author;
private String description;
public Book() {
super();
}
public Book(String id, String name, String author, String description) {
super();
this.id = id;
this.name = name;
this.author = author;
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
//顯示商品詳細信息的servlet
public class CookieDemo1_1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//1.根據用戶帶過來的id,顯示相應商品的詳細信息
String id = request.getParameter("id");
Book book = (Book) Db.getAll().get(id);
out.write(book.getId()+"<br/>");
out.write(book.getAuthor()+"<br/>");
out.write(book.getName()+"<br/>");
out.write(book.getDescription()+"<br/>");
//2.構建cookie,回寫給瀏覽器
String cookieValue = buildCookie(id, request);
Cookie cookie = new Cookie("bookHistory",cookieValue);
cookie.setMaxAge(1*30*24*60*60);
cookie.setPath("/day06");
response.addCookie(cookie);
}
private String buildCookie(String id, HttpServletRequest request) {
//bookHistory = null 1 1
//bookHistory = 2,5,1 1 1,2,5
//bookHistory = 2,5,4 1 1,2,5(假設cookie最大值爲3)
//bookHistory = 2,5 1 1,2,5
String bookHistory = null;
Cookie[] cookies = request.getCookies();
for(int i=0; cookies!=null && i<cookies.length;i++){
if(cookies[i].getName().equals("bookHistory")){
bookHistory = cookies[i].getValue();
}
}
if(bookHistory==null){
return id;
}
LinkedList<String> list = new LinkedList<String>(Arrays.asList(bookHistory.split("\\.")));
/* if(list.contains(id)){
list.remove(id);
list.addFirst(id);
}else{
if(list.size()>=3){
list.removeLast();
list.addFirst(id);
}else{
list.addFirst(id);
}
}*/
if(list.contains(id)){
list.remove(id);
}else if(list.size()>=3){
list.removeLast();
}
list.addFirst(id);
StringBuilder sb = new StringBuilder();
for(String bid:list){
sb.append(bid+".");
}
return sb.deleteCharAt(sb.length()-1).toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
cookie其他應用:購物,自動登陸(回寫的時候密碼用MD5碼+隨機數)
4.session:基於cookie(服務器回寫的cookie是沒有有效期的,最好自己覆蓋)
session的生命週期:創建session的代碼,seesion沒有被調用30分鐘後自己關閉。關閉時間服務器配置可修改。也代碼關閉。session.invalidate()。
cookie被瀏覽器禁了的情況:(localhost不會被禁止)
服務器先查看有沒有cookie,沒有就重寫URL。
解決方案:在超鏈接後面帶session的id號。
String url = reponse.encodeURL("/"); 會自己加id
新問題:關閉了瀏覽器,之前的session的id號就沒有了。
無法解決。
案例1:session實現簡單的購物(相對cookie對服務器壓力較大)
購物首頁
購買
顯示
3個案例:
案例2:用戶登陸
登陸界面
產生登陸標記
登陸成功界面
用戶註銷
案例3:客戶端,服務端 防表單重複提交
客戶端:
javascript解決方案:只用這的話 不安全(比如刷新,又提交等等)
服務端:繼續防,防止表單重複提交,在創建表單前給每個表單帶上一個隨機數
產生表單:
產生隨機數:
表單頁面:
數據處理:
表單重複判斷:
md5的作用:應用很廣泛
保證用戶密碼的安全性。(先和加隨機數,再MD5,防止暴力破解)
校驗數據的完整性。
校驗光盤的完整性。
BASE64:數據傳遞的時候用的很多
案例4:校驗圖片認證碼
5.三個域對象(容器):servletcontext, request, session
使用情形:
request:數據顯示完了沒用了(一個請求上用一次)
session:除了顯示,等一會還要用(一個請求上用多次)
servletcontext:除了顯示,等一會還要用,還要給別人用(多個請求都用)聊天室
綜合案例:過濾器的時候再做