CookieAPI的使用
- 下面代码展示通过设置cookie存活时间来保存用户名
package servlet;
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;
import java.io.PrintWriter;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String userName ="";
String checked = "";
Cookie[] cookies = request.getCookies();
for (int i = 0;cookies!=null && i < cookies.length; i++) {
if("userName".equals(cookies[i].getName())){
userName = cookies[i].getValue();
checked = "checked='checked'";
}
}
out.write("<form action='"+request.getContextPath()+"/doLogin' method='post'>");
out.write("用户名:<input type='text' name='userName' value='"+userName+"'/><br/>");
out.write("密码:<input type='password' name='pwd'/><br/>");
out.write("<input type='checkbox' name='remember' "+checked+" />记住用户名<br/>");
out.write("<input type='submit' value='登录'/><br/>");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 上面Servlet实现了登录界面,下面Servlet用来实现获取表单数据、处理业务逻辑、分发转向的功能
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DoLoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
String remember = request.getParameter("remember");
Cookie ck = new Cookie("userName", userName);
ck.setPath("/");
if("tom".equals(userName)&&"123".equals(pwd)){
if(remember!=null){
ck.setMaxAge(Integer.MAX_VALUE);
}else{
ck.setMaxAge(0);
}
response.addCookie(ck);
out.write("登录成功!");
}else{
out.write("登录失败!");
response.setHeader("refresh", "2;url="+request.getContextPath()+"/login");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 下面代码利用cookie实现保存用户最近三条浏览记录的功能。
- 需要用到的类包括两个Servlet、一个商品(书)类和一个工具类(用来模拟对数据库的读取操作)。
- 两个Servlet分别用来展示所有书和每个书的详细信息。其中用来展示所有书的页面包括了最近浏览的三条记录。
- 经过分析发现添加cookie的功能应该在详细信息的Servlet中写,因为只有点了某本书,才会将这本书添加到cookie中。而读取cookie的功能则应该写在展示所有书信息的Servlet中。
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
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 entity.Book;
import util.DBUtil;
public class ShowAllBooksServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("本网站有以下好书:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
out.write("<a href='"+request.getContextPath()+"/showBookDetail?id="+book.getKey()+"' target='_blank'>"+book.getValue().getName()+"</a><br/>");
}
out.write("<hr/>您最近浏览过的书有:<br/>");
Cookie[] cookies = request.getCookies();
for (int i = 0;cookies!=null && i < cookies.length; i++) {
if("historyBookId".equals(cookies[i].getName())){
String value = cookies[i].getValue();
String[] ids = value.split("-");
for (int j = 0; j < ids.length; j++) {
Book book = DBUtil.findBookById(ids[j]);
out.print(book.getName()+"<br/>");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 上面是用来展示全部商品信息的Servlet,下面是用来展示商品详细信息的Servlet
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.naming.LinkLoopException;
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 entity.Book;
import util.DBUtil;
public class ShowBookDetail extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String id = request.getParameter("id");
Book book = DBUtil.findBookById(id);
out.print(book);
String historyBookId = organizeId(id,request);
Cookie ck = new Cookie("historyBookId",historyBookId);
ck.setPath("/");
ck.setMaxAge(Integer.MAX_VALUE);
response.addCookie(ck);
}
private String organizeId(String id, HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if(cookies==null){
return id;
}
Cookie historyBook = null;
for (int i = 0; i < cookies.length; i++) {
if("historyBookId".equals(cookies[i].getName())){
historyBook = cookies[i];
}
}
if(historyBook==null){
return id;
}
String value = historyBook.getValue();
String[] values = value.split("-");
LinkedList<String> list = new LinkedList<String>(Arrays.asList(values));
if(list.size()<3){
if(list.contains(id)){
list.remove(id);
}
}else{
if(list.contains(id)){
list.remove(id);
}else{
list.removeLast();
}
}
list.addFirst(id);
StringBuffer sb = new StringBuffer();
for (int i=0; i< list.size();i++) {
if(i>0){
sb.append("-");
}
sb.append(list.get(i));
}
return sb.toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package servlet;
import java.util.HashMap;
import java.util.Map;
import entity.Book;
public class DBUtil {
private static Map<String, Book> books = new HashMap<String, Book>();
static{
books.put("1", new Book("1", "金瓶梅", 20, "王瑞鑫"));
books.put("2", new Book("2", "葵花宝典", 20, "杨成毅"));
books.put("3", new Book("3", "九阴真经", 30, "陈光"));
books.put("4", new Book("4", "玉女心经", 10, "陈志家"));
}
public static Map<String, Book> findAllBooks(){
return books;
}
public static Book findBookById(String id){
return books.get(id);
}
}
HttpSession
- HttpSession也是一个域对象,它是介于ServletContext和ServletRequest中间的域对象。ServletRequest的范围只限于同一个request,ServletContext的范围是整个项目资源都可以进行设置和获取对象。而HttpSession则是同一会话中的所有资源通向同一个HttpSession对象,可以设置和获取对象。不同的会话对应着不同的HttpSession。
- HttpSession与Cookie的区别在于:
- Cookie是客户端技术,只能存取字符串
- HttpSession是服务器端技术,可以存取对象
- 下面展示一个例子,通过HttpSession实现购物车功能,能够区别不同用户(购物车存在HttpSession当中)
- 包括三个Servlet(用于展示所有商品信息,用于添加一本选中的书到购物车中,用于展示购物车中的内容)、两个类(Book和DBUtil用来模拟数据库,跟上面一个例子相同)
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import entity.Book;
import util.DBUtil;
public class ShowAllBooksServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("本网站有以下好书:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
out.print("<a href='"+request.getContextPath()+"/addCart?id="+book.getKey()+"' >"+book.getValue().getName()+"</a><br/>");
}
out.print("<a href='"+request.getContextPath()+"/showCart"+"'>查看购物车</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 下面是添加商品的Servlet,在这个Servlet中,需要获取HttpSession,往里面存放的代表购物车的List中添加商品,然后再将List放回HttpSession中。
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import entity.Book;
import util.DBUtil;
public class AddCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String id = request.getParameter("id");
Book book = DBUtil.findBookById(id);
HttpSession session = request.getSession();
List<Book> list = (List<Book>)session.getAttribute("cart");
if(list==null){
list = new ArrayList<Book>();
}
list.add(book);
session.setAttribute("cart", list);
out.print("购买成功!");
response.setHeader("refresh", "2;url="+request.getContextPath()+"/showAllBooksServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 下面是展示购物车内容的Servlet,在这个Servlet中也需要获取到HttpSession,获取里面的List购物车。
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import entity.Book;
public class ShowCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("购物车有以下商品:<br/>");
HttpSession session = request.getSession();
List<Book> books = (List<Book>)session.getAttribute("cart");
if(books==null){
out.print("你还什么都没买呢");
response.setHeader("refresh", "2;url="+request.getContextPath()+"/showAllBooksServlet");
return;
}
for (Book book : books) {
out.write(book.getName()+"<br/>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- getSession():内部执行原理
- 获取名称为JSESSIONID的cookie的值。
- 没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写了一个名字为JSESSIONID=sessionID的cookie
- 有这样的Cookie,获取cookie的值(即HttpSession对象的值),从服务器的内存中根据ID找那个HttpSession对象。如果找不到(由于过期等原因),重新创建一个新的HttpSession对象。