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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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) {throw new RuntimeException(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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected 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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected 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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected 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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected 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: GuDate: 2024-06-13Time: 18:43To 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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected 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: GuDate: 2024-06-13Time: 18:43To 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>