当前位置: 首页 > news >正文

项目实战系列三: 家居购项目 第三部分

文章目录

  • 🍃后台分页
    • 🍅后台分页导航
  • 🍃首页分页
    • 🍅首页分页导航
    • 🍅首页搜索
    • 🍅两个奇怪的问题
    • 🍅会员显示登录名
    • 🍅注销登录
    • 🍅验证码

🍃后台分页

程序框架图
在这里插入图片描述

1.新建com.zzw.furns.entity.Page

//Page是一个Javabean, 是一个分页的数据模型(包含了分页的各种信息)
//T表示泛型, 因为将来分页模型对应的数据类型是不确定的
public class Page<T> {//因为每页显示多少条记录, 是其它地方也可以使用的public static final Integer PAGE_SIZE = 3;//pageNo 前端页面传来的private Integer pageNo;//表示显示当前页[即显示第几页]private Integer pageSize = PAGE_SIZE;//表示每页显示几条记录//pageTotal 计算得到的private Integer pageTotal;//表示共有多少页//totalRow 是可以从数据库来的, 由DAO来完成private Integer totalRow;//表示共有多少条记录//items 从数据库DB来的, 由DAO完成private List<T> items;//表示当前页,要显示的数据private String url;//分页导航的字符串public Page() {}public Page(Integer pageSize, Integer pageNo) {this.pageSize = pageSize;this.pageNo = pageNo;}
}

2.参考

在这里插入图片描述

3.修改FurnDao.java

//Page的哪些属性是可以从数据库中获取的, 就把获取这个属性的任务放在DAO层
public int getTotalRow();/*** 获取当前页要显示的数据** @param begin    表示当前数据从第几条记录开始获取, 从0开始计算* @param pageSize 表示取出多少条记录* @return*/
public List<Furn> getPageItems(int begin, int pageSize);

4.修改FurnDaoImpl.java

@Override
public int getTotalRow() {String sql = "SELECT COUNT(*) FROM furn";//return (Integer) queryScalar(sql);//=>会报cast异常//java.lang.Long cannot be cast to java.lang.Integerreturn ((Number) queryScalar(sql)).intValue();
}@Override
public List<Furn> getPageItems(int begin, int pageSize) {String sql = "select id, `name`,business,price,saleNum,inventory,image_path from furn limit ?,?";return queryMany(sql, Furn.class, begin, pageSize);
}

5.测试FurnDaoTest.java

@Test
public void getTotalRow() {int totalRow = furnDao.getTotalRow();System.out.println(totalRow);
}@Test
public void getPageItems() {List<Furn> pageItems = furnDao.getPageItems(1, 5);for (Furn furn : pageItems) {System.out.println(furn);}
}

6.修改FurnService.java

/*** 根据传入的 pageNo和 pageSize, 返回对应的page对象* @param pageNo* @param pageSize* @return*/
public Page<Furn> page(int pageNo, int pageSize);

7.修改FurnServiceImpl.java

@Override
public Page<Furn> page(int pageNo, int pageSize) {//先创建一个page对象, 然后根据实际情况, 填充属性Page<Furn> page = new Page<>();page.setPageNo(pageNo);//(1)表示显示当前页[即显示第几页]page.setPageSize(pageSize);//(2)表示每页显示几条记录int totalRow = furnDAO.getTotalRow();page.setTotalRow(totalRow);//(3)表示共有多少条记录//比如 6 2 => 6 / 2 = 3//比如 5 2 => 5 / 2 = 2//比如 7 2 => 7 / 2 = 3//比如 0 2 => 0 / 2 = 0int pageTotal = totalRow / pageSize;if (totalRow % pageSize > 0) {++pageTotal;}page.setPageTotal(pageTotal);//(4)表示共有多少页//比如: pageNo=1, pageSize=3 => begin=1//比如: pageNo=2, pageSize=3 => begin=4//比如: pageNo=3, pageSize=2 => begin=4//注意: 这里隐藏了一个坑, 此刻还看不到, 之后会暴露int begin = (pageNo - 1) * pageSize;List<Furn> pageItems = furnDAO.getPageItems(begin, pageSize);page.setItems(pageItems);//(5)表示当前页,要显示的数据//还差一个url[分页导航], 后面需要return page;
}

8.测试FurnServiceTest.java

@Test
public void page() {//小技巧: 如果我们需要看一个对象, 这个对象比较复杂, 可以debug看对象Page<Furn> page = furnService.page(2, 2);System.out.println("page ===> " + page);
}

在这里插入图片描述

9.修改src/com/zzw/furns/web/FurnServlet.java, web层获取page对象

protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int pageNo = DataUtils.parseInt(req.getParameter("pageNo"), 1);int pageSize = DataUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);//调用service, 获取page对象Page<Furn> page = furnService.page(pageNo, pageSize);//将page放入到request域req.setAttribute("page", page);//请求转发到家居管理页面req.getRequestDispatcher("/views/manage/furn_manage.jsp").forward(req, resp);
}

10.修改manage_menu.jsp, 取缔list方法

<div class="header-bottom-set dropdown"><a href="manage/furnServlet?action=page">家居管理</a>
</div>

11.测试, 管理员登陆后, 点击家居管理
在这里插入图片描述

12.修改web/views/manage/furn_manage.jsp

<c:forEach items="${requestScope.page.items}" var="item">
<tr><td class="product-thumbnail"><a href="#"><img class="img-responsive ml-3" src="${item.imagePath}"alt=""/></a></td><td class="product-name"><a href="#">${item.name}</a></td><td class="product-name"><a href="#">${item.business}</a></td><td class="product-price-cart"><span class="amount">${item.price}</span></td><td class="product-quantity">${item.saleNum}</td><td class="product-quantity">${item.inventory}</td><td class="product-remove"><a href="manage/furnServlet?action=display&id=${item.id}"><i class="icon-pencil"></i></a><a furnName="${item.name}" href="manage/furnServlet?action=del&id=${item.id}"><i class="icon-close"></i></a></td>
</tr>
</c:forEach>

🍅后台分页导航

需求分析

  1. 管理员进入到家居管理后台页面
  2. 可以通过分页导航条来进行分页显示
  3. 完成上页, 下页, 显示共多少页
  4. 点击分页导航, 可以显示对应页的家居信息
  5. 在管理员进行修改, 删除, 添加后, 能够回显原来操作所在页面的数据

程序框架图

在这里插入图片描述

1.粘贴首页的分页导航代码

<!--  Pagination Area Start -->
<div class="pro-pagination-style text-center mb-md-30px mb-lm-30px mt-6" data-aos="fade-up"><ul><li><a href="#">首页</a></li><li><a href="#">上页</a></li><li><a class="active" href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li><li><a href="#">下页</a></li><li><a href="#">末页</a></li><li><a>共10页</a></li><li><a>共90记录</a></li></ul>
</div>
<!--  Pagination Area End -->

2.放到web/views/manage/furn_manage.jsp, 并做修改

<!--  Pagination Area Start -->
<div class="pro-pagination-style text-center mb-md-30px mb-lm-30px mt-6" data-aos="fade-up"><ul><%--如果当前页 > 1, 就显示首页和上一页--%><li><a style="${requestScope.page.pageNo == 1 ? 'pointer-events: none; color: lightgray' : ''}"href="manage/furnServlet?action=page&pageNo=1&pageSize=${requestScope.page.pageSize}">首页</a></li><li><a style="${requestScope.page.pageNo == 1 ? 'pointer-events: none; color: lightgray' : ''}"href="manage/furnServlet?action=page&pageNo=${requestScope.page.pageNo - 1}&pageSize=${requestScope.page.pageSize}">上一页</a></li><%--显示所有的分页数 先确定开始的页数 begin 1; 再确定结束的页数 end=>pageTotal--%><%--最多显示10, 这里涉及算法--%><c:set scope="page" var="begin" value="1"></c:set><c:set scope="page" var="end" value="${requestScope.page.pageTotal}"></c:set><%--循环显示--%><c:forEach begin="${pageScope.begin}" end="${pageScope.end}" var="i"><%--总的页数--%><%--如果i是当前页, 就使用class="active"来修饰--%><li><a class="${i eq requestScope.page.pageNo ? "active" : ""}"href="manage/furnServlet?action=page&pageNo=${i}&pageSize=${requestScope.page.pageSize}">${i}</a></li></c:forEach><%--如果当前页 < 总的页数, 就显示末页和下一页--%><li><a style="${requestScope.page.pageNo == requestScope.page.pageTotal ? 'pointer-events: none; color: lightgray' : ''}"href="manage/furnServlet?action=page&pageNo=${requestScope.page.pageNo + 1}&pageSize=${requestScope.page.pageSize}">下一页</a></li><li><a style="${requestScope.page.pageNo == requestScope.page.pageTotal ? 'pointer-events: none; color: lightgray' : ''}"href="manage/furnServlet?action=page&pageNo=${requestScope.page.pageTotal}&pageSize=${requestScope.page.pageSize}">末页</a></li><li><a>共${requestScope.page.pageTotal}</a></li><li><a>共${requestScope.page.totalRow}记录</a></li></ul>
</div>
<!--  Pagination Area End -->

3.修改后返回原页面
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.删除后返回原页面

在这里插入图片描述
在这里插入图片描述

5.添加后返回原页面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

🍃首页分页

🍅首页分页导航

需求分析

  1. 顾客进入首页页面
  2. 分页显示家居
  3. 正确显示分页导航条, 即功能完善, 可以使用

程序框架图

在这里插入图片描述

1.新建src/com/zzw/furns/web/CustomerFurnServlet.java, 使用注解方式

@WebServlet(urlPatterns = "/customerFurnServlet")
public class CustomerFurnServlet extends BasicServlet {private FurnService furnService = new FurnServiceImpl();protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"), 1);Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);Page<Furn> page = furnService.page(pageNo, pageSize);//保存到request域req.setAttribute("page", page);//请求转发到/views/customer/index.jspreq.getRequestDispatcher("/views/customer/index.jsp").forward(req, resp);}
}

2.将项目页面移到web/views/customer目录下.

3.新建web/index.jsp, 负责请求转发.

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.直接请求CustomerFurnServlet, 获取网站首页要显示的分页数据. 类似我们网站的入口页面

在这里插入图片描述

5.分页显示数据

<c:forEach items="${requestScope.page.items}" var="item"><div class="col-lg-3 col-md-6 col-sm-6 col-xs-6 mb-6" data-aos="fade-up"data-aos-delay="200"><!-- Single Prodect --><div class="product"><div class="thumb"><a href="shop-left-sidebar.jsp" class="image"><img src="${item.imagePath}" alt="Product"/><img class="hover-image" src="assets/images/product-image/5.jpg"alt="Product"/></a><span class="badges"><span class="new">New</span></span><div class="actions"><a href="#" class="action wishlist" data-link-action="quickview"title="Quick view" data-bs-toggle="modal"data-bs-target="#exampleModal"><iclass="icon-size-fullscreen"></i></a></div><button title="Add To Cart" class=" add-to-cart">AddTo Cart</button></div><div class="content"><h5 class="title"><a href="shop-left-sidebar.jsp">Simple 北欧${item.name} </a></h5><span class="price"><span class="new">家居: ${item.name}</span></span><span class="price"><span class="new">厂商: ${item.business}</span></span><span class="price"><span class="new">价格: ¥${item.price}</span></span><span class="price"><span class="new">销量: ${item.saleNum}</span></span><span class="price"><span class="new">库存: ${item.inventory}</span></span></div></div></div>
</c:forEach>

6.首页分页导航

<c:set var="pageNo" value="${requestScope.page.pageNo}"></c:set>
<c:set var="pageTotal" value="${requestScope.page.pageTotal}"></c:set>
<c:set var="pageSize" value="${requestScope.page.pageSize}"></c:set>
<!--  Pagination Area Start -->
<div class="pro-pagination-style text-center mb-md-30px mb-lm-30px mt-6" data-aos="fade-up"><ul><li><a href="customerFurnServlet?action=page&pageNo=1&pageSize=${pageSize}">首页</a></li><li><a style="${pageNo <= 1 ? 'pointer-events: none; color: lightgray' : ''}" href="customerFurnServlet?action=page&pageNo=${pageNo - 1}&pageSize=${pageSize}">上页</a></li><c:forEach begin="1" end="${pageTotal}" var="i"><li><a class="${pageNo == i ? 'active' : ''}" href="customerFurnServlet?action=page&pageNo=${i}&pageSize=${pageSize}">${i}</a></li></c:forEach><li><a style="${pageNo >= pageTotal ? 'pointer-events: none; color: lightgray;': ''}" href="customerFurnServlet?action=page&pageNo=${pageNo + 1}&pageSize=${pageSize}">下页</a></li><li><a href="customerFurnServlet?action=page&pageNo=${pageTotal}&pageSize=${pageSize}">末页</a></li><li><a>共${pageTotal}</a></li><li><a>共${requestScope.page.totalRow}记录</a></li></ul>
</div>
<!--  Pagination Area End -->

🍅首页搜索

需求分析
1.顾客进入首页页面
2.点击搜索按钮, 可以输入家居名
3.正确显示分页导航条, 并且要求在分页时, 保留上次搜索条件

程序框架图

在这里插入图片描述

代码实现
1.修改com.zzw.furns.FurnDAO, 模糊查询👉

//根据name查询furn对象的个数
public int getTotalQuantityByName(String name);//根据begin,pageSize,name查询furn对象
public List<Furn> getPageItemsByName(int begin, int pageSize, String name);

2.修改com.zzw.furns.impl.FurnDaoImpl

@Override
public int getTotalQuantityByName(String name) {String sql = "SELECT COUNT(*) FROM furn WHERE `name` LIKE ?";return ((Number) queryScalar(sql, "%" + name + "%")).intValue();
}@Override
public List<Furn> getPageItemsByName(int begin, int pageSize, String name) {//mysql中, limit默认从0开始String sql = "SELECT id, `name`, business, price, saleNum, " +"inventory, image_path as imagePath FROM furn WHERE `name` LIKE ? Limit ?, ?";return queryMany(sql, Furn.class, "%" + name + "%", begin, pageSize);
}

3.测试, 修改FurnDaoTest

@Test
public void getTotalQuantityByName() {System.out.println(furnDAO.getTotalQuantityByName("小台灯"));
}@Test
public void getPageItemsByName() {List<Furn> furns = furnDAO.getPageItemsByName(3, 2, "小台灯");for (Furn furn : furns) {System.out.println(furn);}
}

4.修改com.zzw.furns.FurnService

//根据传入的pageNo,pageSize,name, 返回对应的page对象
public Page<Furn> pageByName(int pageNo, int pageSize, String name);

5.修改com.zzw.furns.impl.FurnServiceImpl

@Override
public Page<Furn> pageByName(int pageNo, int pageSize, String name) {//先创建一个page对象, 然后根据实际情况, 填充属性Page<Furn> page = new Page<>();page.setPageNo(pageNo);//(1)表示显示当前页[即显示第几页]page.setPageSize(pageSize);//(2)表示每页显示几条记录int countByName = furnDAO.getTotalQuantityByName(name);page.setTotalRow(countByName);//(3)根据家居名 返回总的记录数//比如 6 2 => 6 / 2 = 3//比如 5 2 => 5 / 2 = 2//比如 7 2 => 7 / 2 = 3//比如 0 2 => 0 / 2 = 0int pageTotal = countByName / pageSize;//计算得到总的页数if (countByName % pageSize > 0) {++pageTotal;}page.setPageTotal(pageTotal);//(4)表示共有多少页//比如: pageNo=1, pageSize=3 => begin=1//比如: pageNo=3, pageSize=2 => begin=4//注意: 这里隐藏了一个坑, 此刻还看不到, 之后会暴露int begin = (pageNo - 1) * pageSize;List<Furn> pageItems = furnDAO.getPageItemsByName(begin, pageSize, name);page.setItems(pageItems);//(5)表示当前页,要显示的数据//还差一个url[分页导航], 后面需要return page;
}

6.测试,修改com.zzw.furns.impl.FurnServiceTest

@Test
public void pageByName() {Page<Furn> page = furnService.pageByName("蚂蚁", 1, 5);System.out.println(page);
}

6.web层 - 修改src/com/zzw/furns/web/CustomerFurnServlet.java, 增加pageByName方法

protected void pageByName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取家居名//1.如果参数有name, 但是没有值, 这时接收到的是空串, 查询所有家居信息//2.如果参数name都没有, 接收到的是nullString name = req.getParameter("name");name = (name == null) ? "" : name;int pageNo =DataUtils.parseInt(req.getParameter("pageNo"), 1);int pageSize =DataUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);//调用service方法, 获取page对象Page<Furn> page = furnService.pageByName(pageNo, pageSize, name);//将家居名[搜索条件]封装到page对象的url属性StringBuilder url = new StringBuilder("customerFurnServlet?action=pageByName");if (!"".equals(name)) {//如果name不为"", 则拼接name参数url.append("&name=").append(name);}page.setUrl(url.toString());//将page放入到request域req.setAttribute("page", page);//请求转发到index.jspreq.getRequestDispatcher("/views/customer/index.jsp").forward(req, resp);
}

7.修改web/views/customer/index.jsp

<div class="dropdown_search"><form class="action-form" action="customerFurnServlet"><input type="hidden" name="action" value="pageByName"><input type="hidden" name="pageSize" value="${param.pageSize}"><input class="form-control" name="name" placeholder="Enter your search key" type="text"><button class="submit" type="submit"><i class="icon-magnifier"></i></button></form>
</div>

8.修改web/views/customer/index.jsp导航栏

<c:set var="pageNo" value="${requestScope.page.pageNo}"></c:set>
<c:set var="pageTotal" value="${requestScope.page.pageTotal}"></c:set>
<c:set var="pageSize" value="${requestScope.page.pageSize}"></c:set>
<c:set var="url" value="${requestScope.page.url}"></c:set>
<!--  Pagination Area Start -->
<div class="pro-pagination-style text-center mb-md-30px mb-lm-30px mt-6" data-aos="fade-up"><ul><li><a href="${url}&pageNo=1&pageSize=${pageSize}">首页</a></li><li><a style="${pageNo <= 1 ? 'pointer-events: none; color: lightgray' : ''}" href="${url}&pageNo=${pageNo - 1}&pageSize=${pageSize}">上页</a></li><c:forEach begin="1" end="${pageTotal}" var="i"><li><a class="${pageNo == i ? 'active' : ''}" href="${url}&pageNo=${i}&pageSize=${pageSize}">${i}</a></li></c:forEach><li><a style="${pageNo >= pageTotal ? 'pointer-events: none; color: lightgray;': ''}" href="${url}&pageNo=${pageNo + 1}&pageSize=${pageSize}">下页</a></li><li><a href="${url}&pageNo=${pageTotal}&pageSize=${pageSize}">末页</a></li><li><a>共${pageTotal}页</a></li><li><a>共${requestScope.page.totalRow}记录</a></li></ul>
</div>
<!--  Pagination Area End -->

🍅两个奇怪的问题

1.点击家居管理, 发出两个请求

在这里插入图片描述
在这里插入图片描述

manage_menu.jspfurn_manage.jsp

在这里插入图片描述
抓包
在这里插入图片描述

原因: furn_manage.jsp有图片url

在这里插入图片描述

2.首页分页出现问题

在这里插入图片描述
在这里插入图片描述

原因

在这里插入图片描述

🍅会员显示登录名

需求分析
1.会员登陆成功
2.如果登陆成功后返回首页面, 显示订单管理和安全退出
3.如果用户没有登陆过, 首页就显示登录注册, 后台管理超链接

程序框架图

在这里插入图片描述

1.修改src/com/zzw/furns/web/MemberServlet.java

if (memberService.login(member)) {//登陆成功System.out.println("登陆成功");//将member存入到session域request.getSession().setAttribute("member", member);if ("admin".equals(member.getUsername())) {//管理员登录成功request.getRequestDispatcher("/views/manage/manage_menu.jsp").forward(request, response);} else {//普通用户登陆成功request.getRequestDispatcher("/views/member/login_ok.jsp").forward(request, response);}
}

2.修改web/views/customer/index.jsp

<!-- Single Wedge Start -->
<c:if test="${sessionScope.member != null}"><div class="header-bottom-set dropdown">欢迎: ${sessionScope.member.username}</div><div class="header-bottom-set dropdown"><a href="#">订单管理</a></div><div class="header-bottom-set dropdown"><a href="#">安全退出</a></div>
</c:if>
<c:if test="${sessionScope.member == null}"><div class="header-bottom-set dropdown"><a href="views/member/login.jsp">登录|注册</a></div><div class="header-bottom-set dropdown"><a href="views/manage/manage_login.jsp">后台管理</a></div>
</c:if>
<!-- Single Wedge End -->

🍅注销登录

思路分析
1.用户登录成功后
2.login_ok.jsp, 点击安全退出, 注销登录
3.返回首页, 也可点击安全退出, 注销登录

程序框架图

在这里插入图片描述

代码实现
1.修改src/com/zzw/furns/web/MemberServlet.java,增加方法logout

//安全退出
protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("member 被调用...");HttpSession session = req.getSession();//让当前session立即无效session.invalidate();//默认访问index.jsp 首页面//req.getContextPath() http://localhost://jiaju_mall/resp.sendRedirect(req.getContextPath());
}

2.修改web/views/customer/index.jsp

<div class="header-bottom-set dropdown"><a href="memberServlet?action=logout">安全退出</a>
</div>

🍅验证码

表单重复提交情况

  1. 提交完表单. 服务器使用请求转发进行页面跳转. 用户刷新(F5), 会发起最后一次的请求, 造成表单重复提交问题. 解决:用重定向.
  2. 用户正常提交, 由于网络延迟等原因, 未收到服务器的响应. 这时, 用户着急多点了几次提交操作, 也会造成表单重复提交. 解决: 验证码
  3. 用户正常提交, 服务器也没有延迟, 但是提交完成后, 用户回退浏览器. 重新提交, 也会造成表单重复提交. 解决: 验证码
  4. 恶意注册, 使用可以批量发送Http的工具, 比如 Postman, Jemeter等, 使用验证码防护

程序框架图
在这里插入图片描述

代码实现
1.引入kaptcha-2.3.2.jar包

2.web层, 配置KaptchaServlet

<servlet><servlet-name>KaptchaServlet</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>KaptchaServlet</servlet-name><url-pattern>/kaptchaServlet</url-pattern>
</servlet-mapping>

在这里插入图片描述
在这里插入图片描述

3.KAPTCHA_SESSION_KEY是一个常量, 使用前需要导入

import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;

在这里插入图片描述

4.修改前端页面web/views/member/login.jsp

<input type="text" id="captchaText" name="captcha" style="width: 50%"placeholder="验证码"/>  <img id="captcha" alt="" width="150px" src="kaptchaServlet">

5.测试

在这里插入图片描述

6.增加js代码, 点击图片更换验证码

$("#captcha").click(function () {$(this).attr("src", "kaptchaServlet?zzw=" + new Date());
});

7.增加校验 ⇒ 点击提交, 验证码不能为空

var captchaText = $("#captchaText").val().trim();
if (captchaText == "" || captchaText == null) {$("span.errorMsg").text("验证码不能为空!");return false;
}

8.修改MemberServlet

protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//todo 构建member//获取用户提交的验证码String captcha = request.getParameter("captcha");//从session中获取 生成的验证码HttpSession session = request.getSession();String token = (String) session.getAttribute(KAPTCHA_SESSION_KEY);//立即删除session中的验证码, 防止该验证码重复使用session.removeAttribute(KAPTCHA_SESSION_KEY);//如果token不为空, 并且和用户提交的验证码保持一致, 就继续if (token != null && token.equalsIgnoreCase(captcha)) {//todo 判断用户名是否可用 可用注册用户 不可用返回注册页面} else {request.setAttribute("msg", "验证码不正确");request.setAttribute("username", username);//回显用户名request.setAttribute("password", password);//回显密码request.setAttribute("email", email);//回显邮件request.setAttribute("active", "register_tab");request.getRequestDispatcher("/views/member/login.jsp").forward(request, response);}
}

相关文章:

项目实战系列三: 家居购项目 第三部分

文章目录 &#x1f343;后台分页&#x1f345;后台分页导航 &#x1f343;首页分页&#x1f345;首页分页导航&#x1f345;首页搜索&#x1f345;两个奇怪的问题&#x1f345;会员显示登录名&#x1f345;注销登录&#x1f345;验证码 &#x1f343;后台分页 程序框架图 1.…...

【WPF】Border的使用

在 WPF 中&#xff0c;Border 控件是一个非常实用的容器控件&#xff0c;它可以用来为其他控件添加边框、背景颜色、边距等样式。Border 本身没有内置的行为&#xff0c;但是它可以包含一个子元素&#xff0c;并且可以通过各种属性来自定义外观。 Border基本属性 Child: 表示…...

机器学习(西瓜书)第 4 章 决策树

4.1 决策树基本流程 决策树模型 基本流程 在第⑵种情形下&#xff0c;我们把当前结点标记为叶结点&#xff0c;并将其类别设定为该结点所含样本最多的类别&#xff1b;在第⑶种情形下&#xff0c;同样把当前结点标记为叶结点&#xff0c;但将其类别设定为其父结点所含样本最多…...

8、值、指针、引用作为参数或返回值

一、作为参数 1、值传递 #include <iostream> using namespace std;void swap(int a, int b) {cout << __FUNCTION__ << "交换前a:" << a << " b:" << b << endl;int tmp a;a b;b tmp;cout << __FUN…...

向量——通俗地解释

1. 向量 向量是一个既有大小(模)又有方向的对象&#xff0c;它可以用来描述空间中的位置、力或速度等量。我们可以从物理、数学和计算机的角度来看待向量&#xff0c;这三种观点看似不同却有关联。 &#xff08;1&#xff09;在物理专业视角下&#xff0c;向量是空间中的箭头&a…...

新书宣传:《量子安全:信息保护新纪元》

《量子安全&#xff1a;信息保护新纪元》 前言本书的看点本书的目录结语 前言 你好&#xff01; 这是我第一次发布类广告的博文&#xff0c;目的也很单纯&#xff0c;希望以作者的身份介绍一下自己出版的图书——《量子安全&#xff1a;信息保护新纪元》。此书于2024年7月出版…...

Android Framework(五)WMS-窗口显示流程——窗口布局与绘制显示

文章目录 relayoutWindow流程概览应用端处理——ViewRootImpl::setView -> relayoutWindowViewRootImpl::setViewViewRootImpl::performTraversalsViewRootImpl::relayoutWindow Surface的创建WindowManagerService::relayoutWindow了解容器类型和Buff类型的SurfaceBuff类型…...

【计网】计算机网络基础

当自律变成一种本能的习惯&#xff0c; 你就会享受到它的快乐。 --- 村上春树 --- 初识计算机网络 1 初识协议1.1 协议分层1.2 OSI七层模型1.3 TCP / IP协议 2 初识局域网2.1 什么是局域网2.2 MAC地址2.3 局域网通信 3 简单认识IP地址 1 初识协议 1.1 协议分层 首先&#…...

秃姐学AI系列之:实战Kaggle比赛:图像分类(CIFAR-10)

目录 准备工作 整理数据集 将验证集从原始的训练集中拆分出来 整理测试集 使用函数 图像增广 读取数据集 定义模型 定义训练函数 训练和验证数据集 对测试集进行分类并提交结果 准备工作 首先导入竞赛需要的包和模块 import collections import math import os i…...

nginx: [error] invalid PID number ““ in “/run/nginx.pid“

出现这个报错的原因 &#xff1a; 空值&#xff1a;“/run/nginx.pid” 文件为空或者内容不是有效的PID数字 文件损坏&#xff1a;如果PID文件被意外修改&#xff0c;例如被其他程序覆盖了内容&#xff0c;可能会显示为无效。 路径错误&#xff1a;Nginx无法找到指定的PID文件…...

Java使用Apache POI向Word文档中填充数据

Java使用Apache POI向Word文档中填充数据 向一个包含占位符的Word文档中填充数据&#xff0c;并保存为新的文档。 准备工作 环境搭建 在项目中添加Apache POI依赖。在pom.xml中添加如下依赖&#xff1a; <dependencies><dependency><groupId>org.apache.po…...

Gitflow基础知识

0.理想状态 现状 听完后的理想状态 没使用过 git 知道 git 是什么&#xff0c;会用 git 基础流程命令 用过 git&#xff0c;但只通过图形化界面操作 脱离图形化界面操作&#xff0c;通过 git 命令操作 会 git 命令 掌握 gitflow 规范&#xff0c;合理使用 rebase 和解决…...

NLP基础及其代码-tokenizer

基础知识 NLP-分词器&#xff1a;SentencePiece【参考Chinese-LLaMA-Alpaca在通用中文语料上训练的20K中文词表并与原版LLaMA模型的32K词表进行合并的代码】_sentencepiece 中文训练-CSDN博客 【OpenLLM 008】大模型基础组件之分词器-万字长文全面解读LLM中的分词算法与分词器…...

OpenCV结构分析与形状描述符(8)点集凸包计算函数convexHull()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 查找一个点集的凸包。 函数 cv::convexHull 使用斯克拉斯基算法&#xff08;Sklansky’s algorithm&#xff09;来查找一个二维点集的凸包&#…...

灰光模块,彩光模块-介绍

1. 引用 知识分享系列一&#xff1a;5G基础知识-CSDN博客 5G前传的最新进展-CSDN博客 灰光和彩光_通信行业5G招标系列点评之二&#xff1a;一文读懂5G前传-光纤、灰光、彩光、CWDM、LWDM、MWDM...-CSDN博客 ADOP带你了解&#xff1a;CWDM、DWDM、MWDM、LWDM&#xff1a;快速…...

python-新冠病毒

题目描述 假设我们掌握了特定时间段内特定城市的新冠病毒感染病例的信息。在排名 i 的当天有 i 个案例&#xff0c;即&#xff1a; 第一天有一例感染第二天有两例感染第三天有三例感染以此类推...... 请计算 n 天内的感染总数和每天平均感染数。 输入 整数 n 表示天数&…...

2023年408真题计算机网络篇

https://zhuanlan.zhihu.com/p/6954228062023年网络规划设计师上午真题解析TCP流量计算_哔哩哔哩_bilibili 1 1在下图所示的分组交换网络中&#xff0c;主机H1和H2通过路由器互联&#xff0c;2段链路的数据传输速率为100 Mb/s、时延带宽积 &#xff08;即单向传播时延带宽&am…...

分类学习器(Classification Learner App)MATLAB

在MATLAB中&#xff0c;分类学习器用于构建和评估分类模型。MATLAB提供了一些工具和功能&#xff0c;帮助你进行分类任务&#xff0c;例如分类学习器应用程序、统计和机器学习工具箱中的函数等。 数据集介绍 不同的人被要求在平板电脑上写字母"J"、“V"和&quo…...

DolphinDB 基准性能测试工具:金融模拟数据生成模块合集

测试 DolphinDB 数据库性能时&#xff0c;往往需要快速写入一些测试数据。为方便用户快速完成简单的基准性能测试&#xff0c;金融 Mock 数据生成模块覆盖了常用的金融数据集&#xff0c;满足用户生成模拟数据的需求。基于本模块生成的模拟数据不具有实际意义&#xff0c;建议仅…...

BUUCTF—[BJDCTF2020]The mystery of ip

题解 打开环境点击上面的flag可以看到这个IP页面。 抓个包看看有啥东西无&#xff0c;可以看到在返回包有IP。 看到IP就想到X-Forwarded-For这个玩意&#xff0c;我们用X-Forwarded-For随便添加个IP看看。可以看到返回的IP内容变成了123。 X-Forwarded-For:123 推测它会输出我…...

leecode100题-双指针-三数之和

给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 答案中不可以包含重复的三元组。 示例 1&#xff1a; 输入…...

计算机毕业设计PySpark+Django考研分数线预测 考研院校推荐系统 考研推荐系统 考研爬虫 考研大数据 Hadoop 大数据毕设 机器学习 深度学习

《PySparkDjango考研分数线预测与推荐系统》开题报告 一、研究背景与意义 随着教育水平的提高和就业竞争的加剧&#xff0c;越来越多的学生选择继续深造&#xff0c;参加研究生入学考试&#xff08;考研&#xff09;。然而&#xff0c;考研信息繁杂&#xff0c;选择专业和院校…...

Go语言多态实践以及gin框架c.BindJSON序列化遇到的坑

遇到的问题 如果定义的接收结构体字段是interface{}&#xff0c;在调用gin的 c.BindJSON 方法后会直接转为map&#xff0c; 导致无法断言为其他类型 场景 在创建工程请求中&#xff0c;根据工程类别的不同会有多种创建参数&#xff0c;比如 // A 类型需要编译 所以有这些字…...

SpringCloud神领物流学习笔记:项目概述(一)

SpringCloud神领物流学习笔记&#xff1a;项目概述&#xff08;一&#xff09; 文章目录 SpringCloud神领物流学习笔记&#xff1a;项目概述&#xff08;一&#xff09;1、项目介绍2、基本业务流程3、系统架构4、技术架构 1、项目介绍 ​ 神领物流是一个基于微服务架构体系的【…...

RocketMQ异步报错:No route info of this topic

在SpringBoot中发送RocketMQ异步消息的时候报错了&#xff0c;提示org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, testTopic1 这里给出具体的解决方案 一、Broker模块不支持自动创建topic&#xff0c;并且topic没有被手动创建过 R…...

Node.js学习记录(一)

目录 一、文件读取 readFile 二、写入文件 writeFile 三、动态路径 __dirname&#xff1a;表示当前文件所处的目录、path.join 四、获取路径文件名 path.basename 五、提取某文件中的css、JS、html 六、http 七、启动创建web服务器 服务器响应 八、将资源请求的 url 地…...

【AI】Pytorch_模型构建

建议点赞收藏关注&#xff01;持续更新至pytorch大部分内容更完。 本文已达到10w字&#xff0c;故按模块拆开&#xff0c;详见目录导航。 整体框架如下 数据及预处理 模型及其构建 损失函数及优化器 本节目录 模型线性回归逻辑回归LeNetAlexNet 构建模块组织复杂网络初始化网络…...

FFmpeg源码:avcodec_descriptor_get函数分析

一、avcodec_descriptor_get函数的声明 avcodec_descriptor_get函数声明在FFmpeg源码&#xff08;本文演示用的FFmpeg源码版本为7.0.1&#xff09;的头文件libavcodec/codec_desc.h中&#xff1a; /*** return descriptor for given codec ID or NULL if no descriptor exist…...

为数据仓库构建Zero-ETL无缝集成数据分析方案(下篇)

对于从事数据分析的小伙伴们来说&#xff0c;最头疼的莫过于数据处理的阶段。在我们将数据源的原始数据导入数据仓储进行分析之前&#xff0c;我们通常需要进行ETL流程对数据格式进行统一转换&#xff0c;这个流程需要分配专业数据工程师基于业务情况完成&#xff0c;整个过程十…...

ElMessageBox消息确认框组件在使用时如何设置第三个或多个自定义按钮

ElMessageBox自带两个按钮一个确认一个取消&#xff0c;当还想使用该组件还想再加个功能组件时,就需要自定义个按钮加到组件里 第二种方法可以通过编写自定义弹窗来完成,个人觉得代码量增多过于繁琐,当然也可以实现 先定义方法负责获取dom父节点&#xff0c;创建新的子元素加…...