🍃后台分页
程序框架图
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.Integer
return ((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 = 0
int 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.粘贴首页的分页导航代码
<!-- 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.新建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.jsp
req.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"><i
class="icon-size-fullscreen"></i></a>
</div>
<button title="Add To Cart" class=" add-to-cart">Add
To 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 = 0
int 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都没有, 接收到的是null
String 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.jsp
req.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.jsp
到furn_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>
🍅验证码
表单重复提交情况
- 提交完表单. 服务器使用请求转发进行页面跳转. 用户刷新(F5), 会发起最后一次的请求, 造成表单重复提交问题. 解决:用重定向.
- 用户正常提交, 由于网络延迟等原因, 未收到服务器的响应. 这时, 用户着急多点了几次提交操作, 也会造成表单重复提交. 解决: 验证码
- 用户正常提交, 服务器也没有延迟, 但是提交完成后, 用户回退浏览器. 重新提交, 也会造成表单重复提交. 解决: 验证码
- 恶意注册, 使用可以批量发送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);
}
}