用Struts2+MySQL作的名片管理系统
这个小项目做了好些天了,用实际一点的观点来说,项目并不难,或者说很容易,但可能是因为我第一次使用Struts2做东西吧,所以进度很慢,不过好在,终于在今天把它做完了。然后就可以很幸运的在下午开始另外一个项目,帮一个老师写些mfc的东西。本来这样的小东西是不足以这样写的,但想来想去还是决定贴出来,然后请大家帮我看看,提出宝贵的意见,这样自己才能成长起来。
为了节约版面,项目组织结构 图作为附件放在下面,如果有需要,请点击查看。
然后说一下主要的几个功能模块:com.javaeye.rennyit.cardms.db包下的三个类分别对应UserAction, CardAction, ClassAction三个类的数据库操作实现;com.javaeye.rennyit.cardms.main包下的三个类分别就是三种类型的Action实现了,pages中则为view层的一些东西。
接下来就是我自己的一些总结:
1:在真正开始写代码之前,整个系统的设计真的是非常重要,即便是这样一个小小的东西,也能够把这点体现出来。
2:如果真的想学好Struts2,还是弄本书好,这样进度也要快很多。而我做这个东西速度这样慢,我想这也其中的一个原因,每次自己遇到什么问题都要找来找去,然后再在猜想中摸索,时间就这样过去了。就像之前我写的那个,在action中处理多个请求一样,后面发现竟然是《Struts2权威指南》那个书上讲了的,而我自己去摸索了一天多才发现这种方法。不过话又说回来,自己摸索出来的东西会理解的深刻一些,到底怎样选择就看具体情况了。
3:书上还有网上好多人都在叫喊“要让view层只做显示的东西,便于维护和查错”,一开始我也是按照这样的思路跟想法在写,所以好多jsp文件中都是纯标签写出来的,没有看到js或者java代码(其实js我不会),不过速度相当地慢,尤其是在开始的时候对那些标签都不熟。可是后来,发现用纯标签都要做不下去了。问题是这样的:在scanCard.jsp页面中,把所有名片的信息显示出来,然后在每一条记录的后面就会有几个链接,如:详细信息、修改信息、删除等。这样的话,我开始的想法是用url或者什么标签来进行跳转,可是不知道怎样把当前访问到的那条名片记录作为参数传过去。于是,就开始想旁门歪道的方法去解决,最后就是把名片的编号(数据库该值为名片的主键)放在<a />中传到相应的页面中,再在那个页面里用java代码找出名片的对象,再进行操作,如读出名片的信息。这样,虽然问题解决了,但也引进了新的问题:Struts2的标签中不允许使用表达式,google之后都说版本问题,然后就直接用html标签来解决了。不过这样,对于那些input中type为radio或者select的又成了问题,因为select的选项是未知的,也就不能够在代码中直接都添加出来。直到最后都是没法更改性别跟名片所属联系人类别。
4:在这个小小项目中,我感到最麻烦也是用得最多的三个符号就是”# $ %",感觉变来变去好模糊,还是只知道几个用得多的用法。
5:虽然我是第一次用Struts2做东西,不敢说自己有什么深刻地理解。但我觉得Struts2在应用中的作用就是提供一个框架和一堆标签。框架用来实现页面的转发和拦截action请求,标签就不说了,其他的标签库也是一样的,并没有传说中的那么神奇,也没有那么大的难度。
6:还有一个疑问就是session在程序中是一个怎样的身份。我开始的时候把好多信息都保存在session中,然后在jsp页面中就可以直接通过session访问。开始还没觉得有什么问题,后面写得多了,就发现这个session越来越大了,无疑就是在增加网络的负担。后面跟一个网友交流了一下,他说通常都是直接在jsp页面中访问数据库,让我更加疑惑了,虽然这样可以给session减负,但在view层访问DB是不是太危险了一点啊?而且与鼓吹的要保持view层干净似乎有些不合。但不这样的话,问题也是很显然的,这个小小项目中现在都还有一个bug就是把数据保存在session中引起的,可以通过在jsp页面中访问DB来解决,不过我还是就这样放着,没有修改。
为了更好地让大家提出宝贵的意见,决定将db和main包下各贴一个类上来。db包下的UserDAO类代码如下:
package com.javaeye.rennyit.cardms.db; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.sql.DriverManager; import java.sql.SQLException; /**关于表User的操作 * @author Renny */ @SuppressWarnings("finally") public class UserDAO { private static final String dburl = "jdbc:mysql://localhost:3306/" + "Cardms?user=root&password=mysql"; private static Connection con = null; private static Statement stm = null; private static ResultSet result = null; public UserDAO() {} /** * 根据给定的username及password在数据库中查询该用记是否存在或者帐号密码是否匹配 * 如果userName存在且password正确,则返回true;否则返回false */ public static boolean isExist(String userName, String password) { String mysql = "Select * From user Where userName = '" + userName + "' AND password = '"+ password + "';"; boolean flag = false; try { con = DriverManager.getConnection(dburl); stm = con.createStatement(); result = stm.executeQuery(mysql); if(result.next()) flag = true; result.close(); stm.close(); con.close(); } catch(SQLException e) { e.printStackTrace(); } finally { return flag; } } /** * 判断给出的用户名是否已经存在于数据库中 * @param userName = 要查询的用户名 * @return 如果存在在数据库,则返回true;否则返回false */ public static boolean isExist(String userName) { String mysql = "Select * From user Where userName = '" + userName + "';"; boolean flag = false; try { con = DriverManager.getConnection(dburl); stm = con.createStatement(); result = stm.executeQuery(mysql); if(result.next()) flag = true; result.close(); stm.close(); con.close(); } catch(SQLException e) { e.printStackTrace(); } finally { return flag; } } /** * 根据给出的用户名及密码创建新的用户帐号 * @param userName, password * @return 如果添加用户成功则返回true;否则返回false */ public static boolean addUser(String userName, String password) { String mysql = "Insert Into user Values('"+userName+"','"+password+"');"; boolean flag = false; try { con = DriverManager.getConnection(dburl); stm = con.createStatement(); stm.executeUpdate(mysql); stm.close(); con.close(); flag = true; } catch(SQLException se) { se.printStackTrace(); } finally { return flag; } } /* * test this class */ public static void main(String[] args) { System.out.println(UserDAO.isExist("rennyit", "rennyit")); UserDAO.addUser("renny", "renny"); } }
然后就是一个main包下的类-UserAction
package com.javaeye.rennyit.cardms.main; import java.util.List; import java.util.Map; import org.apache.struts2.ServletActionContext; //import com.opensymphony.xwork2.ActionContext; import com.javaeye.rennyit.cardms.db.CardDAO; import com.javaeye.rennyit.cardms.db.ClassDAO; import com.javaeye.rennyit.cardms.db.UserDAO; import com.opensymphony.xwork2.ActionSupport; //public class UserAction { public class UserAction extends ActionSupport { private static final long serialVersionUID = 1L; private String userName; private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * 实现登录信息校验 */ public void validateLogin() { if(!UserDAO.isExist(userName, password)) { System.out.println("帐号或密码错误"); addFieldError("userName", "帐号或密码错误"); } } /** * 登录到系统的判断方法, 实现相关信息的保存到session中 * @return */ public String login() { //将登录成功的信息放到Session中 //用ActionContext实现 /*ActionContext ac = ActionContext.getContext(); Map<String,Object> sessionMap = ac.getSession(); sessionMap.put("userName", userName); sessionMap.put("password", password); */ //用ServletActionContext实现 //将用户的登录信息放入到session中 Map<String,Object> session = ServletActionContext.getContext().getSession(); session.put("userName", userName); session.put("password", password); //将用户所有的联系人类别名字保存到session中 List<String> classNameList = null; classNameList = ClassDAO.getClassNames(userName); session.put("classNameList", classNameList); //将用户所有的联系人类别信息保存到session中 List<ClassAction> classList = null; classList = ClassDAO.getClasses(userName); session.put("classList", classList); //将该用户的联系人信息添加到session中 List<CardAction> cardList = null; cardList = CardDAO.queryCard(userName); session.put("cardList", cardList); /*int cardNum = cardList.size(); System.out.println("Card Number:"+cardNum); for(int i = 0; i < cardNum; i++) { System.out.println(cardList.get(i).getCardId()); System.out.println(cardList.get(i).getUserName()); System.out.println(cardList.get(i).getName()); System.out.println(cardList.get(i).getTel()); System.out.println(cardList.get(i).getAddress()); }*/ return SUCCESS; } /** * 实现注册时信息的检验 */ public void validateRegister() { String regUserName = ServletActionContext.getRequest(). getParameter("userName"); String regPsw = ServletActionContext.getRequest().getParameter("password"); String regPswCon = ServletActionContext.getRequest(). getParameter("pswConfirm"); if(regUserName.equals("")) addFieldError("userName","用户名不能为空"); else if(!regPsw.equals(regPswCon)) addFieldError("password","两次输入密码不一致"); else if(UserDAO.isExist(regUserName)) addFieldError("userName","该用户名已存在"); } /** * 注册用户登录帐号的方法 * @return */ public String register() { String regUserName = ServletActionContext.getRequest(). getParameter("userName"); String regPsw = ServletActionContext.getRequest(). getParameter("password"); UserDAO.addUser(regUserName,regPsw); Map<String,Object> session = ServletActionContext.getContext().getSession(); session.put("userName", regUserName); session.put("password", regPsw); return SUCCESS; } /* * test this class */ public static void main(String[] args) { UserAction test = new UserAction(); test.setUserName("rennyit"); test.setPassword("rennyit"); //System.out.println(test.execute()); } }
如果有必要,可以将整个项目都打包传上来,强烈欢迎大家帮我指正,提出宝贵的意见,谢谢
# * 实现注册时信息的检验
# */
# public void validateRegister() {
# String regUserName = ServletActionContext.getRequest().
# getParameter("userName");
# String regPsw = ServletActionContext.getRequest().getParameter("password");
# String regPswCon = ServletActionContext.getRequest().
# getParameter("pswConfirm");
# if(regUserName.equals(""))
# addFieldError("userName","用户名不能为空");
# else if(!regPsw.equals(regPswCon))
# addFieldError("password","两次输入密码不一致");
# else if(UserDAO.isExist(regUserName))
# addFieldError("userName","该用户名已存在");
# }
#
这个代码不用吧...
struts2 的 ActionSupport下面不是有个validation的方法么..?
你把他重写下...
# private String userName;
# private String password;
这个两个不是在这个类下面的方法么???不用从request里面取得...
这个代码不用吧...struts2 的 ActionSupport下面不是有个validation的方法么..?你把他重写下...# private String userName; # private String password; 这个两个不是在这个类下面的方法么???不用从request里面取得...
首先非常谢谢你帮我指出问题。
如果现在再写的话,确实不用了,当时写的时候都是自己摸着写的,所以有些问题就。。。
validate那个方法是个通用的校验方法,也就是说在login跟register中提交的数据都会被用相同的方法检验,这样应该是不合要求的
后来知道客户端的校验可以通过js来实现
后面那个我确实是用错了,完全没理解问题
自己是学生,然后尝试着学下struts2,错误的地方请多多指正