项目第二天
4-验证码
1-制作验证码
在action
创建一个ValCodeServlet.java
的文件
@WebServlet(urlPatterns = "/code.let", loadOnStartup = 1)
public class ValCodeServlet extends HttpServlet {
Random random = new Random();
private String getRandomStr() {
String str = "23456789ABCDEFGHJKMNPQRSTUVWXYZabcdefghgkmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
int index = random.nextInt(str.length());
char letter = str.charAt(index);
sb.append(letter);
}
return sb.toString();
}
private Color getBackColor() {
int red = random.nextInt(256);
int green = random.nextInt(256);
int blue = random.nextInt(256);
return new Color(red, green, blue);
}
private Color getForeColor(Color bgColor) {
int red = 255 - bgColor.getRed();
int green = 255 - bgColor.getGreen();
int blue = 255 - bgColor.getBlue();
return new Color(red, green, blue);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("image/jpeg");
BufferedImage bufferedImage = new BufferedImage(80, 30, BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.getGraphics();
Color bgColor = getBackColor();
g.setColor(bgColor);
g.fillRect(0, 0, 80, 30);
Color foreColor = getForeColor(bgColor);
g.setColor(foreColor);
g.setFont(new Font("黑体", Font.BOLD, 26));
String randomStr = getRandomStr();
HttpSession session = req.getSession();
session.setAttribute("code", randomStr);
g.drawString(randomStr, 10, 28);
for (int i = 0; i < 30; i++) {
g.setColor(Color.white);
int x = random.nextInt(80);
int y = random.nextInt(30);
g.fillRect(x, y, 1, 1);
}
ServletOutputStream sos = resp.getOutputStream();
ImageIO.write(bufferedImage, "jpeg", sos);
}
}
2-判断验证码是否正确
在UserServlet
添加如下代码
@WebServlet("/user.let")
public class UserServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
switch (method) {
case "login":
// .....
String UserCode = req.getParameter("valcode");
String code = session.getAttribute("code").toString();
if (!code.equalsIgnoreCase(UserCode)) {
out.println("<script>alert('验证码输入错误'); location.href='login.html';</script>");
return;
}
if (user == null) { // ....} else {
session.setAttribute("user", user);
// ....
}
}
}
}
3-点击验证码刷新
在login.html
文件中添加如下代码,注意给验证码图片添加一个id
<script language="JavaScript" src="Js/jquery-3.3.1.min.js"></script>
<script language="JavaScript">
$(function() {
$("#code").click(function() {
$(this).prop("src", "code.let?id=" + new Date())
})
})
</script>
5-首页
1-html转换成jsp
- 在web包下创建对应名称的jsp的文件,然后把资料里的html代码拷贝到jsp文件里,
注意:
-
拷贝的时候需要保留文件头,其他的就都不需要
<%- 此行保留,其他的就用资料的html代码 -%> <%@ page contentType="text/html;charset=UTF-8" language="java" %>
首页需要先把资料里的对应html文件转换成index.jsp
、top.jsp
、left.jsp
、set_pwd.jsp
文件
2-登录显示用户名
在top.jsp
修改如下代码
当前用户:<b>${user.name}</b>
3-退出功能
-
在
UserServlet
的switch添加如下代码case "exit": session.invalidate(); out.println("<script>parent.window.location.href='login.html';</script>"); break;
-
在
top.jsp
修改如下代码<a style="color:white" onclick="return confirm('确认退出')" href="user.let?type=exit"> 安全退出 </a>
6-修改密码
1-导入对应的网页文件
- 把
set_pwd.html
文件转换成set_pwd.jsp
文件 - 把
left.jsp
文件里的.html
修改成.jsp
2-UserDao层
-
在
UserDao.java
文件添加如下代码public int modifyPwd(long id, String pwd) throws Exception { String sql = "update user set pwd = ? where id = ?"; Connection conn = DBHelper.getConnection(); int count = runner.update(conn, sql, pwd, id); conn.close(); return count; }
3-UserServer层
-
在
UserBiz.java
文件添加如下代码public int modifyPwd(long id, String pwd) { int count = 0; try { count = userDao.modifyPwd(id, pwd); } catch (Exception e) { e.printStackTrace(); } return count; }
4-UserServlet层
-
在
UserServlet
的switch添加如下代码case "modifyPwd": String newPwd1 = req.getParameter("newpwd"); String newPwd2 = req.getParameter("newpwd2"); String pwd1 = req.getParameter("pwd"); String pwd2 = ((User) session.getAttribute("user")).getPwd(); if (!pwd1.equals(pwd2)) { out.println("<script>alert('原密码不正确');location.href='set_pwd.jsp';</script>"); return; } if (!newPwd1.equals(newPwd2)) { out.println("<script>alert('新密码与确认密码不一致');location.href='set_pwd.jsp';</script>"); return; } long id = ((User) session.getAttribute("user")).getId(); int count = userBiz.modifyPwd(id, newPwd1); if (count > 0) { out.println("<script>alert('密码修改成功');parent.window.location.href='login.html';</script>"); } else { out.println("<script>alert('密码修改失败');</script>"); } break;
-
修改
set_pwd.jsp
的form表单<form action="user.let?type=modifyPwd" method="post">
7-图书类型管理
1-Type实体类
实体类都放在bean
包下
public class Type implements Serializable {
private long id;
private String name;
private long parentId;
// 下方省略get/set方法以及toString方法
}
2-TypeDao层
TypeDao层放在dao
包下
public class TypeDao {
QueryRunner runner = new QueryRunner();
// 添加图书类型
public int add(String name, long parentId) throws Exception {
Connection conn = DBHelper.getConnection();
String sql = "insert into type value(null, ?, ?)";
int count = runner.update(conn, sql, name, parentId);
conn.close();
return count;
}
// 获取所有的类型
public List<Type> getAll() throws Exception {
Connection conn = DBHelper.getConnection();
String sql = "select * from type";
List<Type> types = runner.query(conn, sql, new BeanListHandler<Type>(Type.class));
DBHelper.close(conn);
return types;
}
// 根据类型编号获取类型对象
public Type getById(long typeId) throws Exception {
Connection conn = DBHelper.getConnection();
String sql = "select * from type where id = ?";
Type type = runner.query(conn, sql, new BeanHandler<Type>(Type.class), typeId);
DBHelper.close(conn);
return type;
}
// 修改图书类型
public int modify(long id, String name, long parentId) throws Exception {
Connection conn = DBHelper.getConnection();
String sql = "update type set name = ?, parentId = ? where id = ?";
int count = runner.update(conn, sql, name, parentId, id);
conn.close();
return count;
}
// 删除图书类型
public int remove(long id) throws Exception {
Connection conn = DBHelper.getConnection();
String sql = "delete from type where id = ?";
int count = runner.update(conn, sql, id);
DBHelper.close(conn);
return count;
}
}
3-TypeServer层
-
准备
Book
的实体类。【放在bran
包下,由于删除类型的功能要判断此类型里面是否有书籍,所以就要提前准备实体类】public class Book implements Serializable { private long id; private String name; private double price; private String desc; private String pic; private String publish; private String author; private long stock; private String address; //外键号 private long typeId; //外键对应的实体对象 private Type type; // 下方省略get/set方法以及toString方法 }
-
BookDao
层【BookDao层放在dao
包下】public class BookDao { QueryRunner runner = new QueryRunner(); // 根据类型查询对应的书籍信息 public List<Book> getBookTypeId(long typeId) throws Exception { Connection conn = DBHelper.getConnection(); String sql = "select * from book where typeId = ?"; List<Book> books = runner.query(conn, sql, new BeanListHandler<Book>(Book.class), typeId); DBHelper.close(conn); return books; } }
-
TypeServer层放在
biz
包下public class TypeBiz { TypeDao typeDao = new TypeDao(); public int add(String name, long parentId) { int count = 0; try { count = typeDao.add(name, parentId); } catch (Exception e) { e.printStackTrace(); } return count; } public List<Type> getAll() { try { return typeDao.getAll(); } catch (Exception e) { e.printStackTrace(); return null; } } public Type getById(long id) { try { return typeDao.getById(id); } catch (Exception e) { e.printStackTrace(); return null; } } public int modify(long id, String name, long parentId) { int count = 0; try { count = typeDao.modify(id, name, parentId); } catch (Exception e) { e.printStackTrace(); } return count; } public int remove(long id) throws Exception { BookDao bookDao = new BookDao(); int count = 0; try { List<Book> books = bookDao.getBookTypeId(id); if (books.size() > 0) { throw new Exception("删除的类型中有图书,请勿删除"); } count = typeDao.remove(id); } catch (SQLException e) { e.printStackTrace(); } return count; } }
4-实现图书所有类型展示功能
-
把
type_list.html
文件转换成type_list.jsp
文件 -
在book包下创建一个
listener
包。【这个是放监听器文件的包】 -
在
listener
包下创建一个TypeServletContextListener
类,编写如下代码@WebListener public class TypeServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { TypeBiz biz = new TypeBiz(); List<Type> types = biz.getAll(); ServletContext application = servletContextEvent.getServletContext(); application.setAttribute("types", types); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) {} }
-
修改
type_list.jsp
文件-
引入JSTL标准库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
修改文件的table
<table width="60%" class="cont tr_color"> <tr> <th>类型编号</th> <th>类型名称</th> <th>父类型</th> <th>操作</th> </tr> <c:forEach items="${types}" var="t"> <tr align="center" class="d"> <td>${t.id}</td> <td>${t.name}</td> <td>${t.parentId}</td> <td> <a href="type_modify.html">修改</a> <a href="#">删除</a> </td> </tr> </c:forEach> </table>
-
5-实现图书类型的添加功能
-
把
type_add.html
文件转换成type_add.jsp
文件 -
在
action
包下创建TypeServlet.java
文件@WebServlet("/type.let") public class TypeServlet extends HttpServlet { TypeBiz typeBiz = new TypeBiz(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); ServletContext application = req.getServletContext(); String type = req.getParameter("type"); switch (type) { case "add": add(req, resp, out, application); break; } } public void add(HttpServletRequest req, HttpServletResponse resp, PrintWriter out, ServletContext application) { String typeName = req.getParameter("typeName"); long parentId = Long.parseLong(req.getParameter("parentType")); int count = typeBiz.add(typeName, parentId); if (count > 0) { List<Type> types = typeBiz.getAll(); application.setAttribute("types", types); out.println("<script>alert('添加成功');location.href = 'type_list.jsp';</script>"); } else { out.println("<script>alert('添加失败');location.href = 'type_add.jsp';</script>"); } } }
-
修改
type_add.jsp
<%--引入JSTL标准库--%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <form action="type.let?type=add" method="post"> <table width="40%" class="cont"> <%-- 注意此处的name属性要跟上面add方法中获取文本框的属性值一致 --%> <td width="40%"><input class="text" type="text" name="typeName" value="" required/></td> <select id="parentType" name="parentType"> <option value="0" selected>无</option> <c:forEach items="${types}" var="t"> <option value="${t.id}">${t.name}</option> </c:forEach> </select> </table> </form>
6-实现图书类型删除的功能
-
修改
type_list.jsp
的删除按钮<a onclick="return confirm('确认删除');" href="type.let?type=remove&id=${t.id}">删除</a>
-
在
TypeServlet
的switch添加如下代码case "remove": remove(req, resp, out, application); break;
-
在
TypeServlet
中添加对应的方法public void remove(HttpServletRequest req, HttpServletResponse resp, PrintWriter out, ServletContext application) { long id = Long.parseLong(req.getParameter("id")); try { int count = typeBiz.remove(id); if (count > 0) { List<Type> types = typeBiz.getAll(); application.setAttribute("types", types); out.println("<script>alert('删除成功');location.href = 'type_list.jsp';</script>"); } else { out.println("<script>alert('删除失败');location.href = 'type_list.jsp';</script>"); } } catch (Exception e) { out.println("<script>alert('" + e.getMessage() + "');location.href='type_list.jsp';</script>"); } }
7-实现修改图书类型的功能
-
修改
type_list.jsp
的修改按钮<a onclick="return confirm('确认修改');" href="type.let?type=modifypre&id=${t.id}">修改</a>
-
在
TypeServlet
的switch添加如下代码case "modifypre": modifyPre(req, resp, out, application); break;
-
在
TypeServlet
中添加对应的方法public void modifyPre(HttpServletRequest req, HttpServletResponse resp, PrintWriter out, ServletContext application) throws ServletException, IOException { long id = Long.parseLong(req.getParameter("id")); Type type = typeBiz.getById(id); req.setAttribute("type", type); req.getRequestDispatcher("type_modify.jsp").forward(req, resp); }
-
把
type_modify.html
文件转换成type_modify.jsp
文件 -
修改
type_modify.jsp
文件-
引入JSTL标准库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
修改文件的from
<form action="type.let?type=modify" method="post"> .... <td width="40%"> <input type="text" id="typeId" class="text" name="txtTypeId" value="${type.id}" disabled /> <input type="hidden" class="text" name="typeId" value="${type.id}" /> </td> ..... <td width="40%"> <input type="text" id="typeName" class="text" name="typeName" value="${type.name}"/> </td> ..... <td> <select id="parentType" name="parentType"> <c:if test="${type.parentId==0}"> <option value="0" selected>无</option> <c:forEach items="${types}" var="t"> <c:if test="${t.id==type.parentId}"> <option value="${t.id}" selected>${t.name}</option> </c:if> <c:if test="${t.id!=type.parentId}"> <option value="${t.id}">${t.name}</option> </c:if> </c:forEach> </c:if> <c:if test="${type.parentId!=0}"> <option value="0">无</option> <c:forEach items="${types}" var="t"> <c:if test="${t.id==type.parentId}"> <option value="${t.id}" selected>${t.name}</option> </c:if> <c:if test="${t.id!=type.parentId}"> <option value="${t.id}">${t.name}</option> </c:if> </c:forEach> </c:if> </select> </td> ..... </form>
-
-
在
TypeServlet
的switch添加如下代码case "modify": modify(req, resp, out, application); break;
-
在
TypeServlet
中添加对应的方法public void modify(HttpServletRequest req, HttpServletResponse resp, PrintWriter out, ServletContext application) { long id = Long.parseLong(req.getParameter("typeId")); String name = req.getParameter("typeName"); long parentId = Long.parseLong(req.getParameter("parentType")); int count = typeBiz.modify(id, name, parentId); if(count>0){ List<Type> types = typeBiz.getAll(); application.setAttribute("types",types); out.println("<script>alert('修改成功');location.href = 'type_list.jsp';</script>"); }else{ out.println("<script>alert('修改失败');location.href = 'type_list.jsp';</script>"); } }