之前的用户管理系统在设计上有很多不合理的地方,这种方法是将界面和业务逻辑放在一起(model1模式),存在以下问题:
- 在loginCl.java文件和wel.java文件中都操作了数据库,它们的逻辑相似,有重复的代码
- 整个框架没有清晰的逻辑结构,显得比较乱
- 代码不够优雅,可读性差,可维护性差
通过对问题的分析,我们可以对程序进行改进:
- 进行分层,分为界面层和逻辑层(MV模式,M:model模型,V:view视图)
- 将常用的代码(比如说连接数据库),封装到类
改进后的框架图如下所示:
下面是修改后的代码:
ConnDB.java:
/** * @(#)ConnDB.java * *连接到数据库 * @author * @version 2.00 2017/3/26 */ package com.chongqing; import java.sql.*; public class ConnDB { private Connection ct = null; public Connection getConn(){ try { //连接到数据库 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); ct = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;DatabaseName=TestServlet","sa","293313"); } catch (Exception ex) { ex.printStackTrace(); } //不用关闭资源 return ct; } }
UserBean.java:
/** * @(#)UserBean.java * *映射到数据库中的users表,它的一个对象与users表的一条记录相对应,操作UserBean就相当于操作数据库 * @author * @version 2.00 2017/3/26 */ package com.chongqing; public class UserBean { private int userId; private String userName; private String passwd; private String mail; private int grade; //userId的方法 public void setUserId(int userId){ this.userId = userId; } public int getUserId(){ return this.userId; } //userName的方法 public void setUserName(String userName){ this.userName = userName; } public String getUserName(){ return this.userName; } //passwd的方法 public void setPasswd(String passwd){ this.passwd = passwd; } public String getPasswd(){ return this.passwd; } //mail的方法 public void setMail(String mail){ this.mail = mail; } public String getMail(){ return this.mail; } //grade的方法 public void setGrade(int grade){ this.grade = grade; } public int getGrade(){ return this.grade; } }
UserBeanCl.java:
/** * @(#)UserBeanCl.java *业务逻辑和处理类,用来处理users表,即操作UserBean * * @author * @version 2.00 2017/3/26 */ package com.chongqing; import java.sql.*; import java.util.*; public class UserBeanCl { private Connection ct = null; private PreparedStatement ps = null; private ResultSet rs = null; private int pageCount = 0; //一共有多少页(通过计算获得) //验证用户 public boolean checkUser(String u,String p){ boolean flag = false; try { //得到连接 ConnDB cd = new ConnDB(); ct = cd.getConn(); ps = ct.prepareStatement("select * from users where username = ? and passwd = ?"); ps.setString(1,u); ps.setString(2,p); rs = ps.executeQuery(); if(rs.next()){ flag = true; } } catch (Exception ex) { ex.printStackTrace(); } finally { this.close(); } return flag; } //分页显示结果 //不能返回ResultSet,因为关闭数据库资源的时候ResultSet也将消失,这里是返回ArrayList public ArrayList getResultByPage(int pageNow,int pageSize){ ArrayList al = new ArrayList(); try { int rowCount = 0; //一共有多少行记录(通过查表获得) //连接数据库 ConnDB cd = new ConnDB(); ct = cd.getConn(); ps = ct.prepareStatement("select count(*) from users"); rs = ps.executeQuery(); if(rs.next()){ rowCount = rs.getInt(1);//获得rowCount的值 } //计算pageCount的值 if(rowCount%pageSize == 0){ pageCount = rowCount/pageSize; }else{ pageCount = rowCount/pageSize + 1; } ps = ct.prepareStatement("select top "+pageSize+" * from users where userID not in (select top "+pageSize*(pageNow-1)+" userID from users)"); rs = ps.executeQuery(); while(rs.next()){ //将rs中的每条记录封装到UserBean ub中 UserBean ub = new UserBean(); ub.setUserId(rs.getInt(1)); ub.setUserName(rs.getString(2)); ub.setPasswd(rs.getString(3)); ub.setMail(rs.getString(4)); ub.setGrade(rs.getInt(5)); al.add(ub); //将ub添加到ArrayList中 } } catch (Exception ex) { ex.printStackTrace(); } finally { this.close(); } return al; } //返回pageCount public int getPageCount(){ return this.pageCount; } //关闭资源 public void close(){ try { if(null != rs){ rs.close(); rs = null; } if(null != ps){ ps.close(); ps = null; } if(null != ct){ ct.close(); ct = null; } } catch (SQLException e) { e.printStackTrace(); } } }
登录界面:
/** * @(#)Login.java * *登录界面 * @author * @version 2.00 2017/3/26 */ package com.chongqing; import javax.servlet.http.*; import java.io.*; public class Login extends HttpServlet { //处理get请求 public void doGet(HttpServletRequest req,HttpServletResponse res){ //业务逻辑 try { //中文乱码 res.setContentType("text/html;charset=gbk"); PrintWriter pw = res.getWriter(); //登录界面 pw.println("<html>"); pw.println("<body>"); //接收wel.java的错误信息 String info = req.getParameter("info"); if(null != info) { pw.println("<h1>用户名或者密码错误!</h1><br/>"); } pw.println("<h1>登录界面</h1>"); pw.println("<form action= logincl method=post>"); pw.println("用户名:<input type=text name=username><br>"); pw.println("密码:<input type=password name=passwd><br>"); pw.println("<input type=checkbox name=keep value=2>两周内不重复登录<br> "); pw.println("<input type=submit value=login><br>"); pw.println("</form>"); pw.println("</body>"); pw.println("</html>"); } catch (Exception ex) { ex.printStackTrace(); } } public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res); } }
登录验证界面:
/** * @(#)LoginCl.java * *验证页面 * @author * @version 2.00 2017/3/26 */ package com.chongqing; import javax.servlet.http.*; public class LoginCl extends HttpServlet { //处理get请求 public void doGet(HttpServletRequest req,HttpServletResponse res){ //接收用户名和密码 String u = req.getParameter("username"); String p = req.getParameter("passwd"); try { //验证用户 UserBeanCl ubc = new UserBeanCl(); if(ubc.checkUser(u,p)){ //合法 //接收Login.java的checkbox的值 String keep = req.getParameter("keep"); if(null != keep){ //将用户名和密码通过Cookie保存到客户端 //创建Cookie Cookie name = new Cookie("myname",u); Cookie passwd = new Cookie("passwd",p); //设置时间,保存两周 name.setMaxAge(2*7*24*3600); passwd.setMaxAge(2*7*24*3600); //回写到客户端 res.addCookie(name); res.addCookie(passwd); } //合法,添加Session并跳转到欢迎界面 HttpSession mySession = req.getSession(true); mySession.setMaxInactiveInterval(30); //指定Session存活的时间,单位是秒 mySession.setAttribute("usname",u); //在Session中添加一个属性 res.sendRedirect("wel");//转到wel界面 }else{ //不合法 res.sendRedirect("login");//返回login界面 } } catch (Exception ex) { ex.printStackTrace(); } } public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res); } }
欢迎界面:
/** * @(#)wel.java * *欢迎界面 * @author * @version 2.00 2017/3/26 */ package com.chongqing; import javax.servlet.http.*; import java.io.*; import java.sql.*; import java.util.*; public class wel extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){ Connection ct = null; PreparedStatement ps = null; ResultSet rs = null; //首先判断Session中是否有登录时添加的属性 HttpSession mySession = req.getSession(true); String val = (String)mySession.getAttribute("usname"); try{ if(null == val){ //如果session中没有用户信息,再看看Cookie中有没有 String name = null; String passwd = null; //从客户端获得所有Cookie Cookie[] allCookies = req.getCookies(); if(null != allCookies){ for(int i=0; i < allCookies.length; ++i){ //依次取出Cookie Cookie myCookie = allCookies[i]; if(myCookie.getName().equals("myname")){ //得到Cookie的值 name = myCookie.getValue(); }else if(myCookie.getName().equals("passwd")){ passwd = myCookie.getValue(); } } } //如果用户名和密码都不为空 if(!name.equals("")&&!passwd.equals("")){ //到loginCl中进行验证是否用户名和密码合法 res.sendRedirect("logincl?username="+name+"&passwd="+passwd); return; } //返回登录界面 res.sendRedirect("login?info=error"); return; } //欢迎界面 //中文乱码 res.setContentType("text/html;charset=gbk"); PrintWriter pw = res.getWriter(); //把所有内容放在中间 pw.println("<body><center>"); pw.println("Welcom!"); //分页的功能 int pageSize = 3; //每页显示3条记录 int pageNow = 1; //首先显示第一页的内容 //动态的接收pageNow String sPageNow = req.getParameter("pageNow"); if(null != sPageNow){ pageNow = Integer.parseInt(sPageNow); } UserBeanCl ubc = new UserBeanCl(); ArrayList al = ubc.getResultByPage(pageNow,pageSize); //用表格显示用户的信息 pw.println("<table border = 1>"); pw.println("<tr><td>userID</td><td>username</td><td>passwd</td><td>email</td><td>grade</td></tr>"); for(int i=0; i<al.size();++i){ //读取每个UserBean中的值 UserBean ub = (UserBean)al.get(i); pw.println("<tr>"); pw.println("<td>"+ub.getUserId()+"</td>"); pw.println("<td>"+ub.getUserName()+"</td>"); pw.println("<td>"+ub.getPasswd()+"</td>"); pw.println("<td>"+ub.getMail()+"</td>"); pw.println("<td>"+ub.getGrade()+"</td>"); pw.println("</tr>"); } pw.println("</table>"); //显示超链接 if(1 != pageNow){ pw.println("<a href=wel?pageNow="+1+">首页</a>"); } int pageCount = ubc.getPageCount(); for(int i=1; i<=pageCount; ++i ){ pw.println("<a href=wel?pageNow="+i+">"+i+"</a>"); } if(pageCount != pageNow){ pw.println("<a href=wel?pageNow="+pageCount+">尾页</a>"); } pw.println("</body></center>"); } catch (Exception ex) { ex.printStackTrace(); } } public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res); } }
程序的功能值之前修改前的功能一样。