案例:WEB版学生管理系统

Day37

综合案例

http请求方式有哪些?

GET:请求指定的页面信息,并返回实体主体。这是最常见的请求方式,用于从服务器获取数据。
HEAD:类似于GET请求,只不过返回的响应中没有具体的内容,只有报文头,用于获取报文头信息。
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT:从客户端向服务器传送的数据取代指定的文档的内容。
DELETE:请求服务器删除指定的页面。
CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS:允许客户端查看服务器的性能。
TRACE:回显服务器收到的请求,主要用于测试或诊断。
PATCH:对PUT方法的补充,用来对已知资源进行局部更新。
这些请求方式各有其用途,例如GET和POST是最常用的两种请求方式,其中GET用于获取数据,而POST用于提交数据。其他请求方式如PUT、DELETE等则用于更新或删除服务器上的资源。

WEB版学生管理系统

注册

拿到项目先做需求分析:

用户角色:登录(验证码、记住我)、安全退出、修改密码

学生角色:注册、修改信息

老师角色:修改信息、查询所有学生(分页查询)、修改学生信息、删除学生信息

数据库搭建:

​ 创建表:学生表(username、password、name、sex、age、hobbies)

​ 老师表(username、password、name、courseId)

​ 学科表(id、name)

项目搭建:

​ 导包(servlet、sql、druid),导入会有路径问题,在problem那里查看解决。

​ 创建包:utils(需要放入properties文件)、pojo、servlet。

​ 写前端页面:两个超链接:一个是登录(写login.html),一个是注册(register.html)。登录有验证码、记住我、返回等。

欢迎页面:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <welcome-file-list>
        <welcome-file>welcome.html</welcome-file>
    </welcome-file-list>
</web-app>

登录页面:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
            background: #f0f0f0;
        }
    </style>
</head>
<body>
<div>
    <form action="LoginServlet" method="post">
        <h2>欢迎来到登录界面</h2><br/>
        <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="userCode" /><img  width="120px" height="30px"><a href="#" onclick="flushCode()">刷新</a><br />
                </td>
            </tr>
            <tr>
                <td>
                    角色:<input type="radio" name="role" value="student"/>学生
                    <input type="radio"name="role" value="teacher"/>老师
                </td>
            </tr>
            <tr>
                <td>
                    记住我:<input type="checkbox" name="rememberMe"/><br/>
                </td>
            </tr>
            <tr>
                <td>
                    <input type="submit" value="登录"/>
                </td>
            </tr>

        </table>
    </form>
</div>
<script type="text/javascript">
    
    function flushCode(){
        
    }
</script>
</body>
</html>

注册页面:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
            background: #f0f0f0;
        }
    </style>
</head>
<body>

<form action="RegisterServlet" method="post">
    <h2>欢迎来到注册页面</h2>
    <br/>
    账号:<input type="text" name="username" /><br />
    密码:<input type="password" name="password" /><br />
    姓名:<input type="text" name="name" /><br />
    年龄:<input type="text" name="age" /><br />
    性别:
    <input type="radio" name="sex" value="man" checked="checked"/><input type="radio" name="sex" value="woman"/><br />
    爱好:
    <input type="checkbox" name="hobbies" value="football" checked="checked"/>足球
    <input type="checkbox" name="hobbies" value="basketball" />篮球
    <input type="checkbox" name="hobbies" value="shop" />购物
    <br />

    <input type="submit" value="注册" />
    <button type="button" onclick="fun01()">返回</button>
</form>

<script type="text/javascript">
    function fun01(){
        window.location = "welcome.html";
    }
</script>

</body>
</html>

写实体类pojo:

​ User类:属性(表内字段)、构造方法、getset()、toString()

​ Student类继承User:属性、构造(有参选择父类有参)、getset、toString

​ Teacher类继承User:属性、构造()、getset、toString()

​ Course类:属性、构造、getset、toString()

package com.qf.pojo;

public class User {
    private String username;
    private String password;
    private String name;

    public User() {
    }

    public User(String username, String password, String name) {
        this.username = username;
        this.password = password;
        this.name = name;
    }

    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 getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
package com.qf.pojo;

public class Student extends User{
    private String sex;
    private int age;
    private String hobbies;

    public Student(String username, String password, String name, String sex, int age, String hobbies) {
        super(username, password, name);
        this.sex = sex;
        this.age = age;
        this.hobbies = hobbies;
    }

    public Student() {
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHobbies() {
        return hobbies;
    }

    public void setHobbies(String hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sex='" + sex + '\'' +
                ", age=" + age +
                ", hobbies='" + hobbies + '\'' +
                "} " + super.toString();
    }
}
package com.qf.pojo;

public class Teacher extends User{
    private int courseId;

    public Teacher(String username, String password, String name, int courseId) {
        super(username, password, name);
        this.courseId = courseId;
    }

    public Teacher() {
    }

    public int getCourseId() {
        return courseId;
    }

    public void setCourseId(int courseId) {
        this.courseId = courseId;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "courseId=" + courseId +
                "} " + super.toString();
    }
}
package com.qf.pojo;

public class Course {
    private int id;
    private String name;

    public Course() {
    }

    public Course(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

​ 写RegisterServlet类,继承HttpServlet,注释,设置编码格式,获取请求中的数据,将获取的数据封装成一个对象(打印一下查看是否获取到数据),注意其中的hobbies要转换为String,age要从String转换为Integer。再判断账号是否存在,用commonQueryObj方法返回对象,如果等于null,就允许注册,插入sql语句,然后跳转到登录页面。如果非空进行提示。

(优化:获取数据这个过程getParameter()太冗杂,用request.getParameterMap()方法,放的是字段和字段数组。

写一个将数组转换为String的工具类StringUtil,静态方法parseString(Object[] objs),用StringBuffer来添加数组内容,不要用Arrays.toString,因为会带有中括号。

package com.qf.utils;

public class StringUtil {
    public static String parseString(Object[] objs){
        StringBuffer sb = new StringBuffer();
        for(Object obj :objs){
            if(sb.length()!=0){
                sb.append(",");
            }
            sb.append(obj);
        }
        return sb.toString();
    }
}

写一个工具类BeanUtil:

编写getField方法获取本类及其父类属性对象;

编写setProperty(Object bean,String name,Object value)方法设置属性,注意这里的key,value可能是字符串数组,要加判断,使用编写的StringUtil的方法把字符串数组转换为字符串。并进行set设置;

编写getProperty(Object bean,String name)方法获取本类及父类的属性值;

编写无返回值的populate(Object bean,Map<String,String[]> properties)方法,把字段数组放入对象中。(request.getParameterMap()方法返回的键都是String,值都是String[])

package com.qf.utils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;

public class BeanUtil {
    /**
     * 获取本类及其父类的属性对象
     * @param clazz
     * @param name
     * @return
     */
    public static Field getField(Class<?> clazz,String name) {

        for(Class<?> c=clazz;c!=null;c=c.getSuperclass()){
            try {
                return c.getDeclaredField(name);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    /**
     * 获取对象及其父类对象的属性值
     * @param bean
     * @param name
     * @return
     */
    public static Object getProperty(Object bean,String name){
        Class<?> clazz = bean.getClass();
        Field field = getField(clazz, name);
        if(field==null){
            return null;
        }
        field.setAccessible(true);
        try {
            Object fieldVal = field.get(bean);
            return fieldVal;
        } catch (IllegalAccessException e) {
            //这里不能处理,否则找不到父类属性!!!
        }
    }

    /**
     * 设置对象属性
     * @param bean
     * @param name
     * @param value
     */
    public static void setProperty(Object bean,String name,Object value){
        Class<?> clazz = bean.getClass();
        Field field = getField(clazz, name);
        if(field==null){
            return;
        }
        field.setAccessible(true);
        try {
            if(field.getType()==String.class){
                if(value.getClass()==String[].class){
                    String[] ss= (String[]) value;
                    String str = StringUtil.parseString(ss);

                    field.set(bean,str);
                }
            }
            if(field.getType()==String[].class){
                if(value.getClass()==String[].class){
                    String[] ss = (String[]) value;
                    field.set(bean,ss);
                }
            }
            if(field.getType()==int.class){
                if(value.getClass()==String[].class){
                    String[] ss = (String[]) value;
                    String str = StringUtil.parseString(ss);
                    int num = Integer.parseInt(str);
                    field.set(bean,num);
                }
            }
        }catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
    public static void populate(Object bean, Map<String,String[]> properties){
        Set<Map.Entry<String, String[]>> entries = properties.entrySet();
        for(Map.Entry<String, String[]> entry:entries){
            String key = entry.getKey();
            String[] value = entry.getValue();
            setProperty(bean,key,value);
        }
    }
}

DButil里面添加commonQueryObj()方法返回单个对象。思路为调用commonQueryList()方法,进行内容判断。)

package com.qf.utils;

import com.alibaba.druid.pool.DruidDataSource;

import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class DBUtil {

    //druid数据库连接池
    private static DruidDataSource pool;

    static{

        Properties properties = new Properties();
        try {
            properties.load(DBUtil.class.getClassLoader().getResourceAsStream("DBConfig.properties"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String driverName = properties.getProperty("driverName");
        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(driverName);
        pool.setUrl(url);
        pool.setUsername(username);
        pool.setPassword(password);
        pool.setMaxActive(maxActive);

        local = new ThreadLocal<>();
    }

    private static ThreadLocal<Connection> local;

    /**
     * 开启事务
     */
    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 = null;
        }
    }

    /**
     * 回滚事务
     */
    public static void rollback() throws SQLException {
        Connection connection = local.get();
        if(connection != null){
            connection.rollback();
            connection = null;
        }
    }


    /**
     * 获取连接对象
     */
    public static Connection getConnection() throws SQLException {
        Connection connection = local.get();
        if(connection == null){
            connection = pool.getConnection();

            //设置事务的隔离界别
            connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);

            local.set(connection);
        }
        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 int commonUpdate(String sql,Object... params) throws SQLException {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            paramsHandler(statement,params);

            int num = statement.executeUpdate();
            return num;
        } finally {
            close(connection,statement,null);
        }
    }

    /**
     * 主键回填
     */
    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);
            paramsHandler(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, InstantiationException, IllegalAccessException {

        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            paramsHandler(statement,params);

            resultSet = statement.executeQuery();

            //获取表信息对象
            ResultSetMetaData metaData = resultSet.getMetaData();
            //获取字段个数
            int fieldCount = metaData.getColumnCount();

            List<T> list = new ArrayList<>();

            while(resultSet.next()){

                //创建对象
                T t = clazz.newInstance();

                for (int i = 1; i <= fieldCount ; i++) {
                    //获取字段名
                    String fieldName = metaData.getColumnName(i);
                    //获取该数据行上对应字段的数据
                    Object val = resultSet.getObject(fieldName);
                    //利用反射设置对象里对应的属性
                    setField(t,fieldName,val);
                }

                //将对象添加到List集合中
                list.add(t);
            }

            return list;
        } finally {
            close(connection,statement,resultSet);
        }
    }
    /**
     * 查询单个对象
     */
    public static <T> T commonQueryObj(Class<T> clazz,String sql,Object... params) throws SQLException, InstantiationException, IllegalAccessException {
        List<T> list = commonQueryList(clazz, sql, params);
        if(list.isEmpty()){
            return null;
        }
        T t = list.get(0);
        return t;
    }
    /**
     * 处理sql命令中的参数
     */
    private static void paramsHandler(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();
            }
        }
    }

}

RegisterServlet:

package com.qf.servlet;

import com.qf.pojo.Student;
import com.qf.utils.BeanUtil;
import com.qf.utils.DBUtil;

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 java.io.IOException;
import java.sql.SQLException;
import java.util.Map;

@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");
        Map<String, String[]> parameterMap = request.getParameterMap();
        Student stu = new Student();
        BeanUtil.populate(stu,parameterMap);
        //判断账号是否存在
        try {
            Student student = DBUtil.commonQueryObj(stu.getClass(),"select * from student where username=?",stu.getUsername());
            if(student==null){
                //允许注册
                String insertSql="insert into student(username,password,name,age,sex,hobbies) values(?,?,?,?,?,?)";
                DBUtil.commonInsert(insertSql,stu.getUsername(),stu.getPassword(),stu.getName(),stu.getAge(),stu.getSex(),stu.getHobbies());
                response.sendRedirect("login.html");
            }else{
                //不允许注册
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
登录

LoginServlet编写:
设置编码格式,获取请求里的数据,但是无法封装成对象,因为数据是杂乱的,有账号、密码、验证码、角色、记住我。

获取数据后先判断角色,建议颠倒写法,如if(“student”.equals(role)),防止传入数据为空导致空指针异常,然后传入sql语句调用工具类相关方法进行查询。

再利用多态的思想,判断user是否为空,如果为空跳转注册,不为空跳转登录。

package com.qf.servlet;

import com.qf.pojo.Student;
import com.qf.pojo.Teacher;
import com.qf.pojo.User;
import com.qf.utils.DBUtil;

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 java.io.IOException;
import java.sql.SQLException;

@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");

        User user = new User();
        //判断角色并获取相应角色的数据

        try {
            if("student".equals(role)) {
                String sql = "select * from student where username=? and password = ?";
                user = DBUtil.commonQueryObj(Student.class, sql, username, password);
            }else if("teacher".equals(role)){
                String sql = "select * from teacher where username=? and password = ?";
                user = DBUtil.commonQueryObj(Teacher.class,sql,username,password);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(user!=null){
            //有相关数据,登录成功
            response.sendRedirect("index.html");
        }else{
            //登录失败
            response.sendRedirect("welcome.html");
        }
    }
}
验证码

验证码功能:防止恶意登录(利用代码循环机器登录)。

获取验证码通过CodeServlet在后端发送,因为前端可以看到代码,所以放在后端安全性更高。

绘制验证码:

CodeServlet:

画一张验证码,传回前端。步骤:设置画布,填充颜色,获取画笔,设置画笔颜色,填充矩形(和前端验证码框大小一致),画笔位置改变,用其他颜色做适量的干扰线,最后将图片传回给客户端。

package com.qf.servlet;

import javax.imageio.ImageIO;
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 java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@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 ran = new Random();
        String[] codes = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0"};
        Color[] colors={Color.cyan,Color.RED,Color.PINK,Color.GREEN};
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<4;i++){
            //设置字体格式
            graphics.setFont(new Font("宋体",Font.BOLD,20+ran.nextInt(10)));
            //设置字体颜色
            graphics.setColor(colors[ran.nextInt(colors.length)]);
            //绘制单个字体
            String code = codes[ran.nextInt(codes.length)];
            sb.append(code);
            graphics.drawString(code,20+20*i,20+ran.nextInt(10));
        }
        //绘制干扰线
        graphics.setColor(Color.YELLOW);
        for(int i=0;i<3;i++){
            graphics.drawLine(ran.nextInt(width), ran.nextInt(height), ran.nextInt(width), ran.nextInt(height));
        }
        //把验证码图片返回客户端
        ImageIO.write(image,"jpg",response.getOutputStream());
    }
}
刷新展示验证码:

在login.html里设置

浏览器有保护机制,不能重复发相同的请求,所以可以利用时间发送不同名字的请求。

<tr>
              <td>
                  验证码:<input type="text" name="userCode" /><img  id="code" src="CodeServlet" width="120px" height="30px"><a href="#" onclick="flushCode()">刷新</a><br />
              </td>
          </tr>


<script type="text/javascript">
        var code=document.getElementById("code");
        function flushCode(){
            code.src="CodeServlet?"+ new Date();
        }
    </script>
判断验证码

设置静态属性sysCode

思路:在CodeServlet里返回,在LoginServlet里去获取,并判断是否相同。但是会出现问题:多个浏览器连接验证码会冲突。

解决方案:不同的浏览器同时连接服务器,会产生不同的会话对象HttpSession,应该把系统生成的验证码设置到Session中,然后在LoginServlet中利用响应获取验证码。

CodeServlet中:

//将系统生成的验证码设置到session中
        HttpSession session = request.getSession();
        session.setAttribute("Syscode",sb.toString());

LoginServlet获取并用来和获取的登录信息中验证码填写比较:

String sysCode= (String) request.getSession().getAttribute("Syscode");
        User user = new User();
        //判断角色并获取相应角色的数据
        if(sysCode.equalsIgnoreCase(userCode)){
            try {
                if("student".equals(role)) {
                    String sql = "select * from student where username=? and password = ?";
                    user = DBUtil.commonQueryObj(Student.class, sql, username, password);
                }else if("teacher".equals(role)){
                    String sql = "select * from teacher where username=? and password = ?";
                    user = DBUtil.commonQueryObj(Teacher.class,sql,username,password);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            if(user!=null){
                //有相关数据,登录成功
                response.sendRedirect("index.html");
            }else{
                //登录失败
                response.sendRedirect("welcome.html");
            }
        }
登录、注册失败提示

JSP—Java Server Page Java服务页面

理解:可以写HTML+Java代码

在不允许注册里:

请求里存储会话域数据,将数据设置到请求对象中

将register.html删掉,换成register.jsp

jsp中写java代码格式:<% //Java代码 %>

package com.qf.servlet;

import com.qf.pojo.Student;
import com.qf.utils.BeanUtil;
import com.qf.utils.DBUtil;

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 java.io.IOException;
import java.sql.SQLException;
import java.util.Map;

@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");
        Map<String, String[]> parameterMap = request.getParameterMap();
        Student stu = new Student();
        BeanUtil.populate(stu,parameterMap);
        //判断账号是否存在
        try {
            Student student = DBUtil.commonQueryObj(stu.getClass(),"select * from student",stu.getUsername());
            if(student==null){
                //允许注册
                String insertSql="insert into student(username,password,name,age,sex,hobbies) values(?,?,?,?,?,?)";
                DBUtil.commonInsert(insertSql,stu.getUsername(),stu.getPassword(),stu.getName(),stu.getAge(),stu.getSex(),stu.getHobbies());
                response.sendRedirect("login.jsp");
            }else{
                //不允许注册
                //将信息设置到session里面
                request.setAttribute("msg","注册失败,已有该账号");
                request.getRequestDispatcher("register.jsp").forward(request,response);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
<%--
  Created by IntelliJ IDEA.
  User: Gu
  Date: 2024-06-13
  Time: 18:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
            background: #f0f0f0;
        }
    </style>
</head>
<body>
    <%
        //从请求对象中获取数据
        String msg = (String) request.getSession().getAttribute("msg");
    %>
    <%= (msg!=null)?msg:"" %>

<form action="RegisterServlet" method="post">
    <h2>欢迎来到注册页面</h2>
    <br/>
    账号:<input type="text" name="username" /><br />
    密码:<input type="password" name="password" /><br />
    姓名:<input type="text" name="name" /><br />
    年龄:<input type="text" name="age" /><br />
    性别:
    <input type="radio" name="sex" value="man" checked="checked"/>男
    <input type="radio" name="sex" value="woman"/>女
    <br />
    爱好:
    <input type="checkbox" name="hobbies" value="football" checked="checked"/>足球
    <input type="checkbox" name="hobbies" value="basketball" />篮球
    <input type="checkbox" name="hobbies" value="shop" />购物
    <br />

    <input type="submit" value="注册" />
    <button type="button" οnclick="fun01()">返回</button>
</form>

<script type="text/javascript">
    function fun01(){
        window.location = "welcome.html";
    }
</script>

</body>
</html>

注意:放在请求里的数据不能用重定向,因为会发送两次请求,数据会重置。

登录同理,login.html改为login.jsp。

package com.qf.servlet;

import com.qf.pojo.Student;
import com.qf.pojo.Teacher;
import com.qf.pojo.User;
import com.qf.utils.DBUtil;

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 java.io.IOException;
import java.sql.SQLException;

@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");
        User user = new User();
        //判断角色并获取相应角色的数据
        if(sysCode.equalsIgnoreCase(userCode)){
            try {
                if("student".equals(role)) {
                    String sql = "select * from student where username=? and password = ?";
                    user = DBUtil.commonQueryObj(Student.class, sql, username, password);
                }else if("teacher".equals(role)){
                    String sql = "select * from teacher where username=? and password = ?";
                    user = DBUtil.commonQueryObj(Teacher.class,sql,username,password);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            if(user!=null){
                //有相关数据,登录成功
                response.sendRedirect("index.html");
            }else{
                //登录失败 --账号或密码错误
                request.setAttribute("msg","登录失败,账号或密码错误");
                request.getRequestDispatcher("login.jsp").forward(request,response);
            }

        }else{
            //登录失败--验证码错误
            request.setAttribute("msg","登录失败,验证码错误");
            request.getRequestDispatcher("login.jsp").forward(request,response);
        }

    }
}
<%--
  Created by IntelliJ IDEA.
  User: Gu
  Date: 2024-06-13
  Time: 18:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
            background: #f0f0f0;
        }
    </style>
</head>
<body>
    <%
        String msg= (String) request.getSession().getAttribute("msg");
    %>
    <%= (msg!=null)?msg:"" %>
<div>
    <form action="LoginServlet" method="post">
        <h2>欢迎来到登录界面</h2><br/>
        <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="userCode" /><img  id="code" src="CodeServlet" width="120px" height="30px"><a href="#" οnclick="flushCode()">刷新</a><br />
                </td>
            </tr>
            <tr>
                <td>
                    角色:<input type="radio" name="role" value="student"/>学生
                    <input type="radio"name="role" value="teacher"/>老师
                </td>
            </tr>
            <tr>
                <td>
                    记住我:<input type="checkbox" name="rememberMe"/><br/>
                </td>
            </tr>
            <tr>
                <td>
                    <input type="submit" value="登录"/>
                </td>
            </tr>

        </table>
    </form>
</div>
<script type="text/javascript">
    var code=document.getElementById("code");
    function flushCode(){
        code.src="CodeServlet?"+ new Date();
    }
</script>
</body>
</html>

  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值