会话管理

一、RequestDispatcher接口

1、请求转发和请求重定向的区别

clip_image001

ServletRequest:是一个域对象。内部维护了一个Map<String,Object>

Object getAttribute(String name):

void setAttribute(String name,Object obj):

void removeAttribute(String name):

重定向:客户端行为

HttpServletResponse.setState(302);

HttpServletResponse.setHeader("Location",String url);

或者

HttpServletResponse.sendRedirect(String url);等同以上2句代码

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 重定向演示
public class ServletDemo1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setAttribute("demo", "text");
		// 返回特征码,进行重定向
		// response.setStatus(302);
		// response.setHeader("Location", "/review_day06/servlet/ServletDemo2");
		response.sendRedirect("/review_day06/servlet/ServletDemo2");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletDemo2 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String value = (String) request.getAttribute("demo");
		if (value != null)
			response.getOutputStream().write(value.getBytes());
		else
			response.getOutputStream().write("value is null.<br/>".getBytes());
		response.getOutputStream().write("This is Demo2".getBytes());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

结果:

value is null.
This is Demo2

客户端发送了两次请求,且两次请求并不是同一个,故:

源组件和目标组件中的request并不是同一个,所以不能实现数据的共享。

 

转发:服务器行为

方式一:

RequestDispatcher rd = ServletContext.getRequestDispatcher(String path):必须以"/"开头。path只能使用绝对路径

方式二:

RequestDispatcher rd = request.getRequestDispatcher(String path):如果以"/"开头,表示使用绝对路径;不以"/"开头,表示相对路径。

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//转发演示
public class ServletDemo3 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setAttribute("demo", "text");
		//RequestDispatcher rd = request.getRequestDispatcher("/servlet/ServletDemo4");
		//此处使用"/review_day06/servlet/ServletDemo4"报错;使用ServletDemo4不报错;/servlet/ServletDemo4不报错
		RequestDispatcher rd = getServletContext().getRequestDispatcher("/servlet/ServletDemo4");
		//此处使用"/review_day06/servlet/ServletDemo4"报错;使用ServletDemo4也报错
		rd.forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

 

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletDemo4 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String value = (String) request.getAttribute("demo");
		response.getOutputStream().write((value+"<br/>").getBytes());
		response.getOutputStream().write("This is demo4".getBytes());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

结果:

text
This is demo4

转发时,客户端只发送了一次请求,源组件和目标组件中的request是同一个,可以实现数据共享。

 

**扩展知识点:各种URL地址的写法。

相对路径:实际开发中不建议使用。

绝对路径:建议使用方式。

绝对路径的写法:

如果是给服务器用的地址:"/"代表当前应用 /day06

如果是给客户端用的地址:"/"并不代表当前应用,只是区分相对路径用的。需要加上/day06

sendRedirect(String url): url要加 /day06

href: 要加 /day06

form-->action:要加 /day06

请求转发:不要加 /day06

2、包含

源组件包含目标组件:共享请求和响应对象的数据。

目标组件的输出都会出现在源组件中。

目标组件设置的所有响应码头无效。

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//include演示
//源组件
public class ServletDemo5 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write("这是demo5<br/>");
		
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/ServletDemo6");
		rd.include(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//目标组件
public class ServletDemo6 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write("这是demo6");		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

结果:

这是demo5
这是demo6

 

二、会话技术概述
1、什么是会话?如同打电话
2、会话过程中主要解决的问题是保存用户的数据
3、开发技术:
    a、cookie技术:客户端技术
        响应消息:Set-Cookie:
        请求消息:Cookie:
    b、session技术:服务器端技术

三、Cookie概述:API
1、Cookie是Servlet向客户端写的小数据信息。这些信息被浏览器保存在自己的缓存目录中。再次请求服务器资源时能带过去。
2、Cookie的属性:
    name:必须要的属性。
    value:必须要的属性。
    ------------------------------------------------
    以下属性可选:
    comment:
    path:生成cookie的资源路径。区分重名cookie的。
            http://localhost:8080/day06/servlet/ServletDemo1
            path:/day06/servlet
           
            带Cookie问题:
            localost/day06/servlet : lastAccessTime Cookie
            访问路径:http://www.baidu.com/index.jsp  不会带,域名不同
            访问路径:http://localhost:8080/day06  会带
            访问路径:http://localhost:8080/day06/servlet/a/b/ServletDemo2  不会
           
            如果把cookie的path设置为了当前应用:“/day06”,意味着访问day06下面的任何资源,浏览器都会带cookie过来。
           
           
    domain:域。默认是生成Cookie的域名。
    maximum age:设置Cookie的最大存活时间。默认值最大存活时间是浏览器进程(会话范围)。如果值0,代表要删除该cookie,注意domain/path
    version:
   
每个浏览器客户端最多能放300个cookie。对每一个网站做多能放20个cookie;每一个cookie的大小不能超过4KB。
域名+路径+name(domain+path+name):唯一确定一个Cookie
3、如何向客户端写Cookie:HttpServletResponse.addCookie(Cookie c)(原理:response.setHeader("Set-Cookie","name=value");
   
4、服务器如何获取客户端带来的Cookie。HttpServletRequest.getCookies()(原理:request.getHeader("Cookie"));
四、Cookie案例:
    1、记录最后一次的访问时间:帮助大家理解Cookie原理的。

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * 显示用户上次的访问时间
 * name = value-->lastAccessTime = ;
 * 
 * 思路:
 * 1.需要获取cookie,从cookie中取出最后的访问时间返回给客户端;
 * 2.将新的访问时间写回给cookie
 *
 */
public class CookieDemo1 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("上次访问的时间是:");
		
		//从cookie中取出最后的访问时间返回给客户端;
		
		//1.获取所有的Cookie
		Cookie[] cookies = request.getCookies();
		
		//2.从中取出值为lastAccessTime的Cookie
		for(int i=0;cookies!=null&&i<cookies.length;i++){
			if("lastAccessTime".equals(cookies[i].getName())){
				long time = Long.parseLong(cookies[i].getValue());//得到上次访问的时间
				Date d = new Date(time);
				DateFormat df = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
				//将获得的时间响应给浏览器
				out.write(df.format(d));
			}
		}
		
		//3.将本次访问的时间写回给cookie
		Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
		cookie.setMaxAge(24*60*60);//cookie保存时间
		cookie.setPath(request.getContextPath());//request.getContextPath()等同于/review_day06
		response.addCookie(cookie);
		
		//4.删除cookie
		out.write("<a href='"+request.getContextPath()+"/servlet/CookieDemo2'>清除</a>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
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;

//清除cookie
public class CookieDemo2 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Cookie cookie = new Cookie("lastAccessTime", "");
		cookie.setPath(request.getContextPath());
		cookie.setMaxAge(0);
		response.addCookie(cookie);

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

结果:

image


    2、记住登陆用户名

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;

//功能:1.提供登录的UI界面;2.显示已保存的用户名
public class LoginUIServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String username="";
		String checked = "";
		//显示已保存的用户名
		Cookie cookies[] = request.getCookies();
		for(int i=0;cookies!=null&&i<cookies.length;i++){
			if("userInfo".equals(cookies[i].getName())){
				username = cookies[i].getValue();
				checked="checked='checked'";
				break;
			}
		}
		//提供登陆的界面
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.write("<form action='"+request.getContextPath()+"/servlet/LoginServlet' method='post'>");
		out.write("用户名:<input type='text' name='username' value='"+username+"'/><br/>");
		out.write("密码:<input type='password' name='password'/><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);
	}

}
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 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 = request.getParameter("username");
		String password = request.getParameter("password");
		String remember = request.getParameter("remember");
		
		//验证用户、密码暂略
		out.write("欢迎您:"+username);
		//
		if(remember==null){
			//当不选中 记住用户名 时,删除cookie
			Cookie cookie = new Cookie("userInfo", "");
			cookie.setPath(request.getContextPath());
			cookie.setMaxAge(0);
			response.addCookie(cookie);
		}else{
			//当选中 记住用户名 时,则保存cookie
			Cookie cookie = new Cookie("userInfo", username);
			cookie.setPath(request.getContextPath());
			cookie.setMaxAge(Integer.MAX_VALUE);
			response.addCookie(cookie);
		}
		

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

结果:

image


    3、购物网站:记住最近的浏览产品记录

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;

// 功能:1.列出所有的商品列表;2.列出用户近期的浏览记录;3.提供购买链接
// cookis以bookHistory命名
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("<a>本站有以下商品:</a><hr/>");
		Map<String, Book> books = BookDB.findAllBooks();
		for (Map.Entry<String, Book> me : books.entrySet()) {
			out.write(me.getValue().getName()
					+ "&nbsp&nbsp;<a target='_blank' href='"
					+ request.getContextPath()
					+ "/servlet/ShowDetailsServlet?id=" + me.getKey()
					+ "'>查看</a><hr/>");

		}

		out.write("最近查看的商品如下<hr/>");
		Cookie[] cookies = request.getCookies();
		for (int i = 0; cookies != null && i < cookies.length; i++) {
			if ("bookHistory".equals(cookies[i].getName())) {
				String value = cookies[i].getValue();
				String ids[] = value.split("\\-");
				for (String id : ids) {
					Book book = BookDB.findBookById(id);
					out.write(book.getName() + "<br/>");
				}
				break;
			}
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

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.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener;

// 1.显示书籍的详细内容;2.写cookie
public class ShowDetailsServlet 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/>");
		String id = request.getParameter("id");
		Book book = BookDB.findBookById(id);
		out.write(book.toString());

		// 写cookie
		String ids = makeIds(request, id);
		Cookie cookie = new Cookie("bookHistory", ids);
		cookie.setPath(request.getContextPath());
		cookie.setMaxAge(Integer.MAX_VALUE);
		response.addCookie(cookie);

	}

	/*
	 * 1.没有cookie
	 * 2.有cookie,但是没有名为bookHistory的cookie
	 * 3.有名为bookHistory的cookie
	 * 原 新 组织后
	 * 1 2 2-1
	 * 1-2 2 2-1
	 * 1-2 3 3-1-2
	 * 
	 * 1-2-3 4 4-1-2
	 * 1-2-3 2 2-1-3
	 */
	private String makeIds(HttpServletRequest request, String id) {
		Cookie[] cookies = request.getCookies();
		// 没有cookie
		if (cookies == null) {
			return id;
		}

		boolean hasBookHistory = false;
		String value = "";
		for (Cookie cookie : cookies) {
			if ("bookHistory".equals(cookie.getName())) {// 这里必须使用cookie.getName(),而不是cookie
				hasBookHistory = true;
				value = cookie.getValue();
			}
		}

		if (!hasBookHistory) {
			return id;
		}

		String[] vs = value.split("\\-");
		LinkedList<String> list = new LinkedList<String>(Arrays.asList(vs));//需要将vs传入
		if (list.size() < 3) {
			if (list.contains(id)) {
				list.remove(id);
				list.addFirst(id);
			} else {
				list.addFirst(id);
			}
		} else {
			if (list.contains(id)) {
				list.remove(id);
				list.addFirst(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));// 不是sb.append(id);
		}
		return sb.toString();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.util.HashMap;
import java.util.Map;

public class BookDB {
	private static Map<String,Book> books = new HashMap<String,Book> ();
	static{
		books.put("1", new Book("1", "葵花宝典", "HMM", 5.00f, "欲练此功,必须练好基本功"));
		books.put("2", new Book("2", "辟邪剑法", "WDD", 4.00f, "欲练此功,必须练好基本功"));
		books.put("3", new Book("3", "JPM", "DJR", 15.00f, "古代爱情小说"));
		books.put("4", new Book("4", "Java面向对象编程", "WZT", 85.00f, "Java入门经典书籍"));
		books.put("5", new Book("5", "红高粱", "CYY", 7500000.00f, "买套房"));
	}
	
	public static Map<String, Book> findAllBooks(){
		return books;
	}
	
	public static Book findBookById(String id){
		return books.get(id);
	}
}

 

public class Book {
	private String id;
	private String name;
	private String author;
	private float price;
	private String description;
	
	
	public Book() {}
	public Book(String id, String name, String author, float price,
			String description) {
		super();
		this.id = id;
		this.name = name;
		this.author = author;
		this.price = price;
		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 float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ", name=" + name + ", author=" + author
				+ ", price=" + price + ", description=" + description + "]";
	}
	
	
	
}

效果:

image


五、HttpSession概述
每个客户端都有自己对应的HttpSession对象,该对象存放在服务器的内存中。
得到HttpSession对象:
HttpServletRequest.getSession():
先根据你传递的JSESSIONID的值,在内存找id为此值的session对象。名称为JSESSIONID的Cookie如果不存在,或者找不到对应session对象,会新建一个HttpSession对象。
HttpServletReqeust.getSession(boolean b):
如果为true:效果等同没有参数的getSession()
如果为false:只会查找。

HttpSession.getId()

HttpSession实际上借助了Cookie技术,知不是过是写了一个特殊名称的cookie而已。
此Cookie的path是当前应用,age是会话范围。name是JSESSIONID,value是session对象的id。


六、HttpSession的原理

image
七、HttpSession案例:
    1、简单购物车

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;

// 1.显示所有的商品;2.提供购买链接;
public class ShowProductsServlet 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 = BookDB.findAllBooks();
		for (Map.Entry<String, Book> me : books.entrySet()) {
			out.write(me.getValue().getName() + "<a href='"
					+ request.getContextPath() + "/servlet/BuyServlet?id="
					+ me.getKey() + "'>购买</a><hr/>");// 别忘了传入me.getKey(),否则找不到商品
		}
		out.write("<a href='" + request.getContextPath()
				+ "/servlet/ShowCartServlet'>查看购物车</a><br/>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
// 提供购买功能
public class BuyServlet 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");// 获取到要购买商品的id

		Book book = BookDB.findBookById(id);// 找到要买的商品
		// 获得session,如果没有,则创建
		HttpSession session = request.getSession();
		Object obj = session.getAttribute("cart");// 获取购物车

		// 如果没有购物车,则创建一个容器来盛放要买的商品,并将数据传给购物车
		if (obj == null) {
			List<Book> cart = new ArrayList<Book>();
			cart.add(book);
			session.setAttribute("cart", cart);
		} else {
			List<Book> cart = (List<Book>) obj;
			cart.add(book);// 这里不是setAttribute,因为已有Attribute,所以只需添加元素
		}
		out.write("商品已成功放入购物车!<a href='" + request.getContextPath()
				+ "/servlet/ShowProductsServlet'>继续购物</a><br/>");

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

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;

// 1.显示已加入购物车的商品
public class ShowCartServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		HttpSession session = request.getSession(false);// 只查看,不创建
		if (session == null) {
			out.write("还没有购买任何物品!");
			return;
		}
		List<Book> cart = (List<Book>) session.getAttribute("cart");
		if (cart == null) {
			out.write("还没有购买任何物品!");
			return;
		}
		System.out.println(cart);
		out.write("您已经购买了如下商品:<hr/>");
		for (Book book : cart) {
			out.write(book.getName() + "<br/>");
		}
		out.write("<a href='#'>去结算</a>&nbsp;&nbsp;<a href='"
				+ request.getContextPath()
				+ "/servlet/ShowProductsServlet'>继续购物</a>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

效果图:

imageimage

 

    2、实现用户一次登陆和验证码验证

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/*
 * 需要一个主页(IndexServlet)
 * 1.如果已登录,则显示欢迎信息和注销链接
 * 需要获取session,从session中获取username,显示在欢迎信息中;
 * 2.如果未登录,则显示登录链接
 */
public class IndexServlet 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("这是主页<hr/>");
		// 获取session
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		String username = null;
		if (user != null) {
			username = user.getUsername();
		}

		if (username != null) {
			out.write("欢迎您," + username + "<br/>");
			out.write("<a href='" + request.getContextPath()
					+ "/servlet/LogoutServlet'>注销</a>");
		} else {
			out.write("欢迎光临本站,如果想要浏览更多信息<br/>请<a href='"
					+ request.getContextPath()
					+ "/servlet/LoginUIServlet'>登录</a><br/>");
		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/*
 * 需要一个主页(IndexServlet)
 * 1.如果已登录,则显示欢迎信息和注销链接
 * 需要获取session,从session中获取username,显示在欢迎信息中;
 * 2.如果未登录,则显示登录链接
 */
public class IndexServlet 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("这是主页<hr/>");
		// 获取session
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		String username = null;
		if (user != null) {
			username = user.getUsername();
		}

		if (username != null) {
			out.write("欢迎您," + username + "<br/>");
			out.write("<a href='" + request.getContextPath()
					+ "/servlet/LogoutServlet'>注销</a>");
		} else {
			out.write("欢迎光临本站,如果想要浏览更多信息<br/>请<a href='"
					+ request.getContextPath()
					+ "/servlet/LoginUIServlet'>登录</a><br/>");
		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
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;
import javax.servlet.http.HttpSession;

/*
 * 需要一个登录后台处理Servlet(LoginServlet)
 * 1.获取session,获取username、password、code的值,如果三者都匹配,则登录成功,跳转到主页;
 * 2.如果有一项不匹配,则输出错误信息;
 * 3.检测checkbox,如果checked=checked,则写cookie,否则,删除cookie
 */
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 = request.getParameter("username");
		String password = request.getParameter("password");
		String code = request.getParameter("code");

		String remember = request.getParameter("remember");

		HttpSession session = request.getSession();
		String value = (String) session.getAttribute("code");
		// 判断验证码
		if (!code.equals(value)) {
			out.write("验证码输入错误!<br/>");
			out.write("<a href='" + request.getContextPath()
					+ "/servlet/LoginUIServlet'>重新登录</a>");
			return;
		}

		// 根据username、password查找数据库中的用户
		User user = UserDB.findUser(username, password);
		if (user == null) {
			out.write("用户名或密码输入错误!<br/>");
			out.write("<a href='" + request.getContextPath()
					+ "/servlet/LoginUIServlet'>重新登录</a>");
			return;
		} else {
			Cookie cookie = new Cookie("userInfo", username);
			if (remember == null) {
				cookie.setPath(request.getContextPath());
				cookie.setMaxAge(0);
				response.addCookie(cookie);
			}else{
				cookie.setPath(request.getContextPath());
				cookie.setMaxAge(Integer.MAX_VALUE);
				response.addCookie(cookie);
			}

			session = request.getSession();
			session.setAttribute("user", user);

			out.write("登录成功!2秒后返回主页,如果长时间没有反应,请点击<a href='"
					+ request.getContextPath()
					+ "/servlet/IndexServlet'>这里</a>");
			response.setHeader("Refresh", "2;URL=" + request.getContextPath()
					+ "/servlet/IndexServlet");
		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

// 提供随机验证码
public class ImageServlet extends HttpServlet {

	private static int WIDTH = 120;
	private static int HEIGHT = 25;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//验证码图片不缓存
		response.setHeader("Expires", "-1");
		response.setHeader("Cache-Control", "no-cache");
		response.setHeader("Pragma", "no-cache");
		
		// 获取画布
		BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
				BufferedImage.TYPE_INT_RGB);
		// 获取画笔
		Graphics g = image.getGraphics();

		// 画边框
		g.setColor(Color.GRAY);
		g.drawRect(0, 0, WIDTH, HEIGHT);

		// 填充背景色
		g.setColor(Color.YELLOW);
		g.fillRect(1, 1, WIDTH - 2, HEIGHT - 2);

		// 画干扰线
		g.setColor(Color.RED);
		Random r = new Random();
		for (int i = 0; i < 9; i++) {
			g.drawLine(r.nextInt(WIDTH), r.nextInt(HEIGHT), r.nextInt(WIDTH),
					r.nextInt(HEIGHT));
		}

		// 画数字
		g.setColor(Color.BLUE);
		g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 20));
		int x = 20;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < 4; i++) {
			String num = r.nextInt(10) + "";
			sb.append(num);
			g.drawString(num, x, 20);
			x += 20;
		}
		
		//获取session,存储code
		HttpSession session = request.getSession();
		session.setAttribute("code", sb.toString());
		
		ImageIO.write(image, "jpeg", response.getOutputStream());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LogoutServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		//删除session中的user
		HttpSession session = request.getSession();
		session.removeAttribute("user");
		
		out.write("注销成功!<a href='"+request.getContextPath()+"/servlet/IndexServlet'>返回主页</a>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
public class User {
	private String username;
	private String password;
	public User(){}
	public User(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}
import java.util.ArrayList;
import java.util.List;

public class UserDB {
	private static List<User> users = new ArrayList<User>();
	static{
		users.add(new User("chenchong","123"));
		users.add(new User("admin","admin"));
	}
	public static User findUser(String username,String password){
		User user = null;
		for(User u:users){
			if(u.getUsername().equals(username)&&u.getPassword().equals(password)){
				user = u;
			}
		}
		
		return user;
	}
}

 

效果图:

image

image

image


    3、防止表单重复提交

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itheima.util.MD5Util;

//提供注册界面,向RegisterServlet提交数据
//在这里产生唯一的id,防止表单重复提交
public class RegisterUIServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		
//		String s = System.currentTimeMillis()+new Random().nextInt()+"";//尽量获取唯一的id
//		String token = MD5Util.encode(s);//获取token
		
		String token = UUID.randomUUID().toString();//可以获取唯一的值
		
		request.getSession().setAttribute("token", token);//将取到的位移token存放到session中
		out.write("<hr/>");
		out.write("<form action='"+request.getContextPath()+"/servlet/RegisterServlet' method='post'>");
		out.write("用户名<input type='text' name='username'/><br/>");
		out.write("密码<input type='password' name='password'/><hr/>");
		out.write("token<input type='text' name='token' value='"+token+"'>");//这里的type本应为hidden,但是为了便于观察,设为text
		out.write("<input type='submit' name='提交'/><br/>");
		out.write("</form>");

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RegisterServlet 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 = request.getParameter("username");
		String iToken = request.getParameter("token");//表单中提交过来的token
		String sToken = (String) request.getSession().getAttribute("token");//session中存储的token

		//在提交表单以后,删除session中token
		//对比两个token的值,如果相同,则表单尚未提交过;如果不同,则表单已经提交过
		if(iToken.equals(sToken)){
			try {
				Thread.sleep(2000);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			out.write("表单提交成功!<br/>");
			request.getSession().removeAttribute("token");
		}else{
			out.write("网页已过期!");
		}
		
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
import java.security.MessageDigest;

import sun.misc.BASE64Encoder;

//对一组数字进行MD5加密
public class MD5Util {
	public static String encode(String message){
		try {
			MessageDigest md = MessageDigest.getInstance("md5");
			byte[] md5 = md.digest(message.getBytes());//获取message的数据指纹,不一定是一个字符
			//new String(b);//不可行,在转换为字符串时,会查码表,可能会出现乱码
			BASE64Encoder base64 = new BASE64Encoder();
			return base64.encode(md5);//将数据转为明文
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
	}
}

效果图:

image

1.正常提交表单

image

2.重复提交

image

posted on 2012-10-25 13:12  foolchen  阅读(421)  评论(0编辑  收藏  举报

导航