学习Java的日子 Day59 学生管理系统 web1.0版本
A 北枝 2024-09-14 11:03:02 阅读 78
Day59 学生管理系统 web1.0
1.项目需求
有两个角色,老师和学生,相同的功能提取到父类用户角色
2.数据库搭建
设计学生表
设计老师表
插入数据 (超级管理员)
设计学科表
3.项目搭建
处理基础页面,分包,实体类,导入数据库
项目结构,导入数据库相关内容
数据库工具类
<code>package com.qf.utils;
public class DBUtils { -- -->
private static DruidDataSource pool;
private static ThreadLocal<Connection> local;
static{
Properties properties = new Properties();
try {
properties.load(DBUtils.class.getClassLoader().getResourceAsStream("DBConfig.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
String driverClassName = properties.getProperty("driverClassName");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
int maxActive = Integer.parseInt(properties.getProperty("maxActive"));
//初始化数据库连接池
pool = new DruidDataSource();
//设置参数
pool.setDriverClassName(driverClassName);
pool.setUrl(url);
pool.setUsername(username);
pool.setPassword(password);
pool.setMaxActive(maxActive);
local = new ThreadLocal<>();
}
/**
* 获取连接对象
*/
public static Connection getConnection() throws SQLException {
Connection connection = local.get();//获取当前线程的Connection对象
if(connection == null){
connection = pool.getConnection();//获取数据库连接池里的连接对象
local.set(connection);//将Connection对象添加到local中
}
return connection;
}
/**
* 关闭资源
*/
public static void close(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(connection != null){
try {
if(connection.getAutoCommit()){
connection.close();
local.set(null);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
/**
* 开启事务
*/
public static void startTransaction() throws SQLException {
Connection connection = getConnection();
connection.setAutoCommit(false);
}
/**
* 提交事务
*/
public static void commit() throws SQLException {
Connection connection = local.get();
if(connection != null){
connection.commit();
connection.close();
local.set(null);
}
}
public static void rollback() throws SQLException {
Connection connection = local.get();
if(connection != null){
connection.rollback();
connection.close();
local.set(null);
}
}
/**
* 更新数据(添加、删除、修改)
*/
public static int commonUpdate(String sql,Object... params) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = getConnection();
statement = connection.prepareStatement(sql);
paramHandler(statement,params);
int num = statement.executeUpdate();
return num;
}finally {
close(connection,statement,null);
}
}
/**
* 添加数据 - 主键回填(主键是int类型可以返回)
*/
public static int commonInsert(String sql,Object... params) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
statement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
paramHandler(statement,params);
statement.executeUpdate();
resultSet = statement.getGeneratedKeys();
int primaryKey = 0;
if(resultSet.next()){
primaryKey = resultSet.getInt(1);
}
return primaryKey;
}finally {
close(connection,statement,resultSet);
}
}
/**
* 查询多个数据
*/
public static <T> List<T> commonQueryList(Class<T> clazz,String sql, Object... params) throws SQLException{
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
statement = connection.prepareStatement(sql);
paramHandler(statement,params);
resultSet = statement.executeQuery();
//获取表数据对象
ResultSetMetaData metaData = resultSet.getMetaData();
//获取字段个数
int count = metaData.getColumnCount();
List<T> list = new ArrayList<>();
while(resultSet.next()){
T t = null;
try {
t = clazz.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
//获取字段名及数据
for (int i = 1; i <= count; i++) {
String fieldName = metaData.getColumnName(i);
Object fieldVal = resultSet.getObject(fieldName);
setField(t,fieldName,fieldVal);
}
list.add(t);
}
return list;
} finally {
DBUtils.close(connection,statement,resultSet);
}
}
/**
* 查询单个数据
*/
public static <T> T commonQueryObj(Class<T> clazz,String sql, Object... params) throws SQLException{
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
statement = connection.prepareStatement(sql);
paramHandler(statement,params);
resultSet = statement.executeQuery();
//获取表数据对象
ResultSetMetaData metaData = resultSet.getMetaData();
//获取字段个数
int count = metaData.getColumnCount();
if(resultSet.next()){
T t = null;
try {
t = clazz.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
//获取字段名及数据
for (int i = 1; i <= count; i++) {
String fieldName = metaData.getColumnName(i);
Object fieldVal = resultSet.getObject(fieldName);
setField(t,fieldName,fieldVal);
}
return t;
}
} finally {
DBUtils.close(connection,statement,resultSet);
}
return null;
}
/**
* 获取当前表的总条数
*/
public static int getAllCount(String table) throws SQLException {
Connection connection = getConnection();
String sql = "select count(1) from " + table;
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();
if(resultSet.next()){
int allCount = resultSet.getInt(1);
return allCount;
}
return 0;
}
/**
* 处理statement对象参数数据的处理器
*/
private static void paramHandler(PreparedStatement statement,Object... params) throws SQLException {
for (int i = 0; i < params.length; i++) {
statement.setObject(i+1,params[i]);
}
}
/**
* 获取当前类及其父类的属性对象
* @param clazz class对象
* @param name 属性名
* @return 属性对象
*/
private static Field getField(Class<?> clazz,String name){
for(Class<?> c = clazz;c != null;c = c.getSuperclass()){
try {
Field field = c.getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
}
return null;
}
/**
* 设置对象中的属性
* @param obj 对象
* @param name 属性名
* @param value 属性值
*/
private static void setField(Object obj,String name,Object value){
Field field = getField(obj.getClass(), name);
if(field != null){
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
创建首页 Welcome.html
<!DOCTYPE html>
<html lang="en">code>
<head>
<meta charset="UTF-8">code>
<title>首页</title>
</head>
<body>
<h1>欢迎来到学生管理系统页面</h1>
<hr>
<span>请选择你的操作:</span><br/>
<a href="login.jsp">登录</a>code>
<a href="register.jsp">注册</a>code>
</body>
</html>
web.xml配置首页
<?xml version="1.0" encoding="UTF-8"?>code>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"code>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"code>
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"code>
version="4.0">code>
//设置首页
<welcome-file-list>
<welcome-file>Welcome.html</welcome-file>
</welcome-file-list>
</web-app>
实现类创建
User
package com.qf.pojo;
public class User { -- -->
private String username;
private String password;
private String name;
private String sex;
private int age;
//无参构造,有参构造,get,set,toString方法省略
Teacher
public class Teacher extends User{
private int course;
public Teacher() {
}
//无参构造,有参构造带父类的属性,get,set,toString方法省略
Student
package com.qf.pojo;
public class Student extends User{
private String hobbies;
//无参构造,有参构造带父类的属性,get,set,toString方法省略
Course
package com.qf.pojo;
public class Course {
private int id;
private String name;
//无参构造,有参构造,get,set,toString方法省略
4.注册功能
注册流程图
注册逻辑 RegisterServlet
注意:老师不用注册是管理员自动分配账号,而学生需要注册
注册逻辑:
1.设置请求、响应编码格式
2.获取请求中的数据
3.通过username查询数据库中的学生对象
4.通过学生对象进行非空判断
没找到就允许注册,将数据插入到学生表中,利用重定向跳转到登录页面
在数据库中就不允许注册,利用重定向跳转到注册页面
注意:
request.getParameter表示获取前端的参数,参数为页面提交的数据(二进制流不使用这个)
request.getAttribute获取请求对象(请求域)中的数据
<code>package com.qf.Servlet;
@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String age = request.getParameter("age");
String[] hobbies = request.getParameterValues("hobbies");
//通过username查询数据库中的学生对象
Student student = null;
try {
student = DBUtils.commonQueryObj(Student.class, "select * from student where username=?", username);
} catch (SQLException e) {
throw new RuntimeException(e);
}
if(student == null){ //在数据库中没有找到,说明没有这个学生,就允许注册
//将数据插入到学生表中
try {
DBUtils.commonUpdate("insert into student(username,password,name,sex,age,hobbies) values(?,?,?,?,?,?)",username,password,name,sex,age, StringUtils.handleArray(hobbies));
} catch (SQLException e) {
throw new RuntimeException(e);
}
//利用重定向跳转到登录页面
response.sendRedirect("login.jsp");
}else{ //不允许注册
//展示信息,将数据直接设置在request中
//将数据存储到请求域中,生命周期非常短,一来一回就死亡了
//请求发送后,响应后就死亡了
request.setAttribute("msg","注册失败 -- 账号已存在");
//利用转发跳转到注册页面
request.getRequestDispatcher("register.jsp").forward(request,response);
}
}
}
理解以下代码
请求域对象都是使用request
//展示提示信息,将数据存储到请求对象(请求域)中,生命周期非常短,一来一回就死亡了,请求发送后,响应后就死亡了
//只是在web容器内部流转,仅仅是请求处理阶段
request.setAttribute("msg","注册失败 -- 账号已存在");
//利用转发跳转到注册页面
request.getRequestDispatcher("register.jsp").forward(request,response);
//register.jsp前端获取
<%
String msg = (String) request.getAttribute("msg");
%>
注册页面 register.jsp
JSP的脚本:JSP定义Java代码的方式
可以简单理解为几个标签,带有<% % >
<% java代码 %>:写的是java的逻辑代码
<%= java‘代码 %>:写的java代码,会输出展示到页面上。输出语句中可以定义什么,jsp页面就会显示什么内容
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 在jsp中写java代码用<% %> 包裹,拿到请求对象(请求域)中的提示信息:注册失败 -- 账号已存在 -->
<%
String msg = (String) request.getAttribute("msg");
%>
<!-- 在页面中展示提示信息 三目运算符 第一次进入为空不展示-->
<%= (msg != null)? msg:"" %>
<h1>注册页面</h1>
<form action="RegisterServlet" method="post">code>
账号:<input type="text" name="username"/><br/>code>
密码:<input type="password" name="password"/><br/>code>
姓名:<input type="text" name="name"/><br/>code>
年龄:<input type="text" name="age"/><br/>code>
性别:
<input type="radio" name="sex" value="man" checked="checked"/>男code>
<input type="radio" name="sex" value="woman"/>女code>
<br/>
爱好:
<input type="checkbox" name="hobbies" value="football"/>足球code>
<input type="checkbox" name="hobbies" value="basketball"/>篮球code>
<input type="checkbox" name="hobbies" value="shop"/>购物code>
<br/>
<input type="submit" value="注册"/>code>
<input type="button" value="返回" οnclick="goWelcome()">code>
</form>
<script type="text/javascript">code>
function goWelcome(){
window.location = "http://localhost:8080/StudentManagementSystem_Web_exploded/";
}
</script>
</body>
</html>
优化注册页面 register.jsp
<!-- 在jsp中写java代码用<% %> 包裹 -->
<%
String msg = (String) request.getAttribute("msg");
%>
<!-- 在页面中展示数据 三目运算符 第一次进入为空不展示-->
<%= (msg != null)? msg : "" %>
//上面的不要,直接用这一行代码展示msg(页面会自动拿到数据)
${ msg}
因为hobbies是一个字符串数组,所以写一个工具类,让其拼接字符串
StringUtils
利用反射操作数组
package com.qf.utils;
import java.lang.reflect.Array;
public class StringUtils {
public static String handleArray(Object[] os){
StringBuffer sb = new StringBuffer();
for (int i=0;i< Array.getLength(os);i++){ //利用反射操作数组Array
if (i!=0){
sb.append(",");
}
//获取当前下标上的元素
Object element = Array.get(os, i);
sb.append(element);
}
// for (Object element : os) {
// if(sb.length() !=0){
// sb.append(",");
// }
// sb.append(element);
// }
return sb.toString();
}
}
运行结果:
点击注册,输入数据,注册成功(账号没有在数据库里就会注册成功)跳转到登录页面,失败会跳转到注册页面,页面上会显示提示信息 注册失败 – 账号已存在
查看数据库
5.登录页面
LoginServlet
1.设置请求、响应编码格式
2.获取请求中的数据
3.验证码是否输入正确
不正确登录失败 - 验证码错误
4.正确,通过username、password查询数据库中的用户对象
5.通过用户对象判断(是否在数据库中)
<code> 登录成功,利用重定向跳转到详情页面(凭证添加到Cookie,数据存储到Session)
登录失败 – 账号或密码错误,利用重定向跳转到登录页面
package com.qf.Servlet;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String userCode = request.getParameter("userCode");
String rememberMe = request.getParameter("rememberMe");
String role = request.getParameter("role");
String sysCode = (String) request.getSession().getAttribute("sysCode");
if (sysCode.equalsIgnoreCase(userCode)){ //验证码是否输入正确
User user=null;
try {
if ("student".equals(role)){
user=DBUtils.commonQueryObj(Student.class,"select * from student where username=? and password=?",username,password);
} else if ("teacher".equals(role)) {
user=DBUtils.commonQueryObj(Teacher.class,"select * from teacher where username=? and password=?", username, password);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
if (user!=null){ //登录成功
//判断是否记住我
if(rememberMe != null){
//将凭证添加到Cookie中
//cookie保存在浏览器中
response.addCookie(CookieUtils.createCookie("username",user.getUsername(),60*60*24*5));
response.addCookie(CookieUtils.createCookie("name",user.getName(),60*60*24*5));
response.addCookie(CookieUtils.createCookie("role",role,60*60*24*5));
}
//将数据存储到Session中(后续需要使用的)
//浏览器向服务器发送一个请求,服务器会生成一个session对象,保存在服务器中
HttpSession session = request.getSession();
session.setAttribute("username",user.getUsername());
session.setAttribute("name",user.getName());
session.setAttribute("role",role);
response.sendRedirect("index.jsp");
}else{ //登录失败 -- 账号或密码错误
request.setAttribute("msg","登录失败--账号或密码错误");
request.getRequestDispatcher("login.jsp").forward(request,response);
}
}else{ //登录失败 - 验证码错误
//将数据发送到请求对象(请求域)中,时间在一瞬间,交互很短
//我们使用request.setAttribute()方法设置了一个名为 “msg” 的属性,并将其值设置为 “登录失败--验证码错误”。
// 然后,我们可以通过请求转发(forward)将这个属性传递给其他组件,如另一个Servlet或JSP页面
request.setAttribute("msg","登录失败--验证码错误");
request.getRequestDispatcher("login.jsp").forward(request,response);
}
}
}
login.jsp
关注验证码的写法,还有就是刷新验证码和点击验证码自动刷新
注意设置刷新验证码的函数
<%@ page import="java.net.URLDecoder" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 记住我的代码 -->
<%
Cookie[] cookies = request.getCookies();
if(cookies != null){
int count = 0;
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = URLDecoder.decode(cookie.getValue(),"UTF-8");
if("username".equals(name)){
session.setAttribute("username",value);
count++;
}
if("name".equals(name)){
session.setAttribute("name",value);
count++;
}
if("role".equals(name)){
session.setAttribute("role",value);
count++;
}
}
if(count == 3){
response.sendRedirect("index.jsp");
}
}
%>
<!-- 判断登录结果,成功还是失败,提示信息显示在页面上方 -->
<%
String msg = (String) request.getAttribute("msg");
%>
<%= (msg!=null)?msg:""%>
<h1>登录页面</h1>
<!--点击登录页面,会方式两次请求,一次是LoginServlet,第二次是CodeServlet-->
<form action="LoginServlet" method="post">code>
账号:<input type="text" name="username"/><br/>code>
密码:<input type="password" name="password"/><br/>code>
验证码:<input type="text" name="userCode"/><img src="CodeServlet" width="120px" height="30px" οnclick="refresh()"><a href="#" οnclick="refresh()">刷新</a><br/>code>
记住我:<input type="checkbox" name="rememberMe"/><br/>code>
角色:
<select name="role">code>
<option value="student">学生</option>code>
<option value="teacher">老师</option>code>
</select>
<br/>
<input type="submit" value="登录"/>code>
<input type="button" value="返回" οnclick="goWelcome()"/>code>
</form>
<script type="text/javascript">code>
function goWelcome(){
window.location = "welcome.html";
}
//刷新验证码
img = document.getElementsByTagName("img")[0];
function refresh(){
img.src = "CodeServlet?" + new Date();
}
</script>
</body>
</html>
优化login.jsp
<%@ page import="java.net.URLDecoder" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 记住我的java代码直接写出去 rememberMe.jsp,然后导包 -->
<%@include file="rememberMe.jsp"%>code>
<!-- 判断登录结果,成功还是失败,显示在页面上方 -->
<%--<%--%>
<%-- String msg = (String) request.getAttribute("msg");--%>
<%--%>--%>
<%--<%= (msg!=null)?msg:""%>--%>
${ msg}
<h1>登录页面</h1>
<!--点击登录页面,会方式两次请求,一次是LoginServlet,第二次是CodeServlet-->
<form action="LoginServlet" method="post">code>
账号:<input type="text" name="username"/><br/>code>
密码:<input type="password" name="password"/><br/>code>
...省略
</body>
</html>
java代码直接写出去 rememberMe.jsp,然后导包
rememberMe.jsp
<%@ page import="java.net.URLDecoder" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<%
Cookie[] cookies = request.getCookies();
if(cookies != null){
int count = 0;
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = URLDecoder.decode(cookie.getValue(),"UTF-8");
if("username".equals(name)){
session.setAttribute("username",value);
count++;
}
if("name".equals(name)){
session.setAttribute("name",value);
count++;
}
if("role".equals(name)){
session.setAttribute("role",value);
count++;
}
}
if(count == 3){
response.sendRedirect("index.jsp");
}
}
%>
5.1 绘制验证码
CodeServlet
1.创建画布(前提定义宽高)
2.通过画布获取画笔
3.设置背景色 – 填充矩形【利用画笔】
4.设置验证码
创建验证码数字数组、颜色数组
利用随机数进行获取随机下标从而获取随机数字和颜色
设置随机颜色
设置字体(字体,样式,大小)
设置单个验证码
StringBffer拼接成验证码
设置干扰线
6.ImageIO将画布以jpg形式的文件传出给客户端
package com.qf.Servlet;
@WebServlet("/CodeServlet")
public class CodeServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//验证码是图片,不需要编码格式
//设置宽高的变量
int width = 120;
int height = 30;
//创建画布
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics graphics = image.getGraphics();
//设置背景色 -- 填充矩形
graphics.setColor(Color.BLUE);//选择颜色
graphics.fillRect(0,0,width,height);//填充整个图片区域
//设置验证码
Random random = new Random();
String[] codes = { "A","B","C","D","E","F","G","H","J","K","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"};
Color[] colors = { Color.CYAN,Color.BLACK,Color.GREEN,Color.PINK,Color.WHITE,Color.RED,Color.ORANGE};
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
String randomCode = codes[random.nextInt(codes.length)];//随机内容
Color randomColor = colors[random.nextInt(colors.length)];//随机颜色
graphics.setColor(randomColor);//设置随机颜色
graphics.setFont(new Font("宋体",Font.BOLD,20+random.nextInt(10)));//设置字体(字体,样式,大小)
graphics.drawString(randomCode,20+i*25,15+random.nextInt(10));//设置单个验证码
sb.append(randomCode);
}
//将系统验证码设置到Session对象中(会话对象),存储在服务器中
//浏览器向服务器发送一个请求,服务器会生成一个session对象
HttpSession session = request.getSession();//获取请求里的JSESSIONID(客户端Cookie里的数据),如果没有就创建Session对象,如果有就从Session容器中获取会话对象
session.setAttribute("sysCode",sb.toString());//键值对,键是String类型,值是Object对象
//设置干扰线
graphics.setColor(Color.YELLOW);
for (int i = 0; i < 3; i++) {
graphics.drawLine(random.nextInt(width),random.nextInt(height),random.nextInt(width),random.nextInt(height));//绘制直线(x1,y1,x2,y2) -> 两点为一线
}
//将画布以jpg形式的文件传出给客户端,ImageIO工具
ImageIO.write(image,"jpg",response.getOutputStream());
}
}
5.2 分析验证码功能制作
注册功能中的request.getAttribute:将数据直接设置在request中,利用request调用,存储时间短
验证码功能中的HttpSession session = request.getSession(); 浏览器向服务器发送一个请求,服务器会生成一个session对象,利用session(request.getSession() )去调用,30分钟
区别:session的过期时间是30分钟,可以调,长时间的属性可以放在session,一瞬间的数据可以放在jsp里请求对象request里
session对象的作用域为一次会话,通常浏览器不关闭,保存的值就不会消失,当然也会出现session超时(tomcat默认为30分钟)
session.getAttribute(“”) 取到的类型是是object,所以赋值前要强转一下 ,转成你需要的类型
Session的基本工作原理:
用户访问Web应用程序时,服务器为每个用户创建一个唯一的Session对象。服务器将Session ID 分配给每个Session对象,并将Session ID 存储在用户的浏览器中的Cookie中。Session ID 在服务器端和客户端之间用于标识Session。当用户发送请求时,服务器使用Session ID 来查找相应的Session对象。服务器可以将数据存储在Session对象中,以便在用户的不同请求之间共享。当用户关闭浏览器或Session超时时,Session对象被销毁。
session的相关使用
1.获取Session对象,使用的是request对象
<code>HttpSession session = request.getSession();
2.存储数据到 session 域中
session.setAttribute(String name, Object o)
3.根据 key,获取值
session.getAttribute(String name)
验证码功能就是把把验证码存在session对象中,设置键值对属性
输入一个验证码,会寻找对应的session ID,获取对应的值,这个有30分钟,不同的验证码请求有不同的ID
//将系统验证码设置到Session对象中(会话对象)
//浏览器向服务器发送一个请求,服务器会生成一个session对象
HttpSession session = request.getSession();//获取请求里的JSESSIONID(客户端Cookie里的数据),如果没有获取到就创建Session对象,如果有就从Session容器中获取会话对象
session.setAttribute("sysCode",sb.toString());//键值对,键是String类型,值是Object对象
从Session对象中取出来判断
request.getSession() -->获取到这个session对象,再获取里面的value
//从Session对象中获取系统的验证码
String sysCode = (String) request.getSession().getAttribute("sysCode");
if(sysCode.equalsIgnoreCase(userCode)){
......
}
结论
1.Cookie是用来保证用户在未登录情况下的身份识别
2.Session是用来保存用户登录后的数据
3.Session是存储在服务端,而Cookie是存储在客户端
4.购物车、记住我功能:使用Cookie来存储
5.以登录用户的名称展示、验证码:使用Session来存储
运行结果:
输入一个在数据库有的数据
5.3 记住我(存Session、存Cookie)
流程图
实现:存Session、存Cookie
LoginServlet
添加存凭证
1.当第一次登录时,点击了“记住我”,就会存凭证【username、name、role合起来是一个凭证】存在Cookie中
2.再次登录就会判断,是否有凭证
<code> 有,直接跳详情页面,不过在跳转前会将凭证存在session中【因为详情页展示需要session的数据】
没有,就不管,就用户直接输入登录
package com.qf.Servlet;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet { -- -->
String sysCode = (String) request.getSession().getAttribute("sysCode");
if (sysCode.equalsIgnoreCase(userCode)){ //验证码是否输入正确
User user=null;
try {
if ("student".equals(role)){
user=DBUtils.commonQueryObj(Student.class,"select * from student where username=? and password=?",username,password);
} else if ("teacher".equals(role)) {
user=DBUtils.commonQueryObj(Teacher.class,"select * from teacher where username=? and password=?", username, password);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
if (user!=null){ //登录成功
//判断是否记住我
if(rememberMe != null){
//将凭证添加到Cookie中
//cookie保存在客户端中(键值对都是String类型)
response.addCookie(CookieUtils.createCookie("username",user.getUsername(),60*60*24*5));
response.addCookie(CookieUtils.createCookie("name",user.getName(),60*60*24*5));
response.addCookie(CookieUtils.createCookie("role",role,60*60*24*5));
}
//将凭证数据存储到Session中
//浏览器向服务器发送一个请求,服务器会生成一个session对象,保存在服务器中
HttpSession session = request.getSession();
session.setAttribute("username",user.getUsername());
session.setAttribute("name",user.getName());
session.setAttribute("role",role);
response.sendRedirect("index.jsp");
}else{ //登录失败 -- 账号或密码错误
request.setAttribute("msg","登录失败--账号或密码错误");
request.getRequestDispatcher("login.jsp").forward(request,response);
}
添加cookie工具类
CookieUtils
package com.qf.utils;
public class CookieUtils {
public static Cookie createCookie(String name,String value,int time) {
Cookie cookie=null;
try {
//数据中有中文,必须设置编码格式
cookie= new Cookie(name, URLEncoder.encode(value, "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
cookie.setMaxAge(time);
return cookie;
}
}
login.jsp
<%@ page import="java.net.URLDecoder" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- 记住我的代码 -->
<%
Cookie[] cookies = request.getCookies();
if(cookies != null){
int count = 0;
for (Cookie cookie : cookies) {
String name = cookie.getName();
//取数据时需要解码
String value = URLDecoder.decode(cookie.getValue(),"UTF-8");
if("username".equals(name)){
//存储value值
session.setAttribute("username",value);
count++;
}
if("name".equals(name)){
session.setAttribute("name",value);
count++;
}
if("role".equals(name)){
session.setAttribute("role",value);
count++;
}
}
if(count == 3){
response.sendRedirect("index.jsp");
}
}
%>
<!-- 判断登录结果,成功还是失败,显示在页面上方 -->
<%
String msg = (String) request.getAttribute("msg");
%>
<%= (msg!=null)?msg:""%>
<h1>登录页面</h1>
.......
Cookie:
1.创建Cookie对象,并设置值:
Cookie cookie = new Cookie("key","value");
2.发送Cookie到客户端使用的是Reponse对象:
response.addCookie(cookie);
3.获取Cookie:使用Request对象获取Cookie数组:
Cookie[] cookies = request.getCookies();
6.详情页
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//取出登录页面存储的session对象
String username = (String) session.getAttribute("username");
String name = (String) session.getAttribute("name");
String role = (String) session.getAttribute("role");
%>
<button onclick="safeExit()">安全退出</button>code>
<h1>详情页面</h1>
<h1>欢迎<%=name%><%=("student".equals(role))?"学员":""%><%=("teacher".equals(role))?"老师":""%>进入到学生管理系统</h1>
<a href="resetPassword.jsp">修改密码</a>code>
<%if("student".equals(role)){ -- -->%>
<!-- 在这个servlet通过username找到这个学生,再跳转到信息修改页面 -->
<a href="StuInitModifyServlet?username=<%=username%>">修改信息</a>code>
<%}%>
<%if("teacher".equals(role)){ -- -->%>
<a href="TeaInitModifyServlet?username=<%=username%>">修改信息</a>code>
<a href="#">查看所有学生</a>code>
<%}%>
<script type="text/javascript">code>
function safeExit(){ -- -->
window.location = "SafeExitServlet";
}
</script>
</body>
</html>
优化:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--<%--%>
<%-- String username = (String) session.getAttribute("username");--%>
<%-- String name = (String) session.getAttribute("name");--%>
<%-- String role = (String) session.getAttribute("role");--%>
<%--%>--%>
<button onclick="safeExit()">安全退出</button>code>
<h1>详情页面</h1>
<%--<%=("student".equals(role))?"学员":""%>--%>
<%--${ (role eq "student")?"学员":""}--%>
<h1>欢迎${ name}${ (role eq "student")?"学员":""}${ (role eq "teacher")?"学员":""}进入到学生管理系统</h1>
<a href="resetPassword.jsp">修改密码</a>code>
<c:if test="${role eq 'student'}">code>
<a href="StuInitModifyServlet?username=${username}">修改信息</a>code>
</c:if>
<%--<%if("student".equals(role)){ %>--%>
<%--<!-- 在这个servlet通过username找到这个学生,再跳转到信息修改页面 -->--%>
<%--<a href="StuInitModifyServlet?username=<%=username%>">修改信息</a>--%>code>
<%--<%}%>--%>
<%--<%if("teacher".equals(role)){ %>--%>
<%--<a href="TeaInitModifyServlet?username=<%=username%>">修改信息</a>--%>code>
<%--<a href="GetStuListServlet?curPage=1">查看所有学生</a>--%>code>
<%--<%}%>--%>
<c:if test="${role eq 'teacher'}">code>
<a href="TeaInitModifyServlet?username=${usename}">修改信息</a>code>
<a href="GetStuListServlet?curPage=1">查看所有学生</a>code>
</c:if>
<script type="text/javascript">code>
function safeExit(){ -- -->
window.location = "SafeExitServlet";
}
</script>
</body>
</html>
8.安全退出(删Session、删Cookie)
删除账号所有信息 cookie,session
<button οnclick="safeExit()">安全退出</button>code>
<h1>详情页面</h1>
<h1>欢迎<%=name%><%=("student".equals(role))?"学员":""%><%=("teacher".equals(role))?"老师":""%>进入到学生管理系统</h1>
<script type="text/javascript">code>
function safeExit(){
window.location = "SafeExitServlet";
}
</script>
SafeExitServlet
package com.qf.Servlet;
import com.qf.utils.CookieUtils;
@WebServlet("/SafeExitServlet")
public class SafeExitServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//删除Cookie里的数据
//把时间设置为0,就是删除
response.addCookie(CookieUtils.createCookie("username","",0));
response.addCookie(CookieUtils.createCookie("name","",0));
response.addCookie(CookieUtils.createCookie("role","",0));
//删除Session里的数据
HttpSession session = request.getSession();
session.removeAttribute("username");
session.removeAttribute("name");
session.removeAttribute("role");
//跳转
response.sendRedirect("Welcome.html");
}
}
9.修改密码
index.jsp
<code><button onclick="safeExit()">安全退出</button>code>
<h1>详情页面</h1>
<h1>欢迎<%=name%><%=("student".equals(role))?"学员":""%><%=("teacher".equals(role))?"老师":""%>进入到学生管理系统</h1>
<a href="resetPassword.jsp">修改密码</a>code>
// ...省略
resetPassword.jsp
需要展示页面就要先获取session中的username
要用户输入原密码和新密码【对于为什么要原密码,就是在用户电脑在登录情况下被别人直接改密码】
注意1:对于ResetPasswordServlet查询用户对象,是需要username和role,怎么获取?
方案:在这个表单直接请求传过去(使用隐藏域),ResetPasswordServlet就可以在请求中取
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//从前端页面中取出来数据(当前页面没用,但是后面的ResetPasswordServlet有用)
String username = (String) session.getAttribute("username");
String role = (String) session.getAttribute("role");
//提示信息
String msg = (String) request.getAttribute("msg");
%>
<%=(msg!=null)?msg:""%>
<form action="ResetPasswordServlet" method="post">code>
//传入给后端ResetPasswordServlet
<!--隐藏域,不会在页面中展示,但是发送请求后会携带到后端-->
<input type="hidden" name="username" value="<%=username%>"/>code>
<input type="hidden" name="role" value="<%=role%>"/>code>
账号:<%=username%><br/>
原密码:<input type="password" name="password"/><br/>code>
新密码:<input type="password" name="newPassword"/><br/>code>
<input type="submit" value="修改"/>code>
<input type="button" value="返回" οnclick="goIndex()"/>code>
</form>
<script type="text/javascript">code>
function goIndex(){
window.location = "index.jsp";
}
</script>
</body>
</html>
ResetPasswordServlet
1.设置请求、响应编码格式
2.获取请求中的数据
3.通过username、password查询数据库中的用户对象
4.通过用户对象进行非空判断
用户存在,判断角色修改密码,注意要做安全退出【不然在有记住我的情况下,第二次登录直接进来】
用户不存在,设置提示修改密码失败信息,又转发方式跳转回到修改密码页面
package com.qf.Servlet;
@WebServlet("/ResetPasswordServlet")
public class ResetPasswordServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String newPassword = request.getParameter("newPassword");
String role = request.getParameter("role");
User user=null;
try {
//判断角色
if ("student".equals(role)) {
user= DBUtils.commonQueryObj(Student.class,"select * from student where username=? and password=?", username, password);
} else if ("teacher".equals(role)) {
user= DBUtils.commonQueryObj(Teacher.class,"select * from teacher where username=? and password=?", username, password);
}
if (user!=null){ //修改
if ("student".equals(role)){
DBUtils.commonUpdate("update student set password=? where username=?",newPassword,username);
} else if ("teacher".equals(role)) {
DBUtils.commonUpdate("update teacher set password=? where username=?",newPassword,username);
}
//修改密码成功后,做安全退出的功能
//修改密码了,相当于退出了
request.getRequestDispatcher("SafeExitServlet").forward(request,response);
}else { //修改密码失败--原密码不正确
request.setAttribute("msg","修改密码失败--原密码不正确");
request.getRequestDispatcher("resetPassword.jsp").forward(request,response);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
10.修改学生信息(StuInitModifyServlet、StuModifyServlet)
index.jsp
不能直接跳转到修改信息页面,因为拿不到session数据,需要中间页面StuInitModifyServlet(页面跳页面获取学生信息)
在路径中传username, 使StuInitModifyServlet可以拿到账号到数据库查询到改账号的学生信息
<h1>详情页面</h1>
<%if("student".equals(role)){%>
<!-- 在这个servlet通过username找到这个学生,再跳转到信息修改页面 -->
<a href="StuInitModifyServlet?username=<%=username%>">修改信息</a>code>
<%}%>
StuInitModifyServlet
操作:初始化修改学生数据
设置请求、响应编码格式获取请求中的数据从数据库中获取学生对象将学生对象存在请求中,转发方式到学生修改信息页面stuInfo.jsp
package com.qf.Servlet;
@WebServlet("/StuInitModifyServlet")
public class StuInitModifyServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
//从数据库中获取学生对象
Student student = null;
try {
student = DBUtils.commonQueryObj(Student.class, "select * from student where username=?", username);
} catch (SQLException e) {
throw new RuntimeException(e);
}
request.setAttribute("student",student);
request.getRequestDispatcher("stuInfo.jsp").forward(request,response);
}
}
stuInfo.jsp
对于没有学生信息,需要先到StuInitModifyServlet获取到学生对象,再获取其中信息,上传到stuInfo.jsp,用来修改页面展示和表单发送StuModifyServlet中的修改
注意:对性别和爱好的选择处理
<%@ page import="com.qf.pojo.Student" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Student student = (Student) request.getAttribute("student");
%>
<h1>学生修改信息页面</h1>
<form action="StuModifyServlet" method="post">code>
<input type="hidden" name="username" value="<%=student.getUsername()%>"/>code>
账号:<%=student.getUsername()%><br/>
姓名:<input type="text" name="name" value="<%=student.getName()%>"/><br/>code>
年龄:<input type="text" name="age" value="<%=student.getAge()%>"/><br/>code>
性别:
<input type="radio" name="sex" value="man" <%=(student.getSex().equals("man"))?"checked='checked'":""%>/>男code>
<input type="radio" name="sex" value="woman" <%=(student.getSex().equals("woman"))?"checked='checked'":""%>/>女code>
<br/>
爱好:
<input type="checkbox" name="hobbies" value="football" <%=(student.getHobbies().contains("football"))?"checked='checked'":""%>/>足球code>
<input type="checkbox" name="hobbies" value="basketball" <%=(student.getHobbies().contains("basketball"))?"checked='checked'":""%>/>篮球code>
<input type="checkbox" name="hobbies" value="shop" <%=(student.getHobbies().contains("shop"))?"checked='checked'":""%>/>购物code>
<br/>
<input type="submit" value="修改"/>code>
<input type="button" value="返回" οnclick="goIndex()"/>code>
</form>
<script type="text/javascript">code>
function goIndex(){
window.location = "index.jsp";
}
</script>
</body>
</html>
优化:
主要是jsp的EL和JSTL表达式的改进
<%@ page import="com.qf.pojo.Student" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>code>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--<%--%>
<%-- Student student = (Student) request.getAttribute("student");--%>
<%--%>--%>
<h1>学生修改信息页面</h1>
<form action="StuModifyServlet" method="post">code>
<input type="hidden" name="username" value="${student.username}"/>code>
账号:${student.username}<br/>
姓名:<input type="text" name="name" value="${student.name}"/><br/>code>
年龄:<input type="text" name="age" value="${student.age}"/><br/>code>
性别:
<input type="radio" name="sex" value="man" ${(student.sex eq 'man')?"checked='checked'":""}/>男code>
<input type="radio" name="sex" value="woman" ${(student.sex eq 'woman')?"checked='checked'":""}/>女code>
<br/>
爱好:
<input type="checkbox" name="hobbies" value="football" <c:if test="${fn:contains(student.hobbies, 'football')}">checked='checked'</c:if>/>足球code>
<input type="checkbox" name="hobbies" value="basketball" <c:if test="${fn:contains(student.hobbies, 'basketball')}">checked='checked'</c:if>/>篮球code>
<input type="checkbox" name="hobbies" value="shop" <c:if test="${fn:contains(student.hobbies, 'shop')}">checked='checked'</c:if>/>购物code>
<br/>
<input type="submit" value="修改"/>code>
<input type="button" value="返回" οnclick="goIndex()"/>code>
</form>
<script type="text/javascript">code>
function goIndex(){
window.location = "index.jsp";
}
</script>
</body>
</html>
StuModifyServlet(修改学生信息的逻辑)
1.设置请求、响应编码格式
2.获取请求中的数据
3.更新数据库里的学生数据
4.更新Session里的数据【原因:可能改名字,如果不改还是原来的名字就会在使用时出错】
5.更新Cookie里的数据【可存可不存,还是存一下,Cookie只有记住我才会有数据,name涉及凭证】
6.重定向方式跳转到详情页面index.jsp
package com.qf.Servlet;
@WebServlet("/StuModifyServlet")
public class StuModifyServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String age = request.getParameter("age");
String[] hobbies = request.getParameterValues("hobbies");
//更新数据库里的学生数据
try {
DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=? where username=?",name,sex,age, StringUtils.handleArray(hobbies),username);
} catch (SQLException e) {
throw new RuntimeException(e);
}
String role = (String) request.getSession().getAttribute("role");
if("student".equals(role)){
//更新Session里的数据
request.getSession().setAttribute("name",name);
//更新Cookie里的数据
response.addCookie(CookieUtils.createCookie("name",name,60*60*24*5));
//跳转详情页面
response.sendRedirect("index.jsp");
}else if("teacher".equals(role)){
//跳转
response.sendRedirect("GetStuListServlet?curPage=1");
}
}
}
11.修改老师信息(TeaInitModifyServlet、TeaModifyServlet)
详情页面 index.js
通过username拿到老师数据,交给request对象
<h1>详情页面</h1>
<%if("student".equals(role)){ %>
<!-- 在这个servlet通过username找到这个学生,再跳转到信息修改页面 -->
<a href="StuInitModifyServlet?username=<%=username%>">修改信息</a>code>
<%}%>
//省略
TeaInitModifyServle
操作:初始化修改老师数据
设置请求、响应编码格式获取请求中的数据从数据库中获取老师对象将老师对象和课程集合对象存在请求中,转发方式到老师修改信息页面teaInfo.jsp
package com.qf.Servlet;
@WebServlet("/TeaInitModifyServlet")
public class TeaInitModifyServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
//从数据库中获取相应的数据
Teacher teacher = null;
List<Course> courses = null;
try {
teacher = DBUtils.commonQueryObj(Teacher.class,"select * from teacher where username=?",username);
courses = DBUtils.commonQueryList(Course.class,"select * from course");
} catch (SQLException e) {
throw new RuntimeException(e);
}
//存入请求对象中
request.setAttribute("teacher",teacher);
request.setAttribute("courses",courses);
//跳转页面
request.getRequestDispatcher("teaInfo.jsp").forward(request,response);
}
}
teaInfo.jsp(老师修改信息页面)
需要先到TeaInitModifyServlet获取到老师对象,再获取其中信息,用来修改页面展示和表单发送TeaModifyServlet中的修改
注意:对性别和学科选择的处理
对于学科考虑到会新增的情况,不能写死,通过获取学科集合再遍历的方式进行选择展示
<%@ page import="com.qf.pojo.Teacher" %>code>
<%@ page import="java.util.List" %>code>
<%@ page import="com.qf.pojo.Course" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Teacher teacher = (Teacher) request.getAttribute("teacher");
List<Course> courses = (List<Course>) request.getAttribute("courses");
%>
<h1>老师修改信息页面</h1>
<form action="TeaModifyServlet" method="post">code>
<input type="hidden" name="username" value="<%=teacher.getUsername()%>"/>code>
账号:<%=teacher.getUsername()%><br/>
姓名:<input type="text" name="name" value="<%=teacher.getName()%>"/><br/>code>
年龄:<input type="text" name="age" value="<%=teacher.getAge()%>"/><br/>code>
性别:
<input type="radio" name="sex" value="man" <%=(teacher.getSex().equals("man"))?"checked='checked'":""%>/>男code>
<input type="radio" name="sex" value="woman" <%=(teacher.getSex().equals("woman"))?"checked='checked'":""%>/>女code>
<br/>
学科:
<select>
<%for(Course course:courses){ -- -->%>
<option value="<%=course.getId()%>" <%=(course.getId() == teacher.getCourseId())?"selected='selected'":""%> ><%=course.getName()%></option>code>
<%}%>
</select>
<br>
<input type="submit" value="修改"/>code>
<input type="button" value="返回" onclick="goIndex()"/>code>
</form>
<script type="text/javascript">code>
function goIndex(){ -- -->
window.location = "index.jsp";
}
</script>
</body>
</html>
优化:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>code>
<%@ page import="com.qf.pojo.Course" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--<%--%>
<%-- Teacher teacher = (Teacher) request.getAttribute("teacher");--%>
<%-- List<Course> courses = (List<Course>) request.getAttribute("courses");--%>
<%--%>--%>
<h1>老师修改信息页面</h1>
<form action="TeaModifyServlet" method="post">code>
<input type="hidden" name="username" value="${teacher.username}"/>code>
账号:${ -- -->teacher.username}<br/>
姓名:<input type="text" name="name" value="${teacher.name}"/><br/>code>
年龄:<input type="text" name="age" value="${teacher.age}"/><br/>code>
性别:
<input type="radio" name="sex" value="man" ${ -- -->(teacher.sex eq 'man')?"checked='checked'":""}/>男code>
<input type="radio" name="sex" value="woman" ${ -- -->(teacher.sex eq 'woman')?"checked='checked'":""}/>女code>
<br/>
学科:
<select name="courseId">code>
<c:forEach items="${courses}" var="course">code>
<option value="${course.id}" <c:if test="${course.id == teacher.courseId}">selected='selected'</c:if> >${ -- -->course.name}</option>code>
</c:forEach>
</select>
<br/>
<input type="submit" value="修改"/>code>
<input type="button" value="返回" onclick="goIndex()"/>code>
</form>
<script type="text/javascript">code>
function goIndex(){ -- -->
window.location = "index.jsp";
}
</script>
</body>
</html>
TeaModifyServlet
设置请求、响应编码格式
获取请求中的数据
更新数据库里的老师数据
更新Session里的数据【原因:可能改名字,如果不改还是原来的名字就会在使用时出错】
更新Cookie里的数据【可存可不存,还是存一下,Cookie只有记住我才会有数据,name涉及凭证】
重定向方式跳转到详情页面index.jsp
package com.qf.Servlet;
@WebServlet("/TeaModifyServlet")
public class TeaModifyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String age = request.getParameter("age");
String courseId = request.getParameter("courseId");
//更新数据库里的学生数据
try {
DBUtils.commonUpdate("update teacher set name=?,sex=?,age=?,courseId=? where username=?",name,sex,age, courseId,username);
} catch (SQLException e) {
throw new RuntimeException(e);
}
//更新Session里的数据
request.getSession().setAttribute("name",name);
//更新Cookie里的数据
response.addCookie(CookieUtils.createCookie("name",name,60*60*24*5));
response.sendRedirect("index.jsp");
}
}
12.老师角色查询所有学生
要用分页技术
index.jsp
不能直接跳stuList.jsp,没数据
TeaInitModifyServlet?username=<%=username%>:拼接一下,传数据
<code><h1>详情页面</h1>
<%if("teacher".equals(role)){ -- -->%>
<a href="TeaInitModifyServlet?username=<%=username%>">修改信息</a>code>
<a href="GetStuListServlet?curPage=1">查看所有学生</a>code>
<%}%>
</script>
</body>
</html>
GetStuListServlet
拿数据和分页
package com.qf.Servlet;
@WebServlet("/GetStuListServlet")
public class GetStuListServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取当前页数
int curPage = Integer.parseInt(request.getParameter("curPage"));
//设置当前页的数据条数
int count = 15;
//计算偏移量
int offset = (curPage-1)*count;
//计算总页数
int totalPage;
try {
int allCount = DBUtils.getAllCount("student");
if(allCount % count == 0){
totalPage = allCount/count;
}else{
totalPage = allCount/count + 1;
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
//从数据库获取学生的集合
List<Student> students = null;
try {
students = DBUtils.commonQueryList(Student.class, "select * from student limit ?,?", offset, count);
} catch (SQLException e) {
throw new RuntimeException(e);
}
//处理学生集合
List<StudentDto> studentDtos = DtoUtils.studentDtoListHandler(students);
//将数据存入到请求对象中
request.setAttribute("curPage",curPage);
request.setAttribute("totalPage",totalPage);
request.setAttribute("studentDtos",studentDtos);
//跳转
request.getRequestDispatcher("stuList.jsp").forward(request,response);
}
}
stuList.jsp,学生列表页面
添加学生信息处理后获取
<%@ page import="java.util.List" %>code>
<%@ page import="com.qf.pojo.Student" %>code>
<%@ page import="com.qf.dto.StudentDto" %>code>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
List<StudentDto> studentDtos = (List<StudentDto>) request.getAttribute("studentDtos");
int curPage = (int) request.getAttribute("curPage");
int totalPage = (int) request.getAttribute("totalPage");
%>
<button οnclick="doIndex()">返回</button>code>
<h1>学生列表页面</h1>
<table border="1" width="500px">code>
<tr>
<th>账号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>爱好</th>
<th>操作</th>
</tr>
//遍历,数据渲染
<%for (StudentDto studentDto:studentDtos){%>
<tr>
<th><%=studentDto.getStudent().getUsername()%></th>
<th><%=studentDto.getStudent().getName()%></th>
<th><%=studentDto.getSex()%></th>
<th><%=studentDto.getStudent().getAge()%></th>
<th><%=studentDto.getHobbies()%></th>
<th>
<a href="StuInitModifyServlet?username=<%=studentDto.getStudent().getUsername()%>">修改</a>code>
<a href="StuDeleteServlet?username=<%=studentDto.getStudent().getUsername()%>">删除</a>code>
</th>
</tr>
<%}%>
</table>
//分页
<a href="GetStuListServlet?curPage=1">首页</a>code>
//第一页的时候不能有上一页
<%if(curPage > 1){%>
<a href="GetStuListServlet?curPage=<%=curPage-1%>">上一页</a>code>
<%}%>
//最后一页的时候不能有下一页
<%if(curPage < totalPage){%>
<a href="GetStuListServlet?curPage=<%=curPage+1%>">下一页</a>code>
<%}%>
<a href="GetStuListServlet?curPage=<%=totalPage%>">尾页</a>code>
<script type="text/javascript">code>
function goIndex(){
window.location = "index.jsp";
}
</script>
</body>
</html>
DBUtils 数据库工具类
获取当前表的总条数
public static int getAllCount(String table) throws SQLException { -- -->
Connection connection = getConnection();
String sql = "select count(1) from " + table;
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();
if(resultSet.next()){
int allCount = resultSet.getInt(1);
return allCount;
}
return 0;
}
Student
做分页的假数据
public static void main(String[] args) {
for (int i = 10; i < 100; i++) {
String username = "xiaohei" + i;
String password = "123123";
String name = "小黑" + i;
String sex = "man";
int age = 23;
String[] hobbies = { "football", "basketball"};
try {
DBUtils.commonUpdate("insert into student(username,password,name,sex,age,hobbies) values(?,?,?,?,?,?)", username, password, name, sex, age, StringUtils.handleArray(hobbies));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
运行结果:
性别是man,爱好是英语,不方便观看,需要转成中文
包装学生类,写一个bto包,原来的student类不满足需求
分包新增信息处理类,以方便工具类对学生的信息处理
StudentDto
<code>package com.qf.dto;
public class StudentDto { -- -->
private Student student;
private String sex;
private String hobbies;
//无参构造,有参构造,get,set,toString类
}
写一个工具类
DtoUtils
工具类,处理学生信息提升页面展示效果 ,然后在GetStuListServlet里操作
package com.qf.utils;
public class DtoUtils {
public static StudentDto studentDtoHandler(Student student) {
//处理学生的性别数据
String sex = student.getSex();
if ("man".equals(sex)) {
sex = "男";
} else if ("woman".equals(sex)) {
sex = "女";
}
//处理学生的爱好数据(做替换)
String hobbies = student.getHobbies();
hobbies = hobbies.replaceAll("football", "足球");
hobbies = hobbies.replaceAll("basketball", "篮球");
hobbies = hobbies.replaceAll("shop", "购物");
//创建StudentDto
StudentDto studentDto = new StudentDto(student, sex, hobbies);
return studentDto;
}
public static List<StudentDto> studentDtoListHandler(List<Student> students){
ArrayList<StudentDto> studentDtos = new ArrayList<>();
for (Student student:students){
StudentDto studentDto = studentDtoHandler(student);
studentDtos.add(studentDto);
}
return studentDtos;
}
}
12.1 优化分页
GetStuListServlet
多了一个这个:设置URL:String url = “GetStuListServlet?curPage=”;
package com.qf.Servlet;
@WebServlet("/GetStuListServlet")
public class GetStuListServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取当前页数
int curPage = Integer.parseInt(request.getParameter("curPage"));
//设置URL
String url = "GetStuListServlet?curPage=";
//设置当前页的数据条数
int count = 15;
//计算偏移量
int offset = (curPage-1)*count;
//计算总页数
int totalPage;
try {
int allCount = DBUtils.getAllCount("student");code>
if(allCount % count == 0){ -- -->
totalPage = allCount/count;
}else{
totalPage = allCount/count + 1;
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
//从数据库获取学生的集合
List<Student> students = null;
try {
students = DBUtils.commonQueryList(Student.class, "select * from student limit ?,?", offset, count);
} catch (SQLException e) {
throw new RuntimeException(e);
}
//处理学生集合
List<StudentDto> studentDtos = DtoUtils.studentDtoListHandler(students);
//封装Page对象
Page<StudentDto> page = new Page<>(url, curPage, totalPage, studentDtos);
//将数据存入到请求对象中
request.setAttribute("page",page);
//跳转
request.getRequestDispatcher("stuList.jsp").forward(request,response);
}
}
上面的请求对象太多了,同一设置一个page类
原来是这个:
//将数据存入到请求对象中
request.setAttribute(“curPage”,curPage);
request.setAttribute(“totalPage”,totalPage);
request.setAttribute(“studentDtos”,studentDtos);
package com.qf.pojo;
public class Page<T> {
private String url;
private int curPage;
private int totalPage;
private List<T> list;
//省略
page.jsp
把分页放在外面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>code>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>code>
<a href="${page.url}1">首页</a>code>
<c:if test="${page.curPage > 1}">code>
<a href="${page.url}${page.curPage-1}">上一页</a>code>
</c:if>
<c:if test="${page.curPage < page.totalPage}">code>
<a href="${page.url}${page.curPage+1}">下一页</a>code>
</c:if>
<a href="${page.url}${page.totalPage}">尾页</a>code>
13.老师角色操作学生的修改
学生的修改写了的,就是StuInitModifyServlet
stuList.jsp
<%for (StudentDto studentDto:studentDtos){ -- -->%>
<tr>
<th><%=studentDto.getStudent().getUsername()%></th>
<th><%=studentDto.getStudent().getName()%></th>
<th><%=studentDto.getSex()%></th>
<th><%=studentDto.getStudent().getAge()%></th>
<th><%=studentDto.getHobbies()%></th>
<th>
<a href="StuInitModifyServlet?username=<%=studentDto.getStudent().getUsername()%>">修改</a>code>
<a href="StuDeleteServlet?username=<%=studentDto.getStudent().getUsername()%>">删除</a>code>
</th>
</tr>
<%}%>
StuInitModifyServlet,跳转到StuModifyServlet
获取角色
1.通过角色判断修改
2.学生需要更新Session、Cookie里的数据,跳转详情页面
3.老师跳转GetStuListServlet,需要更新数据【因为修改了需要刷新页面】
(老师这里不需要修改cookie和session,最后一步不一样)
package com.qf.Servlet;
@WebServlet("/StuModifyServlet")
public class StuModifyServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求、响应编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取请求中的数据
String username = request.getParameter("username");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String age = request.getParameter("age");
String[] hobbies = request.getParameterValues("hobbies");
//更新数据库里的学生数据
try {
DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=? where username=?",name,sex,age, StringUtils.handleArray(hobbies),username);
} catch (SQLException e) {
throw new RuntimeException(e);
}
String role = (String) request.getSession().getAttribute("role");
if("student".equals(role)){
//更新Session里的数据
request.getSession().setAttribute("name",name);
//更新Cookie里的数据
response.addCookie(CookieUtils.createCookie("name",name,60*60*24*5));
//跳转详情页面
response.sendRedirect("index.jsp");
}else if("teacher".equals(role)){
//跳转
response.sendRedirect("GetStuListServlet?curPage=1");
}
}
}
14.老师角色操作学生的删除
stuList.jsp
<h1>学生列表页面</h1>
<%for (StudentDto studentDto:studentDtos){%>
<tr>
<th><%=studentDto.getStudent().getUsername()%></th>
<th><%=studentDto.getStudent().getName()%></th>
<th><%=studentDto.getSex()%></th>
<th><%=studentDto.getStudent().getAge()%></th>
<th><%=studentDto.getHobbies()%></th>
<th>
<a href="StuInitModifyServlet?username=<%=studentDto.getStudent().getUsername()%>">修改</a>code>
<a href="StuDeleteServlet?username=<%=studentDto.getStudent().getUsername()%>">删除</a>code>
</th>
</tr>
<%}%>
</table>
</body>
</html>
StuDeleteServlet
设置编码格式,获取请求中的账号,通过学生账号删除学生,最后跳转GetStuListServlet同时更新数据
注意:实际开发项目中是不会直接用delete,而是改状态,数据库有提到
package com.qf.Servlet;
@WebServlet("/StuDeleteServlet")
public class StuDeleteServlet extends HttpServlet { -- -->
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
try {
DBUtils.commonUpdate("delete from student where username=?",username);
} catch (SQLException e) {
throw new RuntimeException(e);
}
//跳转
response.sendRedirect("GetStuListServlet?curPage=1");
}
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。