Eclipse12:Cookie&Session

目录

一:会话技术

1.1 概述

1.2 为什么学习会话

 1.3 会话技术的实现原理

  1.3.1 Cookie技术

1.3.2 Session技术

​二、Cookie的API

2.1 通过HttpServletRequest对象中的方法

 2.2 通过HttpServletResponse对象中的方法

2.3 构造方法

三、 记录用户上次访问时间的分析

 四、Cookie的分类

4.1 默认级别的Cookie

4.2 持久级别的Cookie

五、Cookie的API的概述

5.1 构造方法

5.2  获得Cookie名称

5.3 获得Cookie的值

 5.4 设置Cookie的有效域名

  5.5 设置Cookie的有效路径

   5.6 设置Cookie的有效时长

六、Cookie使用细节

七、Session

7.1 概述

7.2 Cookie与Session

7.3 Session如何保存用户数据

 7.4 Session实现原理

 7.5 Session作为域对象存取

 八、Servlet的数据访问范围的总结

8.1 请求范围(ServletRequest)

8.2 会话范围(HttpSession)

8.3 应用范围(ServletContext)

九、案例实现

9.1 需求

9.2 准备

 9.3 案例代码

9.3.1 用户登录的功能

9.3.2 代码实现

 十、一次性验证码的使用

 十一、一次性验证码点击切换图片

十二、记住用户名的实现

 十三、系统的退出


一:会话技术

1.1 概述

会话简单理解为:用户打开一个浏览器,点击多个超链接访问服务器的web资源,然后关闭浏览器,整个过程称为是一次会话。

1.2 为什么学习会话

每个用户与服务器进行交互过程中,产生一些各自的数据,程序想要把这些数据进行保存,就需要使用会话技术。

例如:用户点击超链接购买一个商品,程序应该保存用户所购买的商品,以便于用户点击结账可以得到用户所购买的商品信息。

思考:用户购买的商品保存在request或ServletContext中是否可以?

 1.3 会话技术的实现原理

  1.3.1 Cookie技术

Cookie是客户端技术,程序把每个用户的数据以cookie的形式保存到各自浏览器中。当用户使用浏览器再次访问服务器中的web资源的时候,就会带着各自的数据过去。这样,web资源处理的就是用户各自的数据了。

1.3.2 Session技术

Session是服务器端技术,利用这个技术,服务器在运行时为每一个用户的浏览器创建一个独享的session对象。由于session为用户浏览器独享,所有用户在访问服务器的时候,可以把各自的数据放在各自的session中,当用户再次访问服务器中的web资源的时候,其他web资源再从用户各自的session中取出数据为用户服务。

二、Cookie的API

2.1 通过HttpServletRequest对象中的方法

 2.2 通过HttpServletResponse对象中的方法

2.3 构造方法

三、 记录用户上次访问时间的分析

代码实现

步骤1:创建一个WEB项目

步骤2:建立包结构

步骤3:编写工具类

 步骤4:编写Servlet

 四、Cookie的分类

上述案例存在的问题:

用户访问Servlet,记录用户的上次访问时间。但是如果用户将浏览器关闭,重新打开浏览器访问程序,程序就会把其当成是第一次访问:(显示,您好,欢迎来到本网站)

4.1 默认级别的Cookie

指的是没有设置有效时间的Cookie,默认的情况下只要关闭了浏览器,Cookie也会被销毁。(Cookie存在于浏览器的内存中,当关闭了浏览器Cookie就销毁了)

4.2 持久级别的Cookie

指的是有有效时间的Cookie,这种Cookie的内容不是保存在浏览器的内存中,将Cookie的内容保存(持久化)到硬盘上。这个时候,关闭浏览器,再次打开浏览器会加载硬盘上的文件,从而Cookie中的数据就不会丢失。

五、Cookie的API的概述

5.1 构造方法

5.2  获得Cookie名称

5.3 获得Cookie的值

 5.4 设置Cookie的有效域名

  5.5 设置Cookie的有效路径

   5.6 设置Cookie的有效时长

案例问题解决: 

(1)setPath项目名:该项目下的路径访问都会产生cookies

六、Cookie使用细节

  1. 一个Cookie只用标识一种信息,至少含有一个标识该信息的名称和值。
  2. 一个web站点可以给一个浏览器发送多个Cookie。一个web浏览器可以存储多个web站点的Cookie。
  3. 浏览器一般只允许存放300个Cookie,每个站点最多可以存放20个Cookie,每个Cookie的大小限制为4KB(老版本浏览器)。-----浏览器存放的Cookie的大小和个数是有限制的。
  4. 如果创建了一个Cookie,并发送到浏览器,默认情况下它是一个会话级别的Cookie。用户退出浏览器就被删除。如果希望将这个Cookie存到磁盘上,需要设置有效时长调用setMaxAge(int maxAge)方法,以秒为单位的。

需要手动删除持久性Cookie,可以将Cookie的有效时长设置为0.必须注意:删除Cookie时候,path必须一致,否则无法删除

七、Session

7.1 概述

Session称为是一次会话,Cookie将用户产生的私有的数据保存到浏览器端,Session将用户产生的私有的数据保存到服务器端。注意:一个浏览器独占一个session对象。因此,在需要保存用户数据时候,服务器程序可以将用户数据写到session对象中,当用户使用浏览器访问其他程序时,其他程序可以从用户的session中取出该用户的数据,为用户服务。

7.2 Cookie与Session

  1. Cookie局限性:
    1. Cookie保存的数据是有个数和大小的限制的。
    2. 数据是保存客户端浏览器上(相对不是很安全)。
  2. Session
    1. Session没有个数和大小限制。

数据是保存在服务器上(相对比较安全)

7.3 Session如何保存用户数据

Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到Session对象。

 7.4 Session实现原理

基于Cookie,基于Cookie回写了一个Session的ID

 7.5 Session作为域对象存取

Session作为域对象的API

Session作为域对象,作用范围就是一次会话的范围。一次会话,指的是用户打开浏览器点击多个超链接,访问服务器资源,到最后关闭浏览器的过程

 八、Servlet的数据访问范围的总结

8.1 请求范围(ServletRequest)

  1. 何时创建和销毁的
    1. 创建:当用户向服务器发送一次请求,服务器创建一个request对象。
    2. 销毁:当服务器对这次请求作出了响应,服务器就会销毁这个request对象。
  2. 如何存取数据
    1. 存数据:
      1. void setAttribute(String name,Object value);
    2. 取数据
      1. Object getAttribute(String name);
  3. 作用范围

作用范围:一次请求。(转发就是一次请求)

8.2 会话范围(HttpSession)

  1. 何时创建和销毁的
    1. 创建:服务器端第一次调用getSession()方法的时候。
    2. 销毁:三种情况。
      1. Session过期,默认的过期时间30分钟(Tomcat/conf/web.xml中<session-timeout>配置)。
      2. 非正常关闭服务器。(正常关闭服务器—session会被序列化)。
      3. 手动调用session.invalidate();
  2. 如何存取数据
    1. 存数据:
      1. void setAttribute(String name,Object value);
    2. 取数据
      1. Object getAttribute(String name);
  3. 作用范围

作用范围:一次会话(多次请求)

8.3 应用范围(ServletContext)

  1. 何时创建和销毁的
    1. 创建:服务器启动的时候创建,为每个web项目创建一个单独ServletContext对象。
    2. 销毁:服务器关闭的时候,或者项目从服务器中移除的时候。
  2. 如何存取数据
    1. 存数据:
      1. void setAttribute(String name,Object value);
    2. 取数据
      1. Object getAttribute(String name);
  3. 作用范围

作用范围:整个应用

九、案例实现

9.1 需求

9.2 准备

步骤1:创建WEB项目

步骤2:引入jar包(jar包左下角带图标,说明引入成功)

步骤:3:创建4个包

 步骤4:引入工具类和配置文件

 步骤5:引入相关的类并修改

 

 

  步骤6:修改配置文件

 步骤7:创建登录页面

 

 步骤8:输入http://localhost/demo2/login.jsp访问

 

 

 9.3 案例代码

9.3.1 用户登录的功能

用户输入用户名和密码进行登录:

        若用户名和密码错误,保存错误信息,回到登录界面;

        若用户名和密码正确,将用户信息保存到会话中,跳转到成功界面。

9.3.2 代码实现

 

(1)http://localhost/demo2/login.jsp,提交表单信息至/demo2/loginServlet

 (2)/demo2/loginServlet代码,并配置相关xml文件

package com.itheima.controller;

import java.io.IOException;

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

import com.itheima.domain.User;
import com.itheima.model.UserModel;

/**
 * 登录的Servlet的编写
 */
public class LoginServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try{
			System.out.println("进入LoginServlet.......");
			response.setContentType("text/html;charset=UTF-8");
			response.getWriter().println("进入Servlet.....");
			// 1.接收数据
			// 处理中文乱码
			request.setCharacterEncoding("UTF-8");
			String username = request.getParameter("username");
			String password = request.getParameter("password");
			String checkcode1 = request.getParameter("checkcode");
			String checkcode2 = (String)request.getSession().getAttribute("checkcode");
			System.out.println("用户输入的验证码为:"+checkcode1);
			System.out.println("会话中存放的验证码为:"+checkcode2);
//			为确保验证码只能使用一次,移除
			request.getSession().removeAttribute("checkcode");
//			验证码出错,则跳转至登录页面
			if(!checkcode1.equalsIgnoreCase(checkcode2)) {
				request.setAttribute("msg", "验证码输入错误!");
				request.getRequestDispatcher("/login.jsp").forward(request, response);
				return;
			}
			System.out.println("验证码验证通过");
			// 2.封装数据
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);
			// 3.处理数据
			UserModel userModel = new UserModel();
			User existUser = userModel.login(user);
			// 4.页面跳转
			if(existUser == null){
				// 登录失败
				// 向request域中保存一个错误信息:
				request.setAttribute("msg", "用户名或密码错误!");
				// 使用请求转发进行页面跳转
				request.getRequestDispatcher("/login.jsp").forward(request, response);
			}else{
				// 登录成功
				// 记录登录成功的人数:
				// 将ServletContext中的值取出 +1
				int count = (int) this.getServletContext().getAttribute("count");
				// 进行了+1的操作
				count++;
				// 将+1后的值存回到ServletContext中去。
				this.getServletContext().setAttribute("count", count);
				// 重定向到成功页面
				response.sendRedirect("/demo2/success.jsp");
			}
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException();
		}
	}

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

}

实体类User.java代码

package com.itheima.domain;
/**
 * 用于封装数据的JavaBean
 * @author jt
 *
 */
public class User {
	private Integer uid;
	private String username;
	private String password;
	private String nickname;
	public Integer getUid() {
		return uid;
	}
	public void setUid(Integer uid) {
		this.uid = uid;
	}
	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;
	}
	public String getNickname() {
		return nickname;
	}
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
	
}

Model.java负责处理从loginServlet存进去的数据

package com.itheima.model;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import com.itheima.domain.User;
import com.itheima.utils.JDBCUtils;

/**
 * 处理数据的JavaBean
 * 
 * @author jt
 *
 */
public class UserModel {

	/**
	 * 处理用户登录的方法:
	 * 
	 * @param user
	 * @return
	 * @throws SQLException
	 */
	public User login(User user) throws SQLException {
		// 连接数据库:通过传入的用户名和密码去数据库中进行查询
		QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
		User existUser = queryRunner.query("select * from user where username = ? and password = ?",
				new BeanHandler<User>(User.class), user.getUsername(), user.getPassword());
		return existUser;
	}

}

 JBUtil为数据库连接的工具类

package com.itheima.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * JDBC的工具类
 * @author jt
 *
 */
public class JDBCUtils {
	// 创建一个连接池:但是这个连接池只需要创建一次即可。
	private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
	
	/**
	 * 获得连接的方法
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException{
		return dataSource.getConnection();
	}
	
	/**
	 * 获得连接池:
	 */
	public static DataSource getDataSource(){
		return dataSource;
	}
	
}

登录成功的界面:success.jsp

<%@page import="com.itheima.domain.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	if(request.getSession().getAttribute("existUser") == null){
%>
<h1>您还未登录,请先去<a href="login.jsp">登录</a></h1>
<%		
	}else{
%>
<h1>用户登录成功!</h1>
<%
	User existUser = (User)request.getSession().getAttribute("existUser");
%>
<h3>您好:<%= existUser.getNickname()%></h3>
<%
}
%>
</body>
</html>

 十、一次性验证码的使用

一次性验证码作用:防止恶意灌水。而且一次性验证码只能够使用一次,不管成功或者失败,验证码都将失效

一次性验证码生成(随机生成4个字母或数字,由response生成一张图片响应到页面)

 

步骤1:创建Servlet及相关xml文件

  1. 复制Servlet到指定的包下
  2. 修改web.xml完成该Servlet的配置

 页面中引入Servlet

 checkImgservlet代码:

package com.itheima.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
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;

/**
 * 生成验证码图片
 * 
 * 
 */
public class CheckImgServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 禁止缓存
		// response.setHeader("Cache-Control", "no-cache");
		// response.setHeader("Pragma", "no-cache");
		// response.setDateHeader("Expires", -1);
		System.out.println("check.......");
		int width = 120;
		int height = 30;

		// 步骤一 绘制一张内存中图片
		BufferedImage bufferedImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		// 步骤二 图片绘制背景颜色 ---通过绘图对象
		Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
		// 绘制任何图形之前 都必须指定一个颜色
		graphics.setColor(getRandColor(200, 250));
		graphics.fillRect(0, 0, width, height);

		// 步骤三 绘制边框
		graphics.setColor(Color.WHITE);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 步骤四 四个随机数字
		Graphics2D graphics2d = (Graphics2D) graphics;
		// 设置输出字体
		graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

		String words =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
		//String words = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6";
		Random random = new Random();// 生成随机数

		
		StringBuffer buffer = new StringBuffer();
		// 定义x坐标
		int x = 10;
		for (int i = 0; i < 4; i++) {
			// 随机颜色
			graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
					.nextInt(110), 20 + random.nextInt(110)));
			// 旋转 -30 --- 30度
			int jiaodu = random.nextInt(60) - 30;
			// 换算弧度
			double theta = jiaodu * Math.PI / 180;

			// 生成一个随机数字
			int index = random.nextInt(words.length()); // 生成随机数 0 到 length - 1
			// 获得字母数字
			char c = words.charAt(index);
			buffer.append(c);
			// 将c 输出到图片
			graphics2d.rotate(theta, x, 20);
			graphics2d.drawString(String.valueOf(c), x, 20);
			graphics2d.rotate(-theta, x, 20);
			x += 30;
		}
//		将验证码存入会话
		 String checkcode = buffer.toString();
		 System.out.println(checkcode);
		 request.getSession().setAttribute("checkcode",checkcode);
		 
		
		

		// 步骤五 绘制干扰线
		graphics.setColor(getRandColor(160, 200));
		int x1;
		int x2;
		int y1;
		int y2;
		for (int i = 0; i < 30; i++) {
			x1 = random.nextInt(width);
			x2 = random.nextInt(12);
			y1 = random.nextInt(height);
			y2 = random.nextInt(12);
			graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
		}

		// 将上面图片输出到浏览器 ImageIO
		graphics.dispose();// 释放资源
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

	}


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

	/**
	 * 取其某一范围的color
	 * 
	 * @param fc
	 *            int 范围参数1
	 * @param bc
	 *            int 范围参数2
	 * @return Color
	 */
	private Color getRandColor(int fc, int bc) {
		// 取其随机颜色
		Random random = new Random();
		if (fc > 255) {
			fc = 255;
		}
		if (bc > 255) {
			bc = 255;
		}
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

}

 一次性验证码的校验(LoginServlet.java)

 十一、一次性验证码点击切换图片

login.jsp中加入切换图片“看不清,换一张”的超链接

            <td>验证码</td>
			<td><input type="text" name="checkcode"><image id="img1" src="/demo2/check">
				<a href="#" onclick="changeImage()">看不清换一张</a>
			</td>

login.jsp中的<head>标签下新增<scrpt>实现切换图片的事件,

注意,若src后不加date,图片不会切换,原因是地址一样时,浏览器会默认访问缓存。

<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	function changeImage(){
		console.log("changeImage");
		document.getElementById("img1").src="/demo2/check?time="+new Date().getTime();
	}
</script>
</head>

十二、记住用户名的实现

如果在登录的过程中,将记住用户名的复选框勾选了,而且在登录成功情况下,需要记住用户名,在关闭浏览器,下次访问该网站的登录页面的时候,会在用户名的文本框中自动呈现出用户名。

后台代码(loginServlet.java)

前端代码(login.jsp)

 十三、系统的退出

 success.jsp中加入退出的超链接

<h3>您好:<%= existUser.getNickname()%><a href="/demo2/LogoutServlet">退出</a></h3>

编写logoutServlet

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值