JavaWeb应用系统开发实训任务(二)
PS:上回我们已经完成了任务二中的第一步和第二步,今天完成任务二中的其他几步
项目结构图:
任务二
实现用户登录功能的开发任务,在页面输入用户名、密码、验证码后,点击【登录】按钮,能自动提交用户登录验证请求,验证成功后自动跳转到教师管理页面
3在项目源码src目录下创建包ks.po,在该包中新建用户类User,并实现用户类的java代码
操作说明:
1)在右侧项目资源视图中,选择src目录,选择右键菜单New,选择Package创建包名ks.po
2)再在ks.po包下创建类名User,编写其java代码
User.java
package ks.po;
import java.util.ArrayList;
import java.util.List;
public class User {
private int id;
private String role;
private String name;
private String pwd;
private String tel;
private String address;
private List<Kid> pets=new ArrayList<Kid>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Kid> getPets() {
return pets;
}
public void setPets(List<Kid> pets) {
this.pets = pets;
}
}
4在项目源码src目录下创建包ks.dao,在该包中新建用户数据访问类UserDAO,并在用户数据访问类中,实现与用户验证相关的java代码
操作说明:
1)在右侧项目资源视图中,选择src目录,选择右键菜单New,选择菜单Package创建包名ks.dao
2)再选择ks. dao包,选择右键菜单New,选择菜单Java Class创建类名UserDAO,编写其java代码
UserDAO.java
package ks.dao;
import ks.po.User;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class UserDAO
{
public void save(User user) throws Exception{
Connection con = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_ks","root","root");// 协议://域名(ip):端口/资源(数据库名)
ps=con.prepareStatement("insert into t_user value(null,?,?,?,?,?)");
ps.setString(1, user.getRole());
ps.setString(2, user.getName());
ps.setString(3, user.getPwd());
ps.setString(4, user.getTel());
ps.setString(5, user.getAddress());
ps.executeUpdate();
}catch(ClassNotFoundException e){
e.printStackTrace();
throw new Exception("找不到驱动:"+e.getMessage());//异常不能在底层丢失了
}catch (SQLException e) {
e.printStackTrace();
throw new Exception("数据库操作错误:"+e.getMessage());
}
finally{
if(ps!=null)ps.close();
if(con!=null)con.close();
}
}
/**
* 根据参数userName查找t_user表 如果找到记录就返回对应的封装对象User 没有就返回null
* @param userName
* @return
*/
public User getByName(String userName) throws Exception
{
User user=null;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_ks","root","root");// 协议://域名(ip):端口/资源(数据库名)
ps=con.prepareStatement("select * from t_user where name=?");
ps.setString(1, userName);
rs=ps.executeQuery();
if(rs.next())//如果if为true 表示找到了记录 此时才需要进行User对象的初始化(new User())以及 数据封装(setXxx)
{
user=new User();
user.setAddress(rs.getString("address"));;
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPwd(rs.getString("pwd"));
user.setRole(rs.getString("role"));
user.setTel(rs.getString("tel"));
}
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
throw new Exception("找不到驱动:"+e.getMessage());//异常不能在底层丢失了
}
catch (SQLException e)
{
e.printStackTrace();
throw new Exception("数据库操作错误:"+e.getMessage());
}
finally
{
if(rs!=null)rs.close();
if(ps!=null)ps.close();
if(con!=null)con.close();
}
return user;
}
/**
* 根据参数cname查找t_user表,role类型为customer的用户,如果找到记录就返回对应的封装对象User 没有就返回null
* @param cname
* @return
*/
public List<User> searchCustomer(String cname) throws Exception
{
List<User> users = new ArrayList<User>();
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_ks","root", "root");
// 1.找符合条件的教师
ps = con.prepareStatement("select * from t_user where name like ? and role='teacher'");
ps.setString(1, "%" + cname + "%");
rs = ps.executeQuery();
while(rs.next()) // 这里查询的是t_user.* 所以使用User封装
{
User user = new User();
user.setAddress(rs.getString("address"));;
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPwd(rs.getString("pwd"));
user.setRole(rs.getString("role"));
user.setTel(rs.getString("tel"));
users.add(user);
}
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
throw new Exception("找不到驱动:" + e.getMessage());
}
catch(SQLException e)
{
e.printStackTrace();
throw new Exception("SQL异常:" + e.getMessage());
}
finally
{
if(rs != null)
{
rs.close();
}
if(ps != null)
{
ps.close();
}
if(con != null)
{
con.close();
}
}
return users;
}
/**
* 根据id查找t_user表 将找到的记录封装成为User对象返回
* @param id
* @return
* @throws Exception
*/
public User getById(int id) throws Exception
{
User user=null;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_ks","root","root");// 协议://域名(ip):端口/资源(数据库名)
ps=con.prepareStatement("select * from t_user where id=?");
ps.setInt(1, id);
rs=ps.executeQuery();
if(rs.next()){//如果if为true 表示找到了记录 此时才需要进行User对象的初始化(new User())以及 数据封装(setXxx)
user=new User();
user.setAddress(rs.getString("address"));;
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPwd(rs.getString("pwd"));
user.setRole(rs.getString("role"));
user.setTel(rs.getString("tel"));
}
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
throw new Exception("找不到驱动:"+e.getMessage());//异常不能在底层丢失了
}
catch (SQLException e)
{
e.printStackTrace();
throw new Exception("数据库操作错误:"+e.getMessage());
}
finally
{
if(rs!=null)rs.close();
if(ps!=null)ps.close();
if(con!=null)con.close();
}
return user;
}
/**
* 根据客户ID删除t_usr表的一条记录
* @param userId
* @throws Exception
*/
public void delete(int userId) throws Exception
{
Connection con = null;
PreparedStatement ps = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_ks","root","root");// 协议://域名(ip):端口/资源(数据库名)
ps = con.prepareStatement("delete from t_user where id=?");
ps.setInt(1, userId);
ps.executeUpdate();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
throw new Exception("找不到驱动:"+e.getMessage());//异常不能在底层丢失了
}
catch(SQLException e)
{
e.printStackTrace();
throw new Exception("数据库操作错误:"+e.getMessage());
}
finally
{
if(ps!=null)
{
ps.close();
}
if(con!=null)
{
con.close();
}
}
}
/**
* 获取并返回所有的客户
* @throws Exception
*/
public List<User> getAllCustomer() throws Exception
{
return searchCustomer("");
}
}
5在项目源码src目录下创建包ks.utils,在该包中新建验证码类CheckCode(继承HttpServlet类),实现验证码类的java代码
操作说明:
1)在右侧项目资源视图中,选择src目录,选择右键菜单New,选择菜单Package创建包名ks. utils
2)再选择ks. utils包,选择右键菜单New,选择菜单Java Class创建类名CheckCode,编写其java代码
CheckCode.java
package ks.utils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
// @称为 Java注解 WebServlet注解类用来将路径映射到当前Servlet上
// Java同时支持注解配置和文件配置
@WebServlet("/CheckCode")
public class CheckCode extends HttpServlet
{
private static final long serialVersionUID = 1L;
private int width = 80; // 验证码图片的默认宽度
private int height = 20; // 验证码图片的默认高度
private int codeCount = 4; // 验证码图片的字符数
private int x = 16;
private int fontHeight=16;
private int codeY=18;
private final char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9' };
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, java.io.IOException
{
//构造一个类型为预定义图像类型之一的BufferedImage,设置图像的宽,高,和类型(TYPE_INT_RGB)
BufferedImage Img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 返回Graphics2D,Graphics2D类扩展自Graphics 类,以提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制
Graphics g = Img.getGraphics();
Random random = new Random();
// 将图像填充为白色
g.setColor(Color.WHITE);
//填充指定的矩形。x,y坐标均为0,宽为width,高为height
g.fillRect(0, 0, width, height);
// 创建字体,字体的大小应该根据图片的高度来定。
Font font = new Font("Times new Roman", Font.PLAIN, fontHeight);
g.setColor(Color.black);
g.setFont(font);
Color juneFont = new Color(153, 204, 102);
// 随机产生130条干扰线,不易被其它程序探测
g.setColor( juneFont );
for (int i = 0; i < 130; i++)
{
//返回伪随机数
int x= random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(16); //80/5=16
int yl = random.nextInt(16);
//在此图形上下文的坐标系中,使用当前颜色在点 (x1, y1) 和 (x2, y2) 之间画一条线
g.drawLine(x, y, x + xl, y + yl);
}
// randomCode用于保存随机产生的验证码,以便用户登录后进行验证,线程安全的可变字符序列
StringBuffer randomCode = new StringBuffer();
// 随机产生codeCount数字的验证码
for (int i = 0; i < codeCount; i++)
{
//返回 char 参数的字符串表示形式
String strRand = String.valueOf(codeSequence[random.nextInt(36)]);
// 用随机产生的颜色将验证码绘制到图像中
//创建具有指定红色、绿色和蓝色值的不透明的 sRGB 颜色,这些值都在 (0 - 255) 的范围内
g.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
//使用此图形上下文的当前字体和颜色绘制由指定 string 给定的文本。最左侧字符的基线位于此图形上下文坐标系的 (x, y) 位置处。
g.drawString(strRand, (i + 1) * x-4, codeY);
randomCode.append(strRand);
}
HttpSession session = request.getSession(); // 将四位数字的验证码保存到Session中
session.setAttribute("realcode", randomCode.toString());
// 禁止浏览器缓存
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setHeader("Cache-Control", "no-cache");//HTTP 1.1
response.setDateHeader("Expires", 0); //在代理服务器端防止缓冲
response.setContentType("image/gif"); //设置正被发往客户端的响应的内容类型
// 将图像输出到Servlet输出流中,ServletOutputStream提供了向客户端发送二进制数据的输出流
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(Img, "gif", sos); //使用支持给定格式的任意 ImageWriter 将一个图像写入 OutputStream
sos.flush(); //刷新此输出流并强制写出所有缓冲的输出字节
sos.close();
}
}
6在项目源码src目录下创建包ks.servlet,在该包中新建用户登录功能的LoginServlet,实现处理用户登录验证请求的java代码
操作说明:
1)在右侧项目资源视图中,选择src目录,选择右键菜单New,选择菜单Package创建包名ks. servlet
2)再选择ks. servlet包,选择右键菜单New,选择菜单Servlet,创建类名LoginServlet,编写其java代码
LoginServlet.java
package ks.servlet;
import ks.dao.UserDAO;
import ks.po.User;
import ks.utils.MD5Util;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/LoginServlet")
public class LoginServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
try{
/* 0.取出表单中的用户提交数据 */
String username = request.getParameter("username");
// System.out.println(username);
String pwd = request.getParameter("pwd");
String usercode = request.getParameter("usercode");//用户输入的验证码
//1.验证验证码
String realcode=(String) request.getSession(true).getAttribute("realcode");//session中的验证码
if(!realcode.equalsIgnoreCase(usercode))//如果两个验证码不一致
// if(false)
{
request.setAttribute("msg", "验证码输入错误");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
else
{
User user = new UserDAO().getByName(username);
if(null == user)
{
request.setAttribute("msg", "用户名不存在");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
// else if(!user.getPwd().equals(pwd))
else if(!user.getPwd().equals(pwd))
{
request.setAttribute("msg", "密码输入错误");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
else
{
request.getSession(true).setAttribute("user", user);
// request.setAttribute("msg", "登录成功");
if(user.getRole().equals("teacher"))
{
request.setAttribute("msg", "教师" + user.getName() + "登录成功");
request.getRequestDispatcher("/teacherSearch.jsp").forward(request, response);
}
else if(user.getRole().equals("admin"))
{
request.setAttribute("msg", "系统管理员" + user.getName() + "登录成功");
request.getRequestDispatcher("/teacherSearch.jsp").forward(request, response);
}
else
{
request.setAttribute("msg", user.getName() + "登录成功");
request.getRequestDispatcher("/teacherSearch.jsp").forward(request, response);
}
// request.getRequestDispatcher("/teacherSearch.jsp").forward(request, response);
}
}
}
catch(Exception e)
{
request.setAttribute("msg", e.getMessage());
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
}
}
总结写到这里,我们的任务二的所有功能已经全部完成了,今天写的功能主要是"教师登陆"的功能,从登陆UI获取输入的用户名和密码以及验证码,在LoginServlet.java中首先判断输入的验证码是否正确,然后再分析数据库中是否存在用户输入的用户名和密码。如果返回结果为true,则进入下一个界面。如果结果为flase,则在页面上显示XXX错误。
这里两点需要注意
①在userDao.java文件中数据库连接的密码必须是自己电脑上的连接密码。
②在lib目录中必须添加Mysql驱动(mysql-connector-java-5.1.46-bin.jar)
PS:如果需要前一章教程的童鞋,请戳这里 博主真帅!
下一篇: 5.HTML标题
推荐阅读