最近系统的学习了关于Servlet的相关知识,主要包括Http的Request与Response、Cookie、Session、JSP等,结合前期的JDBC中的数据库连接池Druid、JdbcTemplate等内容简单实现一个含有动态生成随机验证码的表单登录JSP页面。
第一部分 登录界面JSP编写
重点:
form的action与method指定
运用时间戳解决image的src路径切换问题
使用三目运算符解决输出null字符串问题
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>登录页面title> <style> #ta{ margin: auto; padding-top: 50px; } div{ color: red; text-align: center; }style> <script> window.onload = function () { document.getElementById("img").onclick = function () { this.src = "/Demo/checkCode?time="+new Date().getTime(); } }script>head><body> <form action="/Demo/loginServlet" method="post"> <table id="ta"> <tr> <td>用户名td> <td><input type="text" name="username" placeholder="请输入用户名">td> tr> <tr> <td>密码td> <td><input type="text" name="password" placeholder="请输入密码">td> tr> <tr> <td>验证码td> <td><input type="text" name="checkCode">td> tr> <tr align="center"> <td colspan="2"><img id="img" src="/Demo/checkCode">td> tr> <tr align="center"> <td colspan="2"><input type="submit" value="登录">td> tr> table> form> <%--给出相关登陆失败的提示信息--%> <%--结合三目运算符去掉null的显示--%> <div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error")%>div> <div><%=request.getAttribute("checkCode_error") == null ? "" : request.getAttribute("checkCode_error")%>div>body>html>
第二部分 创建数据库(以MySQL为例)
第三部分
1、封装数据表
package JavaEE.Web.Domain;/** * 用户的实体类:User * 封装User表 */public class User { // 根据User表中的属性写出来 private Integer id; private String username; private String password; public User() { } public User(Integer id, String username, String password) { this.id = id; this.username = username; this.password = password; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; }}
2、自定义JDBC工具类,使用Druid连接池技术优化连接
package JavaEE.Web.Util;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.FileReader;import java.io.IOException;import java.sql.Connection;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;/** * JDBC工具类,使用Durid数据库连接池 */public class JDBCUtils { // 1、定义成员变量 private static DataSource ds; private static Properties pro = null; // 静态代码块 static { try { // 2、加载配置文件 pro = new Properties(); String path = JDBCUtils.class.getClassLoader().getResource("druid1.properties").getPath(); pro.load(new FileReader(path)); // 3、获取DataSource对象 ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } // 从连接池中拿取连接对象的方法 public static Connection getConnection() throws SQLException { return ds.getConnection(); } // 向连接池里归还连接对象的方法【一】 public static void close(Statement sta , Connection conn){ if (sta != null){ try { sta.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 获取数据库连接池的方法 public static DataSource getDataSource(){ return ds; }}
3、创建数据表间接操纵类,封装实现查询方法
package JavaEE.Web.DAO;import JavaEE.Web.Domain.User;import JavaEE.Web.Util.JDBCUtils;import org.springframework.dao.DataAccessException;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;/** * 操作数据库中User表的类 */public class UserDAO { // 声明JDBCTemplate对象共用 private JdbcTemplate jdbcTemplate= new JdbcTemplate(JDBCUtils.getDataSource()); /** * 登录方法 * @param loginUser 只有用户名和密码 * @return 包含用户全部数据,没有查询到返回null */ public User login(User loginUser){ try { // 1、编写sql语句 String sql = "select * from USER where username = ? and password = ? "; // 2、调用query查询方法 User userValue = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(User.class), loginUser.getUsername(), loginUser.getPassword()); return userValue; }catch (DataAccessException e){ e.printStackTrace(); return null; } }}
第四部分 实现验证码的动态随机生成与刻画
重点:
验证码图片干扰线的刻画、坐标设计问题
随机验证码生成后的获取与存储
package JavaEE.Web.Session5.SessionTest;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 javax.servlet.http.HttpSession;import java.awt.*;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random;@WebServlet("/checkCode")public class CheckCode extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int image_Width = 90; int image_Height = 40; // 1、创建一个对象,在内存中图片存在(验证码的图片对象) BufferedImage image = new BufferedImage(image_Width,image_Height,BufferedImage.TYPE_INT_RGB); // 使用 BufferedImage 对象在内存中写图片并设置图片长、宽、类型 // 2、美化图片 // 2.1 填充背景色 Graphics graphics = image.getGraphics(); // 获取画笔对象 graphics.setColor(Color.LIGHT_GRAY); // 设置画笔的颜色 graphics.fillRect(0,0,image_Width,image_Height); // 填充 【这个x:0,y:0的坐标点表示图片的左上角的那个点,并以这个点画imageWidth宽度和imageHeight高度】 // 2.2 画边框 graphics.setColor(Color.BLUE); // 设置边框工具颜色 graphics.drawRect(0,0,image_Width-1,image_Height-1); // 画边框 /** * 随机生成验证码 */ // 规定要随机的验证码包括哪些字符 String randomChar = "ABCDEFGHIJKMLNOPQRSTUVWXYZabcdefghijkmlnopqrstuvwxyz0123456789"; // 生成随机下标 Random random = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 1; i <= 4; i++) { // 4用来控制要生成几个字符的验证码 int index = random.nextInt(randomChar.length()); // 随机获取一个下标 // 获取该下标值对应的字符 char ch = randomChar.charAt(index); // 获取到随机字符 // 每生成一个字符,将字符存起来★ sb.append(ch); // 2.3 写验证码 graphics.setColor(Color.MAGENTA); // 设置字符颜色 graphics.drawString(ch+"",image_Width/5*i,image_Height/2); // 在图片上写个字母“A”,规定它的坐标位置为(20,25) } String checkCode_session = sb.toString(); // 程序随机生成的验证码 // 使用Session存起来 // 获取Session对象 HttpSession session = request.getSession(); // 存储数据---程序随机生成的验证码 session.setAttribute("checkCode_session",checkCode_session); // 2.4 画干扰线 for (int j = 0; j < 4; j++) { // 共画4条线 // 随机生成坐标点 int X1 = random.nextInt(image_Width); int Y1 = random.nextInt(image_Height); int X2 = random.nextInt(image_Width); int Y2 = random.nextInt(image_Height); graphics.setColor(Color.GREEN); // 设置线条的颜色 graphics.drawLine(X1,Y1,X2,Y2); // 两个端点的坐标分别为:(x1,y1)、(x2,y2) } // 3、将图片输出到页面展示 /** * 参数中依次为:要写到页面上的图片对象、图片的后缀名、字节输出流 */ ImageIO.write(image,"jpg",response.getOutputStream()); // 使用 ImageIO 对象将内存中的图片通过流写到页面上 } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); }}
第五部分 JSP与Servlet编写
1、表单逻辑判断
重点:
使用session一次性存储和使用验证码
用户名、密码、验证码的一致性比对与逻辑判断
转发与重定向的使用
package JavaEE.Web.Session5.SessionTest;import JavaEE.Web.DAO.UserDAO;import JavaEE.Web.Domain.User;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;import java.util.Map;@WebServlet("/loginServlet")public class loginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1、设置编码格式 request.setCharacterEncoding("utf-8"); // 2、获取表单中的参数 String username = request.getParameter("username"); String password = request.getParameter("password"); String checkCode_user = request.getParameter("checkCode"); // 3、封装user对象 User LoginUser = new User(); // 实例化User对象 LoginUser.setUsername(username); // 将页面中请求的参数-username的值作为LoginUser对象的值 LoginUser.setPassword(password); // 将页面中请求的参数-password的值作为LoginUser对象的值 // 4、判断验证码时候正确 // 获取Session中存储的验证码 HttpSession session = request.getSession(); String checkCode_session = (String) session.getAttribute("checkCode_session"); // 获取session中存储的验证码 session.removeAttribute("checkCode_session"); // 将Session中的验证码与用户输入的验证码判断是否相等并且判断是否为空,因为前面代码有删除checkCode_session的值的操作 if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode_user)){ // 忽略大小写进行比较是否一样 // 如果验证码相同,则继续判断用户名和密码是否一致 // 实例化UserDAO对象并调用其中的login方法进行与数据库查询 UserDAO userDAO = new UserDAO(); User login_user = userDAO.login(LoginUser); // 调用login方法将LoginUser对象中的参数与数据库进行匹配查询 // 判断user对象 if(login_user != null){ // 登陆成功 // 存储用户信息 session.setAttribute("user",login_user); // 重定向到登录成功的页面 response.sendRedirect(request.getContextPath()+"/success.jsp"); // 动态获取路径 }else { // 登录失败 // 存储提示信息到request request.setAttribute("login_error","用户名或密码错误"); // 转发到登录页面 request.getRequestDispatcher("/Login.jsp").forward(request,response); } }else { // 如果验证码不一致 // 存储提示信息到request request.setAttribute("checkCode_error","验证码错误"); // 转发到登录页面 request.getRequestDispatcher("/Login.jsp").forward(request,response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
2、登录成功的JSP页面
重点:
JSP页面中Java代码实现数据输出的书写
登陆成功
,欢迎您! html>
本次分享结束