文章目录
- 一、登录界面
-
- 1.前端代码
- 2.后端代码
- 二、添加功能
-
- 1.前端代码
- 2.后端代码
- 三、删除功能
-
- 1.前端代码
- 2.后端代码
- 四、修改功能
-
- 1.前端代码
-
- (1)修改路径
- (2)信息回显
- (3)隐藏域
- 2.后端代码
-
- (1)findUserServlet
- (2)updateUserServlet
- 五、删除选中功能
-
- 1.前端代码
-
- (1)单选
- (2)全选
- 2.后端代码
- 六、分页查询功能
-
- 1.前端代码
- 2.后端代码
-
- (1)封装pagebean
- (2)findUserByPageServlet
- 七、复杂条件查询
-
- 1.前端代码
- 2.后端代码
- 总结
一、登录界面
图片:
1.前端代码
- 改造验证码
<img src="${pageContext.request.contextPath}/checkCodeServlet" title="看不清点击刷新" id="vcode"/>
- 点击验证码刷新
加new Date().getTime()的原因在于,时间不重复,因此更新验证就不会重复。
<script type="text/javascript">
//切换验证码
function refreshCode(){
//1.获取验证码图片对象
var vcode = document.getElementById("vcode");
//2.设置其src属性,加时间戳
vcode.src = "${pageContext.request.contextPath}/checkCodeServlet?time="+new Date().getTime();
}
</script>
<a href="javascript:refreshCode();">
- 提交表单
<form action="${pageContext.request.contextPath}/loginServlet" method="post">
- 出错显示的信息框
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" >
<span>×</span>
</button>
<strong>${login_msg}</strong>
<!-- 对应后面的:request.setAttribute("login_msg","用户名或密码错误!"); -->
</div>
2.后端代码
- 设置编码
request.setCharacterEncoding("utf-8");
- 获取用户填写验证码,getParameter()的参数是验证码栏的name字段
<input type="text" name="verifycode" class="form-control" id="verifycode" placeholder="请输入验证码" style="width: 120px;"/>
String verifycode = request.getParameter("verifycode");//得到的是页面获取的验证码
- 验证码校验
checkCodeServlet里面,将生成的验证码存放在session中。
//将验证码放入HttpSession中
request.getSession().setAttribute("CHECKCODE_SERVER",checkCode);
equalsIgnoreCase()忽略大小写比较。
HttpSession session = request.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");//获取了生成的验证码
session.removeAttribute("CHECKCODE_SERVER");//确保验证码一次性
if(!checkcode_server.equalsIgnoreCase(verifycode)){
//验证码不正确
//提示信息
request.setAttribute("login_msg","验证码错误!");
//跳转登录页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}
注意:写到这里时,记得先验证是否正确。再进行下一步!!!!!
session.removeAttribute(“CHECKCODE_SERVER”);//确保验证码一次性,注意这一步!!!!
- 获取所有的数据(只有用户名和密码)
Map<String, String[]> map = request.getParameterMap();
- 封装User对象(参考request和reponse—常见问题)
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
- 调用Service查询
UserService service = new UserServiceImpl();
User loginUser = service.login(user);//查询我用户输入的账户是否存在
- 判断是否登录成功
if(loginUser != null){
//登录成功
//将用户存入session
session.setAttribute("user",loginUser);
//跳转页面
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else{
//登录失败
//提示信息
request.setAttribute("login_msg","用户名或密码错误!");
//跳转登录页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
注意:request没有共享数据,因此,登录成功之后,进行重定向!!!
注意:数据库的表需创建,还有配置文件需配置!
二、添加功能
分析图:
1.前端代码
- 修改添加联系人的跳转页面路径
<a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
- 修改头信息
<center><h3>添加联系人页面</h3></center>
<form action="${pageContext.request.contextPath}/addUserServlet" method="post">
注意要给表单加name,不然后端获取数据时,获取不了,为null!!!!
<input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
2.后端代码
- 设置编码
request.setCharacterEncoding("utf-8");
- 获取参数
Map<String, String[]> map = request.getParameterMap();
- 封装对象
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
- 调用Service保存
UserService service = new UserServiceImpl();
service.addUser(user);
- 跳转到userListServlet(注意:下面的不一样,后面会解释)
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");
(表单的校验)
三、删除功能
分析图:
上述的id,是数据库的id,不是下图的编号
1.前端代码
- id的传递,还有路径的改写
<a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/delUserServlet?id="+${user.id}">删除</a></td>
这样写有一个小问题就是,删除一条数据时,直接删除,如果用户是误操作,就会直接删除,用户的体验就不是很好。因此,我们可以将它换成如下操作。
function deleteUser(id){
location.href="${pageContext.request.contextPath}/delUserServlet?id="+${user.id};
}
}
<a class="btn btn-default btn-sm" href="javascript:deleteUser()});">删除</a></td>
但是这样写,有会有一个问题就是,user.id这里是获取不到的,解决办法就是传参。最终版。
function deleteUser(id){
//用户安全提示
if(confirm("您确定要删除吗?")){
//访问路径
location.href="${pageContext.request.contextPath}/delUserServlet?id="+id;
}
}
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a></td>
2.后端代码
- 获取id
String id = request.getParameter("id");
- 调用service删除
UserService service = new UserServiceImpl();
service.deleteUser(id);
- 跳转到查询所有Servlet
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");
四、修改功能
图解:
1.前端代码
删除这句,用不着
(1)修改路径
<a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>
(2)信息回显
- 姓名、年龄、QQ、email的回显(在findUserServlet的转发到update.jsp操作)
<input type="text" class="form-control" id="name" name="name" value="${user.name}" readonly="readonly" placeholder="请输入姓名" />
<input type="text" class="form-control" value="${user.age}" id="age" name="age" placeholder="请输入年龄" />
<input type="text" id="qq" class="form-control" value="${user.qq}" name="qq" placeholder="请输入QQ号码"/>
<input type="text" id="email" class="form-control" value="${user.email}" name="email" placeholder="请输入邮箱地址"/>
- 性别回显
<div class="form-group">
<label>性别:</label>
<c:if test="${user.gender == '男'}">
<input type="radio" name="gender" value="男" checked />男
<input type="radio" name="gender" value="女" />女
</c:if>
<c:if test="${user.gender == '女'}">
<input type="radio" name="gender" value="男" />男
<input type="radio" name="gender" value="女" checked />女
</c:if>
</div>
- 籍贯的回显
<div class="form-group">
<label for="address">籍贯:</label>
<select name="address" id="address" class="form-control" >
<c:if test="${user.address == '陕西'}">
<option value="陕西" selected>陕西</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
</c:if>
<c:if test="${user.address == '北京'}">
<option value="陕西" >陕西</option>
<option value="北京" selected>北京</option>
<option value="上海">上海</option>
</c:if>
<c:if test="${user.address == '上海'}">
<option value="陕西" >陕西</option>
<option value="北京">北京</option>
<option value="上海" selected>上海</option>
</c:if>
</select>
</div>
(3)隐藏域
<!-- 隐藏域 提交id-->
<input type="hidden" name="id" value="${user.id}">
2.后端代码
(1)findUserServlet
- 获取id
String id = request.getParameter("id");
- 调用Service查询
UserService service = new UserServiceImpl();
User user = service.findUserById(id);
- 将user存入request
request.setAttribute("user",user);
- 转发到update.jsp
request.getRequestDispatcher("/update.jsp").forward(request,response);
(2)updateUserServlet
- 设置编码
request.setCharacterEncoding("utf-8");
- 获取map
Map<String, String[]> map = request.getParameterMap();
- 封装对象
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
- 调用Service修改
UserService service = new UserServiceImpl();
service.updateUser(user);
- 跳转到查询所有Servlet
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");
五、删除选中功能
图解:
1.前端代码
(1)单选
- 获取选中条目的id,有多方案,最简单的一种,表单默认支持,选择条目的提交。想要提交,就要加name
<td><input type="checkbox" name="uid" value="${user.id}"></td>
- 点击删除选中,要进行提交表单,对删除选中添加单击事件
<a class="btn btn-primary" href="javascript:void(0);" id="delSelected">删除选中</a>
- 获取value值
不加就会获取不到数据库的id
<script>
//1.获取第一个cb
document.getElementById("firstCb").onclick = function(){
//2.获取下边列表中所有的cb
var cbs = document.getElementsByName("uid");
//3.遍历
for (var i = 0; i < cbs.length; i++) {
//4.设置这些cbs[i]的checked状态 = firstCb.checked
cbs[i].checked = this.checked;
}
}
</script>
<td><input type="checkbox" name="uid" value="${user.id}"></td>
(2)全选
- 下面的框跟第一个框的状态保持一致
第一个框
<th><input type="checkbox" id="firstCb"></th>
下面的框,遍历它,让它保持一致;注意判断是否有选中条目,如果没有选中的情况!!!!。
<script>
window.onload = function(){
//给删除选中按钮添加单击事件
document.getElementById("delSelected").onclick = function(){
if(confirm("您确定要删除选中条目吗?")){
var flag = false;
//判断是否有选中条目
var cbs = document.getElementsByName("uid");
for (var i = 0; i < cbs.length; i++) {
if(cbs[i].checked){
//有一个条目选中了
flag = true;
break;
}
}
if(flag){//有条目被选中
//表单提交
document.getElementById("form").submit();
}
}
}
</script>
<td><input type="checkbox" name="uid" value="${user.id}"></td>
2.后端代码
- 获取所有id
String[] ids = request.getParameterValues("uid");
- 调用service删除
UserService service = new UserServiceImpl();
service.delSelectedUser(ids);
-跳转查询所有Servlet
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");
六、分页查询功能
图解:
分析图:
1.前端代码
- 为什么改成pb.list?因为request.setAttribute(“pb”,pb);存入的是pb
<c:forEach items="${pb.list}" var="user" varStatus="s">
- 总记录和总页码的修改
<span style="font-size: 25px;margin-left: 5px;">
共${pb.totalCount}条记录,共${pb.totalPage}页
</span>
- 下面的修改
- 加激活状态,在li里面加class=“active”
<c:forEach begin="1" end="${pb.totalPage}" var="i" >
<c:if test="${pb.currentPage == i}">
<li class="active"><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">${i}</a></li>
</c:if>
<c:if test="${pb.currentPage != i}">
<li><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">${i}</a></li>
</c:if>
</c:forEach>
- 在最前面的,1之前的加禁用状态
<c:if test="${pb.currentPage == 1}">
<li class="disabled">
</c:if>
<c:if test="${pb.currentPage != 1}">
<li>
</c:if>
<c:if test="${pb.currentPage == pb.totalPage}">
<li class="disabled">
</c:if>
<c:if test="${pb.currentPage != pb.totalPage}">
<li>
</c:if>
还要在UserServiceImpl里的findUserByPage()里面加
if(currentPage <=0) {
currentPage = 1;
}else if (currentPage>totalPage){
currentPage = totalPage;
}
- 将来点击下面的页面,不是进入之前的userListServlet页面,而是进入findUserByPageServlet,所以其他的都要改
2.后端代码
(1)封装pagebean
(2)findUserByPageServlet
request.setCharacterEncoding("utf-8");
- 获取参数
String currentPage = request.getParameter("currentPage");//当前页码
String rows = request.getParameter("rows");//每页显示条数
//解决下面注意事项的问题
if(currentPage == null || "".equals(currentPage)){
currentPage = "1";
}
if(rows == null || "".equals(rows)){
rows = "5";
}
- 调用service查询
UserService service = new UserServiceImpl();
PageBean<User> pb = service.findUserByPage(currentPage,rows);
System.out.println(pb);
- 将PageBean存入request
request.setAttribute("pb",pb);
request.setAttribute("condition",condition);//将查询条件存入request
- 转发到list.jsp
request.getRequestDispatcher("/list.jsp").forward(request,response);
- 注意事项
后面不跟参数,就会报错
解决办法,在上面的代码中
七、复杂条件查询
图解:
1.前端代码
- 查询条件的回显
在findUserByPageServlet中将查询的数据添加到request
request.setAttribute("condition",condition);//将查询条件存入request
在list.jsp中进行value的赋值
<input type="text" name="name" value="${condition.name[0]}" class="form-control" id="exampleInputName2" >
<input type="text" name="address" value="${condition.address[0]}" class="form-control" id="exampleInputName3" >
<input type="text" name="email" value="${condition.email[0]}" class="form-control" id="exampleInputEmail2" >
-
当查询的值查询完之后,我们再点击分页时,就会变成没有查询之前全部的数据的分页,因此我们要在每个路径下拼接路径。
2.后端代码
- 获取条件查询参数
Map<String, String[]> condition = request.getParameterMap();
- 在UserDaoImpl中改造sql语句,用拼接的方式
- 拼接时,要注意: sb.append(" and “+key+” like ? ");and两边要加空格,不然拼接在一起,没有空格时,会报错;
- 还有解决 ? 里面传值的问题,因为值不确定,因此,用List params = new ArrayList();来接收参数
public int findTotalCount(Map<String, String[]> condition) {
//1.定义模板初始化sql
String sql = "select count(*) from user where 1 = 1 ";
StringBuilder sb = new StringBuilder(sql);
//2.遍历map
Set<String> keySet = condition.keySet();
//定义参数的集合
List<Object> params = new ArrayList<Object>();
for (String key : keySet) {
//排除分页条件参数
if("currentPage".equals(key) || "rows".equals(key)){
continue;
}
//获取value
String value = condition.get(key)[0];
//判断value是否有值
if(value != null && !"".equals(value)){
//有值
sb.append(" and "+key+" like ? ");
params.add("%"+value+"%");//?条件的值
}
}
System.out.println(sb.toString());
System.out.println(params);
return template.queryForObject(sb.toString(),Integer.class,params.toArray());
}
- 排除分页条件参数,如果不排除,就会报错
- params.add("%"+value+"%");如果写成了params.add(“value”);当查询的是姓李的人,就会导致没有结果。
-
添加分页的findByPage()方法中,最后加进去的sql语句,一定是拼接后的sql语句。
链接:完整代码
提取码:jzfa
总结
在上述的用红色写的,是不容易发现而且很容易出错的问题,需要大家注意。