【Openfire】网页版的用户注册、登录、修改密码
来源:互联网 发布:解除root 知乎 编辑:程序博客网 时间:2024/04/27 21:32
Openfire客户端的开发是借助Smack提供的方法。Smack可以从官网下载。如果是Openfire3.7.1的版本,建议使用Smack3.2.2与其匹配。官网地址:http://www.igniterealtime.org/downloadServlet?filename=smack/smack_3_2_2.zip
下载之后解压,将里面的4个jar复制到网络工程WEB-INF下的lib文件夹,这样,即可以使用smack的api进行开发。
目标是做出如下样子的工程,在网页版提供用户注册、登录和密码修改的功能。
网络工程的目录结构如下:
web.xml,没什么好说的,仅仅是一些简单的struts2配置,没有其它任何的内容。
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"version="2.4"><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>
DB.java这是在《【Java】利用单例模式、可变参数优化Java操作Mysql数据库、JDBC代码的写作》(点击打开链接)我已经详细说明过的工具类,这里不再多说了。
package tool;import java.sql.*; import java.util.*; public class DB { // 一、单例初始化连接 private Connection con; // 以下代码,保证该类只能有一个实例 private DB() { try { Class.forName("com.mysql.jdbc.Driver"); // 其中test是我们要链接的数据库,user是数据库用户名,password是数据库密码。 // 3306是mysql的端口号,一般是这个 // 后面那串长长的参数是为了防止乱码,免去每次都需要在任何语句都加入一条SET NAMES UTF8 String url = "jdbc:mysql://localhost:3306/openfire?useUnicode=true&characterEncoding=utf8&useOldAliasMetadataBehavior=true"; String user = "root"; String password = "root"; con = DriverManager.getConnection(url, user, password); } catch (Exception e) { e.printStackTrace(); } } // 私有无参构造方法 // 在自己内部定义自己的一个实例,只供内部调用 private static DB db = null; // 这个类必须自动向整个系统提供这个实例对象 // 这里提供了一个供外部访问本class的静态方法,可以直接访问 public static DB getInstance() { if (db == null) { db = new DB(); } return db; } // 二、查询 // 使用SQL查询,查询的结果是一个结果集(视图) public List<Object[]> getBySql(String sql) { List<Object[]> result_list = new ArrayList<Object[]>(); try { PreparedStatement ps = con.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { ResultSetMetaData md = rs.getMetaData(); int columnCount = md.getColumnCount(); Object[] row_data_set = new Object[columnCount]; for (int i = 1; i <= columnCount; i++) { row_data_set[i - 1] = rs.getObject(i); } result_list.add(row_data_set); } return result_list; } catch (SQLException e) { e.printStackTrace(); return null; } } // 查询sql语句带参数的情况 public List<Object[]> getBySql(String sql, Object[] param) { List<Object[]> result_list = new ArrayList<Object[]>(); try { PreparedStatement ps = con.prepareStatement(sql); for (int i = 0; i < param.length; i++) { ps.setObject(i + 1, param[i]); } ResultSet rs = ps.executeQuery(); while (rs.next()) { ResultSetMetaData md = rs.getMetaData(); int columnCount = md.getColumnCount(); Object[] row_data_set = new Object[columnCount]; for (int i = 1; i <= columnCount; i++) { row_data_set[i - 1] = rs.getObject(i); } result_list.add(row_data_set); } return result_list; } catch (SQLException e) { e.printStackTrace(); return null; } } // 使用SQL查询,查询的结果是唯一 public Object getBySql_result_unique(String sql) { try { PreparedStatement ps = con.prepareStatement(sql); ResultSet rs = ps.executeQuery(); rs.next(); return rs.getObject(1); } catch (SQLException e) { e.printStackTrace(); return null; } } // 查询sql语句带参数的情况 public Object getBySql_result_unique(String sql, Object[] param) { try { PreparedStatement ps = con.prepareStatement(sql); for (int i = 0; i < param.length; i++) { ps.setObject(i + 1, param[i]); } ResultSet rs = ps.executeQuery(); rs.next(); return rs.getObject(1); } catch (SQLException e) { e.printStackTrace(); return null; } } // 三、增删改 // insert、update、delete等修改数据库的语句 public void setBySql(String sql) { try { PreparedStatement ps = con.prepareStatement(sql); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } // sql语句带参数的情况 public void setBySql(String sql, Object[] param) { try { PreparedStatement ps = con.prepareStatement(sql); for (int i = 0; i < param.length; i++) { ps.setObject(i + 1, param[i]); } ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } // 析构函数,中断数据库的连接 protected void finalize() throws Exception { if (!con.isClosed() || con != null) { con.close(); } } }
index.jsp也就是如上的效果截图,布局很简单,就三个表单指向相应action,<%@ page isELIgnored="false"%>是为了保证EL表达式,能够在Tomcat5.5使用。
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><%@ page isELIgnored="false"%><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>index</title></head><body>${msg}<hr><p>用户注册<br><form method="post" action="register">用户名:<input type="text" name="username" /><br>密码:<input type="password" name="password" /><br><input type="submit" value="注册" /></form></p><hr><p>用户登录<br><form method="post" action="login">用户名:<input type="text" name="username" /><br>密码:<input type="password" name="password" /><br><input type="submit" value="登录" /></form></p><hr><p>修改密码<br><form method="post" action="modify_password">用户名:<input type="text" name="username" /><br>旧密码:<input type="password" name="password" /><br>新密码:<input type="password" name="newpassword" /><br><input type="submit" value="修改" /></form></p></body></html>
chat.jsp是用户成功登录,所跳转的页面,很简单。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>聊天</title></head><body>欢迎,${sessionScope.username},<a href="logout">登出</a></body></html>
核心关键在于两个,一个是从Openfire源代码中拷贝过来的Blowfish.java,这个文件的详细说明请看《【Openfire】验证用户输入密码是否正确》(点击打开链接)。
这个文件很长,修改的地方,主要是里面关于org.slf4j记录日志的信息的注释掉,然后是对其42-53行的构造方法进行修改,这样以后用到就不用每次都要写代码,在数据库中查询ofproperty中passwordKey所对应的值。修改之后如下:
public Blowfish() {// 改过// hash down the password to a 160bit keyDB db = DB.getInstance();String password = (String) db.getBySql_result_unique("select propValue from ofproperty where name='passwordKey'");MessageDigest digest = null;try {digest = MessageDigest.getInstance("SHA1");digest.update(password.getBytes());} catch (Exception e) {// Log.error(e.getMessage(), e);}// setup the encryptor (use a dummy IV)m_bfish = new BlowfishCBC(digest.digest(), 0);digest.reset();}
最后,所有核心方法都在test.user这个类中。对照struts.xml所配的action:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"><struts><package name="test" extends="struts-default"><action name="register" class="test.user" method="register"><result name="success" type="redirect">/index.jsp</result></action> <action name="login" class="test.user" method="login"><result name="success" type="redirect">/chat.jsp</result><result name="input" type="redirect">/index.jsp</result></action><action name="logout" class="test.user" method="logout"><result name="success" type="redirect">/index.jsp</result></action><action name="modify_password" class="test.user" method="modify_password"><result name="success" type="redirect">/index.jsp</result></action></package></struts>这个user.java的代码如下:
package test;import java.util.Map;import org.jivesoftware.smack.AccountManager;import org.jivesoftware.smack.Connection;import org.jivesoftware.smack.ConnectionConfiguration;import org.jivesoftware.smack.XMPPConnection;import org.jivesoftware.smack.XMPPException;import tool.Blowfish;import tool.DB;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;public class user extends ActionSupport {private static final long serialVersionUID = 5570391705428296402L;private String username;private String password;private String newpassword;private String msg;// 判断输入的密码是否与数据库密码一致private boolean checkPassword(String username, String password) {Blowfish blowfish = new Blowfish();DB db = DB.getInstance();String db_password = (String) db.getBySql_result_unique("select encryptedPassword from ofuser where username=?",new Object[] { username });if (blowfish.decryptString(db_password).equals(password)) {return true;} else {return false;}}// 用户注册public String register() throws XMPPException {DB db = DB.getInstance();if (username.length() == 0) {msg = "用户名不得为空!";return SUCCESS;}if (db.getBySql("select * from ofuser where username=?",new Object[] { username }).size() > 0) {msg = "该用户名已经存在!";} else {ConnectionConfiguration config = new ConnectionConfiguration("127.0.0.1", 5222);Connection connection = new XMPPConnection(config);connection.connect();AccountManager amgr = connection.getAccountManager();amgr.createAccount(username, password);// 会自动使用Openfire的Blowfish编码加密密码。msg = "注册成功!";System.out.println("新用户注册:" + username + ",密码:" + password);connection.disconnect();}return SUCCESS;}// 用户登录public String login() throws XMPPException {if (checkPassword(username, password)) {msg = "登录成功!";ConnectionConfiguration config = new ConnectionConfiguration("127.0.0.1", 5222);Connection connection = new XMPPConnection(config);connection.connect();connection.login(username, password);Map session = ActionContext.getContext().getSession();session.put("username", username);session.put("connection", connection);return SUCCESS;} else {msg = "密码错误!";return INPUT;}}// 用户登出public String logout() {Map session = ActionContext.getContext().getSession();Connection connection = (Connection) session.get("connection");connection.disconnect();session.clear();return SUCCESS;}// 修改密码public String modify_password() throws XMPPException {if (checkPassword(username, password)) {ConnectionConfiguration config = new ConnectionConfiguration("127.0.0.1", 5222);Connection connection = new XMPPConnection(config);connection.connect();connection.login(username, password);// 登录之后才能修改密码connection.getAccountManager().changePassword(newpassword);System.out.println("用户:" + username + ",修改密码从:" + password + ",变为:"+ newpassword);connection.disconnect();msg = "修改成功!";} else {msg = "密码错误!";}return SUCCESS;}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 String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public String getNewpassword() {return newpassword;}public void setNewpassword(String newpassword) {this.newpassword = newpassword;}}
注册、登录、修改密码本来没有什么好说的,因为smack已经提供了一定量的api。
但是,由于smack并没有提供判断用户所输入密码是否正确的方法,只能自己手动到数据库,再配合Blowfish算法查询。如果密码是不正确的,直接利用connect.login方法的话,会直接报错,导致这个网络工程崩溃,try和catch也是没用的。所以在connect.login之前,需要自己查询用户输入的密码是否正确。
再有一点是,如果用户登录正确,那么这个connect对象就应该压入session,跟着他所登录的用户名一起走,为后续的聊天和加好友操作的提供依据,也就是以后的所有动作,最简单就是上面代码的登录,都要使用这个connection来操作,而不是自己再new一个。
- 【Openfire】网页版的用户注册、登录、修改密码
- openfire Android学习(一)----实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- 基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等
- Java事务--JTA原理
- smartCab报告
- LeetCode Symmetric Tree递归,迭代两种方法
- layer弹窗
- Scala数组操作
- 【Openfire】网页版的用户注册、登录、修改密码
- Android 从服务器获取信息 并显示 (包含服务器端代码)
- android点击Button,使字体变色
- 关于 hashCode() 你需要了解的 3 件事
- hibernate关于hql的左外连接查询
- lint代码检查工具
- HDOJ-1042 N!(大数乘法问题)
- 一道sql的笔试题
- 改善既有代码的设计(一)----------小案例展示重构的意义