• 会话管理


    一、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

  • 相关阅读:
    JavaScript 教程
    C#基础实例
    Angularjs实例5
    Angularjs实例4
    Angularjs 数据过滤
    Angularjs实例3
    Angularjs 数据循环
    Angularjs模块
    Angularjs 数据双向绑定
    Angularjs实例应用
  • 原文地址:https://www.cnblogs.com/chenchong/p/2738615.html
Copyright © 2020-2023  润新知