Web综合实践之用户信息管理
前言
在Web阶段也学习了近一个月左右,对于这些知识点也有了一些了解,关于前后端的一个交互有了初步认识,这一篇博客是用来总结自己写过的一个小的综合案例,其实增删改查的操作都很简单了,最重要的是如何将前端和后端连接起来的思想。
登录功能
界面展示
后端代码思路分析
LoginServlet 类的代码编写流程:
1.设置编码
request.setCharacterEncoding("utf-8");
2.获取数据:获取用户填写的验证码
String verifycode = request.getParameter("verifycode");
3.验证码校验
如果验证失败:
1、先设置提示信息
request.setAttribute("login_msg","验证码错误");
2、再跳转界面,跳转回登录界面(使用转发)
为什么要跳转呢?仔细想想,点击登录按钮后,系统自动将数据拿到数据库进行比较
如果登录失败就要跳转到登录界面,而登录成功就需要跳转到另一个系统界面
所以这里要做跳转这一步,后面都会使用到跳转,就不再详细解释了
request.getRequestDispatcher("/login.jsp").forward(request,response);
4.封装User对象
将前端获取的数据进行封装,封装成实体类User(用户信息实体类)对象,这里使用的是 BeanUtils类的 populate 方法,参数为 :(存储数据的对象,要转换的对象)
5.调用Service查询
调用Service实现类中的方法将封装后的对象 user 与数据库中的数据进行比较,这里要说明:
根据三层架构,我们分为:
1.界面层(表示层):用户看的得界面。用户可以通过界面上的组件和服务器进行交互
2.业务逻辑层:处理业务逻辑的。(接口命名为Service,实现类为ServiceImp)
3.数据访问层:操作数据存储文件。(接口命名为Dao,实现类为DaoImp)
6.判断是否登录成功
验证成功
1、把数据存入session
session.setAttribute("user",login_user);2、跳转页面(重定向)
response.sendRedirect(request.getContextPath()+"/index.jsp");
验证失败
1、提示信息
request.setAttribute("login_msg","用户名或密码错误");2、跳转登录界面
request.getRequestDispatcher("/login.jsp").forward(request,response);
前端代码分析
1.为表单设置action属性,设置表单提交的地址,其中
${pageContext.request.contextPath}
用来替代虚拟路径,这样就不用再更换虚拟路径后又一个个进行修改
<formaction="${pageContext.request.contextPath}/loginServlet"method="post">
2.给每一个文本框添加 id 属性,因为要将文本框的数据传入后端,传入的数据是一个map集合,key 就是 id 的内容,例如:
<inputtype="text"name="username"class="form-control"id="user"placeholder="请输入用户名"/>
3.登录界面肯定需要验证码,添加一张验证码的图,
"href="javascript:refreshCode();"
是为该链接添加一个函数,使之能切换不同的验证码
验证码的div如下:
<divclass="form-inline"><labelfor="vcode">验证码:</label><inputtype="text"name="verifycode"class="form-control"id="verifycode"placeholder="请输入验证码"style="width: 120px;"/><ahref="javascript:refreshCode();"><imgsrc="${pageContext.request.contextPath}/checkCodeServlet"title="看不清点击刷新"id="vcode"/></a></div>
验证码的script:
<scripttype="text/javascript">//切换验证码functionrefreshCode(){//1.获取验证码图片对象var vcode = document.getElementById("vcode");//2.设置其src属性,加时间戳
vcode.src ="${pageContext.request.contextPath}/checkCodeServlet?time="+newDate().getTime();}</script>
4.修改错误提示框里的提示信息,
<strong>xxx</strong>
中的xxx改为
${login_msg}
,在Servlet中会定义这个信息,并用setAttribute()方法传入request中
<!-- 出错显示的信息框 --><divclass="alert alert-warning alert-dismissible"role="alert"><buttontype="button"class="close"data-dismiss="alert"><span>×</span></button><strong>${login_msg}</strong></div>
增加功能
界面展示
后端代码思路分析
1.设置编码
设置编码的作用主要是为了防止乱码,代码如下:
request.setCharacterEncoding("utf-8");
2.获取参数
这里的参数指的是页面里输入的数据(前端输入的数据),获取到后端,再到数据库中进行查询和比较,使用的是 getParameterMap() 方法
3.封装对象
将前端获取的数据进行封装,封装成实体类User(用户信息实体类)对象,这里使用的是 BeanUtils类的 populate 方法,参数为 :(存储数据的对象,要转换的对象)
4.调用Service
调用Service实现类中的方法将封装后的对象 user 与数据库中的数据进行比较
5.跳转到 FindUserByPageServlet(重定向)
前端代码分析
1.为表单设置action属性,设置表单提交的地址,其中
${pageContext.request.contextPath}
用来替代虚拟路径,这样就不用再更换虚拟路径后又一个个进行修改:
<form action="${pageContext.request.contextPath}/addUserServlet" method="post"
2.给每一个文本框添加 id 属性,因为要将文本框的数据传入后端,传入的数据是一个map集合,key 就是 id 的内容,例如:
<inputtype="text"class="form-control"id="age"name="age"required="required"placeholder="请输入年龄">
删除功能
删除单个联系人
下面的图是删除单个联系人的流程思路:
首先获取参数(获取的是需要删除的联系人的Id)
然后是调用service的删除的方法(这里需要注意的是,当删除的时候应该给用户一个提示是否删除联系人?这样才能给用户一个更好的体验,避免误删的发生)
最后再跳转到主界面
相关代码
package cn.itcast.web.servlet;import cn.itcast.service.UserService;import cn.itcast.service.impl.UserServiceImpl;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/delUserServlet")publicclassDelUserServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.获取id
String id = request.getParameter("id");//2.调用service
UserService service=newUserServiceImpl();
service.deleteUser(id);//3.跳转
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.doPost(request, response);}}
删除选中
下面的图是删除选中的联系人的流程思路:
首先获取得到一个id的数组,因为删除的选中的联系人,所以得到的是一个数组.
这里需要注意的是也要给用户一个提示是否删除让用户有更好的体验, 然后调用service的删除的方法, 然后再跳转到主页面.
相关代码
ackage cn.itcast.web.servlet;import cn.itcast.service.UserService;import cn.itcast.service.impl.UserServiceImpl;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/delSelectedServlet")publicclassDelSelectedServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.获取所有id
String[] ids = request.getParameterValues("uid");//2.调用service删除
UserService service =newUserServiceImpl();
service.delSelectedUser(ids);//3.跳转查询所有Servlet
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.doPost(request, response);}}
修改功能
代码思路分析
下图是修改联系人的信息的流程思路:
首先得设置编码,因为有中文得输入,这里需要注意得是需要弄一个影藏域得id,还要弄一个回显得信息,让用户有更好得体验,然后是获取单表得数据用map,封装user得对象,调用service得修改得方法
再跳转到主界面 。
相关代码
package cn.itcast.web.servlet;import cn.itcast.domain.User;import cn.itcast.service.UserService;import cn.itcast.service.impl.UserServiceImpl;import org.apache.commons.beanutils.BeanUtils;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.util.Map;@WebServlet("/updateUserServlet")publicclassUpdateUserServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.设置编码
request.setCharacterEncoding("utf-8");//2.获取map
Map<String, String[]> map = request.getParameterMap();//3.封装对象
User user=newUser();try{
BeanUtils.populate(user,map);}catch(IllegalAccessException e){
e.printStackTrace();}catch(InvocationTargetException e){
e.printStackTrace();}//4.调用service
UserService service=newUserServiceImpl();
service.updateUser(user);//5.跳转
response.sendRedirect(request.getContextPath()+"/findUserByPageServlet");}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.doPost(request, response);}}
分页查询功能
代码思路分析
做分页查询得时候比较得复杂,也是跟以上比起来最难的地方思路图上已经很清晰了
前端代码展示
<div><navaria-label="Page navigation"><ulclass="pagination"><!-- 左角标 --><c:iftest="${pb.currentPage == 1}"><liclass="disabled"></c:if><c:iftest="${pb.currentPage != 1}"><li></c:if><ahref="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pb.currentPage - 1}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}"aria-label="Previous"><spanaria-hidden="true">«</span></a></li><!-- 页码 --><c:forEachbegin="1"end="${pb.totalPage}"var="i"><c:iftest="${pb.currentPage == i}"><liclass="active"><ahref="${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:iftest="${pb.currentPage != i}"><li><ahref="${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><!-- 右角标 --><c:iftest="${pb.currentPage==pb.totalPage}"><liclass="disabled"></c:if><c:iftest="${pb.currentPage != pb.totalPage}"><li></c:if><ahref="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pb.currentPage + 1}&rows=5&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}"aria-label="Next"><spanaria-hidden="true">»</span></a></li><!-- 备注 --><spanstyle="font-size: 25px;margin: 5px">
共${pb.totalCount}条数据,共${pb.totalPage}页
</span></ul></nav></div>
上述代码大致分为四个部分:"<" 、页码数字、">"、一共多少数据
- (1) 每个部分的链接地址都由
${pageContext.request.contextPath}
+实际地址
+当前页码
+每页显示的记录数
+文本框的值信息
组成,这样就组成了复制分页查询的分页条 - (2) 在 “<” 和 “>” 的部分做了 if 选择,当页码为1或者最大时,再点击 “<” 和 “>” 图标,就会显示无法点击的图标,用法是给
li
标签添上class="disabled"
属性,但是实际上还是能点击,并且网页会报错,但是这个问题在后端已经解决了 - (3) 在页码数字的部分做了 if 选择,使每个当前页码的样式与其他的页码样式不一样,用法是给
li
标签添上class="active"
属性
版权归原作者 铅华殿 所有, 如有侵权,请联系我们删除。