## Session
1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
2. 快速入门:
1. 获取HttpSession对象:
HttpSession session = request.getSession();
2. 使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
3. 原理
* Session的实现是依赖于Cookie的。
4. 细节:
1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
* 默认情况下。不是。
* 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
* 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
* session的钝化:
* 在服务器正常关闭之前,将session对象系列化到硬盘上
* session的活化:
* 在服务器启动后,将session文件转化为内存中的session对象即可。
3. session什么时候被销毁?
1. 服务器关闭
2. session对象调用invalidate() 。
3. session默认失效时间 30分钟
选择性配置修改
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5. session的特点
1. session用于存储一次会话的多次请求的数据,存在服务器端
2. session可以存储任意类型,任意大小的数据
* session与Cookie的区别:
1. session存储数据在服务器端,Cookie在客户端
2. session没有数据大小限制,Cookie有
3. session数据安全,Cookie相对于不安全
## 案例:验证码
1. 案例需求:
1. 访问带有验证码的登录页面login.jsp
2. 用户输入用户名,密码以及验证码。
* 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
* 如果验证码输入有误,跳转登录页面,提示:验证码错误
* 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
代码:
domain.User.java
package domain;
public class User {
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;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
util.JDBCUtils.java
package util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* JDBC工具类 使用Durid连接池
*/
public class JDBCUtils {
private static DataSource ds ;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
//使用ClassLoader加载配置文件,获取字节输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//2.初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池对象
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取连接Connection对象
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
dao.UserDao.java
package dao;
import domain.User;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import util.JDBCUtils;
public class UserDao {
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
// loginUser.getUsername(), loginUser.getPassword());对应问号
//根据用户输入的值查询数据库中是否有这个数据,返回User
public User login(User loginUser){
try {
//编写sql
String sql="select *from user where username=? and password=?";
//封装成user
User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),
loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (DataAccessException e) {
e.printStackTrace();
}
return null;
}
}
servlet.CheckCodeServlet.java
package servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 50;
//1.创建一对象,在内存中图片(验证码图片对象)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//2.美化图片
//2.1 填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0,0,width,height);
//2.2画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width - 1,height - 1);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
//生成随机角标
Random ran = new Random();
//定义一个StringBuilder
StringBuilder sb=new StringBuilder();
for (int i = 1; i <= 4; i++) {
int index = ran.nextInt(str.length());
//获取字符
char ch = str.charAt(index);//随机字符
//把字符存到StringBuider中
sb.append(ch);
//2.3写验证码
g.drawString(ch+"",width/5*i,height/2);
}
//把StringBuider替换为String
String checkcode = sb.toString();
HttpSession session = request.getSession();
//把验证码存到session中
session.setAttribute("checkcode",checkcode);
//2.4画干扰线
g.setColor(Color.GREEN);
//随机生成坐标点
for (int i = 0; i < 10; i++) {
int x1 = ran.nextInt(width);
int x2 = ran.nextInt(width);
int y1 = ran.nextInt(height);
int y2 = ran.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
//3.将图片输出到页面展示
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
window.onload = function () {
var img = document.getElementById("img");
img.onclick = function () {
//加时间戳
var date = new Date().getTime();
img.src = "/login/checkCodeServlet?" + date;
}
}
</script>
<style>
.c{color: deeppink;
}
</style>
</head>
<body>
<form action="/login/loginServlet" method="post">
<table>
<tr><td>用户名:<input type="text" name="username"></td></tr>
<tr><td>密码:<input type="password" name="password"></td></tr>
<tr><td>验证码:<input type="text" name="checkcode"></td></tr>
<tr><td rowspan="2"><img id="img" src="/login/checkCodeServlet"></td></tr>
<tr><td><input type="submit" value="登录"></td></tr>
</table>
</form>
<%--在域中仅仅封装的数据不用强制转换--%>
<%!
String blanknull(String s)
{
return (s == null) ? "" : s;
}
%>
<%String usererorr = (String)request.getAttribute("usererror");%>
<p class="c"><%=blanknull(usererorr)%></p>
<% String codeerror = (String)request.getAttribute("codeerror");%>
<p class="c"><%=blanknull(codeerror)%></p>
</body>
</html>
servlet.LoginServlet.java
package servlet;
import dao.UserDao;
import domain.User;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置接受的的数据编码
request.setCharacterEncoding("utf-8");
//把数据封装为map对象
Map<String, String[]> map = request.getParameterMap();
//设置一个空的User对象
User loginUser = new User();
try {
//封装map数据到loginUser中
BeanUtils.populate(loginUser, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//因为验证码是单独生成的,所以单独获取用户输入的验证码,
String checkcode = request.getParameter("checkcode");
HttpSession session = request.getSession();
//获取CheckCode生成的验证码并把验证码强行转换为String格式
String checkcode1 = (String) session.getAttribute("checkcode");
//防止登录成功后退验证码依然能有效
session.removeAttribute("checkcode");
//验证码正确
//IgnoreCase(String)是比较字符不区分大小写的方法
if (checkcode != null && checkcode.equalsIgnoreCase(checkcode1)) {
//如果一样的话
UserDao dao = new UserDao();
//调用login方法,参数为封装的loginUser对象
User user = dao.login(loginUser);
//用户输入的值正确
//如果用户不为空证明查找到用户的值
if (user != null) {
//把返回的user存入session中
session.setAttribute("user", user);
//重定向到success界面
response.sendRedirect(request.getContextPath()+"/success.jsp");
} else {
//账号或密码不正确
request.setAttribute("usererror", "账号或密码输入错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
} else {
//验证码输入不正确
request.setAttribute("codeerror", "验证码输入错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
success.jsp
<%@ page import="domain.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
HttpSession session1 = request.getSession();
//一定得强制转换,因为知道user是User类型
User user = (User) session1.getAttribute("user");
%>
<h1><%=user.getUsername()%>欢迎登陆成功</h1>
</body>
</html>