Chinaunix首页 | 论坛 | 博客
  • 博客访问: 105251
  • 博文数量: 17
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 184
  • 用 户 组: 普通用户
  • 注册时间: 2013-05-20 11:19
个人简介

学习内核中~

文章分类

全部博文(17)

文章存档

2013年(17)

我的朋友

分类: Java

2013-07-20 16:19:33

其实代码也是跟着课本抄的,只不过记录下对这个程序的改进,以及一些错误解决和感想。

创建数据库:

点击(此处)折叠或打开

  1. create databese guest;
  2. use guest;

  3. // 创建user表
  4. create table user (
  5.     id int not null auto_increment,
  6.     username varchar(20) not null,
  7.     password varchar(20) not null,
  8.     primary key(id)
  9. );

  10. // 创建留言表
  11. create table message (
  12.     id int not null auto_increment,
  13.     userId int not null,
  14.     date datetime not null,
  15.     title varchar(20) not null,
  16.     content varchar(50) not null,
  17.     primary key(id)
  18. );
MySql错误1067:
昨天还用得好好的,今天就不行了,客户端都连接不上MySql,网上都是说my.ini文件出错,经过排查,发现其实是我昨天把MySql安装的时候自带的mysql数据库删除了,所以最终只能重装MySql。

Date类的格式化输出:
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());,如果是yyyy-MM-dd格式的输出,调用Date类的toString方法就行了。

提交数据的一个BUG:
举个例子,当我注册一个用户时,如果我不填用户名和密码,根据查询语句
String sql = "insert into user (username,password) values('" + username + "','" + password + "')";
结果生成的查询语句是 "insert into user (username,password) values(‘null’,‘null’),也就是说会创建一个用户名和密码都为“null”的账号,提交留言的时候也是这个道理,如果用课本的PreparedStatement类的方式来生成查询语句,那么当username和password为null时,相应的位置会被替换成空串,因此对于数据有效性的检查,我们应该放在客户端或服务端脚本来做,不要以为MySql会帮你做这个检查。

几个改进的地方:
1、只允许一个用户登录
一个会话不需要重复登录,意思就是如果你已经登录了,你进入登录界面后会直接跳转到主界面,在login.jsp的开头加上

点击(此处)折叠或打开

  1. User user = (User)session.getAttribute("user");
  2. if (user != null) {
  3.     response.sendRedirect("mainServlet");
  4.     return;
  5. }
sendRedirect是发送到客户端执行的,在一个页面中不允许执行两次sendRedirect,因此最好加上return语句。

2、增加自动登录功能
用cookies实现自动登录,如果在登陆的时候勾选了自动登录复选框,则在cookies失效之前都会自动登录。
在mainServlet中,如果user不为null(存在该用户),则执行如下代码

点击(此处)折叠或打开

  1. String[] values = request.getParameterValues("auto_login");
  2. // 如果勾选了自动登录
  3. if (values != null) {
  4.     Cookie autoCookie = new Cookie("username", user.getUsername());
  5.     // 一定要设置cookie的存在时间
  6.     autoCookie.setMaxAge(3600*24*7);
  7.     response.addCookie(autoCookie);

  8.     autoCookie = new Cookie("password", user.getPassword());
  9.     autoCookie.setMaxAge(3600*24*7);
  10.     response.addCookie(autoCookie);
  11. }
有了cookies之后,每次进入登录界面我们都要检查是否存在cookies,因此在login.jsp的开头加入

点击(此处)折叠或打开

  1. String username = null;
  2. String pwd = null;
  3. Cookie[] cookies = request.getCookies();

  4. // 检查是否存在cookies,免得出现空指针错误        
  5. if (cookies != null) {
  6.     for (int i = 0; i != cookies.length; i++) {
  7.         if (cookies[i].getName().equals("username")) {
  8.             username = cookies[i].getValue();
  9.         } else if (cookies[i].getName().equals("password")) {
  10.             pwd = cookies[i].getValue();
  11.         }
  12.     }
  13. }
  14. // 如果存在该用户,才跳转到mainServlet        
  15. if (username != null && pwd != null) {
  16.     DB db = new DB();
  17.     user = db.checkUser(username, pwd);
  18.     if (user != null) {
  19.         session.setAttribute("user", user);
  20.         response.sendRedirect("mainServlet");
  21.     }
  22. }
在这里犯了一个错误,就是用“==”来比较一个String引用和一个字符串常量,应该用String类的equals方法。如果在这里不先检查是否存在该用户再跳转,那么如果在mainServlet那里检查不到该用户,就会跳转回去login.jsp,然后login.jsp又重新执行上面这段代码,那么将陷入死循环。

3、增加退出功能
退出功能做两件事:注销会话和删除cookies

点击(此处)折叠或打开

  1. HttpSession session = request.getSession();
  2. // 注销会话
  3. session.invalidate();
  4. Cookie[] cookies = request.getCookies();
  5.         
  6. if (cookies != null) {
  7.     for (int i = 0; i != cookies.length; i++) {
  8.         if (cookies[i].getName().equals("username")) {
  9.             // 在设置好cookie的生存时间后,要调用addCookie方法
  10.             cookies[i].setMaxAge(0);
  11.             response.addCookie(cookies[i]);
  12.         } else if (cookies[i].getName().equals("password")) {
  13.             cookies[i].setMaxAge(0);
  14.             response.addCookie(cookies[i]);
  15.         }
  16.     }
  17. }
  18.         
  19. response.sendRedirect("login.jsp");
4、中文编码问题
在留言时我发现存储不了中文,我用的是MySql,我要存储的字符串用的是gb2312编码,我以为在链接数据库时指定了同样的编码方式就可以了,如

点击(此处)折叠或打开

  1. conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/guest?" +
  2. "user=root&password=123&characterEncoding=gb2312");
但程序缺抛出异常信息
java.sql.SQLException: Incorrect string value: '\xD6\xD0\xCE\xC4' for column 'title' at row 1
好的,看来是MySql存储不了用gb2312编码的字符串了,登录MySql,输入命令 show create table message,可以发现这张表的charset是latin1,在网上找了些方法,最后决定把这张表删除,重新建这张表并且显示指定charset为gb2312。
可以存储中文之后又有一个问题,就是我在MySql中输入命令 select * from message时,发现中文都显示为“??”,输入命令 
show variables like 'character\_set\_%' 可以看到character-set-results的值是latin1,只要用 set character-set-results=gb2312 改变查询结果的编码就行了。

总结如下:最好在创建整个数据库的时候就指定编码方式,如 create database db character set utf-8; 推荐用UTF-8。
阅读(2229) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~