Servlet进阶(Session对象实现登录)
引言:
本文主要分享了有关Session对象的内容,并且利用Session对象实现登录操作,引入ValidateCode实现验证码判定;
@[toc]
1. Session概述
Session对象用于记录用户的状态,指的是在一段时间内,单个客户端与Web服务器的一系列交互过程;在一个Session中,客户可能会多次访问一个资源同样也可能是不同的资源;
1.1 Session的原理
Session是由服务器创建的;
- 服务器为每一次会话分配一个Session对象;
- 同一浏览器发起多次请求属于一次会话;
- 首次使用Session时,服务器会创建自动Session,并创建Cookie存储Session发送回客户端;
1.2 Session的使用
Session的作用范围是一次会话有效,拥有存储数据的空间;
- 同一浏览器发起多次请求属于一次会话,一旦浏览器关闭就结束会话;
- Session中存入数据,再一次会话的任意位置进行获取;
- 可以传递任意类型的数据;
1.2.1 获取Session
- 通过Request对象获取
//写入session
HttpSession session = request.getSession();
System.out.println("name:" + session.getName());
1.2.2 保存数据
- setAttribute(属性名,Object);、保存数据到Session中;
//传入session中
session.setAttribute("vcode", codes);
1.2.3 获取数据
- setAttribute(属性名);、获取Session中的数据;
//获取数据
session.getAttribute("vcode");
- 通过vcode访问codes
1.2.4 移除数据
- removeAttribute(属性名);、从Session中删除数据;
//删除数据
session.getAttribute("vcode");
1.3 Session和Request的区别
- Session:一次会话有效,浏览器改变Session改变
- Request:一次请求有效,请求改变Request改变
2. 基于Session的登录案例
步骤:
- 创建数据库表
- 将数据写入接口实现类中
- 当用户首次访问登录页时,服务端先生成验证码,并将其存入session中,再生成图片随登录页显示
- 用户登录(含有验证码);
- 当用户登陆时,将用户名、密码、验证码发送到后端;
- servlet接受到登录请求时,先判断验证码是否有效(和服务端的session存储的验证码比对);
- 如果验证码有效,则继续根据用户名查询用户信息;
- 将登录请求的密码和用户信息中的密码进行对比;
- 如果密码匹配正确,则登录成功,再将用户信息写入session作用域中;
- 返回登录成功页面;
- 当用户访问其他页面时,首先判定用户是否登陆,如果没登陆则,导航到登录页;如果已登陆,则直接访问该页;
2.1 创建数据库表
CREATE TABLE login(
username VARCHAR(20),
PASSWORD VARCHAR(50)
)CHARSET = utf8;
INSERT INTO login(username,PASSWORD) VALUES ("admin","123456");
2.2 创建UserInfo.java封装用户名、密码
package com.yl.kaka.entity;
public class UserInfo {
private String username;
private String 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;
}
}
2.3 创建JDBCUtils.java封装JDBC工具类
package com.yl.kaka.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCUtils {
//定义常量
final static String driver = "com.mysql.jdbc.Driver";
final static String url = "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8";
final static String username = "root";
final static String password = "root";
//声明常用对象
protected Connection conn = null;
protected PreparedStatement pstmt = null;
protected ResultSet rs = null;
//静态代码块
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public void getConnection(){
try {
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
}
//关闭资源
public void closeAll(){
try {
if(rs != null) rs.close();
if(pstmt != null) rs.close();
if(conn != null) rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2.4 创建UserInfoDao.java接口
package com.yl.kaka.dao;
import com.yl.kaka.entity.UserInfo;
public interface UserInfoDao {
public UserInfo findUserInfoByUsername(String username);
}
2.5 创建UserInfoDaoImpl.java接口实现类
package com.yl.kaka.dao;
import java.sql.SQLException;
import com.yl.kaka.entity.UserInfo;
import com.yl.kaka.util.JDBCUtils;
public class UserInfoDaoImpl extends JDBCUtils implements UserInfoDao {
@Override
public UserInfo findUserInfoByUsername(String username) {
String sql = "SELECT * FROM LOGIN";
try {
super.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
UserInfo info = new UserInfo();
while(rs.next()){
if (username.equals(rs.getString("username"))) {
String password = rs.getString("password");
info.setPassword(rs.getString("password"));
info.setUsername(username);
}else{
return null;
}
}
return info;
} catch (SQLException e) {
e.printStackTrace();
}finally{
super.closeAll();
}
return null;
}
}
2.6 配置XML文件
<servlet>
<servlet-name>InforServlet</servlet-name>
<servlet-class>com.yl.kaka.controller.UserInfoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>InforServlet</servlet-name>
<url-pattern>/userInfo</url-pattern>
</servlet-mapping>
2.7 编写UserInfoServlet.java
package com.yl.kaka.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 javax.servlet.http.HttpSession;
import com.yl.kaka.dao.UserInfoDao;
import com.yl.kaka.dao.UserInfoDaoImpl;
import com.yl.kaka.entity.UserInfo;
import cn.dsna.util.images.ValidateCode;
public class UserInfoServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取页面的值
String action = request.getParameter("action");
if(action == null){
//获取跳转的页面
request.getRequestDispatcher("login.jsp").forward(request, response);
}else if(action.equals("code")){
//获取验证码
//生成验证码
ValidateCode vc = new ValidateCode(200,30,4,10);
//获取验证码
String codes = vc.getCode();
//写入session
HttpSession session = request.getSession();
//传入session中
session.setAttribute("vcode", codes);
//写入流中
vc.write(response.getOutputStream());
}else if(action.equals("login")){
//展示登录页面
//处理登录请求,获取信息
String username = request.getParameter("username")== null?"Admins":request.getParameter("username");
String password = request.getParameter("password");
String verifyCode = request.getParameter("verifyCode");
//从session中获取事先存储的验证码
HttpSession session = request.getSession();
String sessionCode = (String)session.getAttribute("vcode");
//匹配验证码
if(!verifyCode.isEmpty()&&verifyCode.equalsIgnoreCase(sessionCode)){
//验证码正确,继续根据用户名查询用户信息
UserInfoDao uid = new UserInfoDaoImpl();
//调用方法
UserInfo userInfo = uid.findUserInfoByUsername(username);
if (userInfo!=null) {
if(userInfo.getPassword().equalsIgnoreCase(password)){
//登录成功,将用户信息写入session中
session.setAttribute("userInfo", username);
//显示登录成功
request.getRequestDispatcher("success.jsp").forward(request, response);
}else{
//验证码不正确,重新到登录页
response.sendRedirect("login.jsp");
}
}else{
response.sendRedirect("login.jsp");
}
}else{
//验证码不正确,重新到登录页
response.sendRedirect("login.jsp");
}
}else{
//验证用户是否登录才可访问的页
HttpSession session = request.getSession();
Object info = session.getAttribute("userInfo");
if(info!=null){
request.getRequestDispatcher("page.jsp").forward(request, response);
}
else{
response.sendRedirect("login.jsp");
}
}
}
}
2.8 编写login.jsp登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
<style>
body{
text-align:center;
}
</style>
</head>
<body>
<form action="userInfo?action=login" method="post">
USERNAME:<input type = "text" name = "username" /><br/>
PASSWORD:<input type = "password" name = "password"/><br/>
verifyCode:<input type = "text" name = "verifyCode" /> <img src="userInfo?action=code" /> <br/>
<input type = "submit" value = "LOGIN"/>
</form>
</body>
</html>
2.9 成功登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>success...........</h2>
name:<%=session.getAttribute("userInfo") %>
</body>
</html>