首先,数据库新建两张表:loginlog 字段:id ,userID,logintime,success
第二张:t_table_id 字段table_name,value ;默认写入数据loginlog;0
1、Loginlog.java
package com.marcellotest.basedata.domain; /** * 用户登录日志 * @author Administrator * */ public class Loginlog { public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getLogintime() { return logintime; } public void setLogintime(String logintime) { this.logintime = logintime; } public int getSuccess() { return success; } public void setSuccess(int success) { this.success = success; } public void setLoginLogID(String loginLogID) { LoginLogID = loginLogID; } public String getLoginLogID() { return LoginLogID; } //主键 private String LoginLogID; private String userId; private String logintime; private int success; }
2、LoginlogManager.java
package com.marcellotest.basedata.manager; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.marcellotest.basedata.domain.Loginlog; import com.marcellotest.util.DBUtil; import com.marcellotest.util.generator.IDGenerator; public class LoginlogManager { private static LoginlogManager instance = null; private LoginlogManager() {} public static synchronized LoginlogManager getInstance() { if (instance == null) { instance = new LoginlogManager(); } return instance; } /** * 根据userid查询登录日志 * @param userid * @return 如果存在返回返回最后三次登录失败信息,否则返回null */ public List<String> findUserLOGById(String userID) { StringBuffer sbSql = new StringBuffer(); sbSql.append("select * from loginlog " ) .append("where userId =?" ) .append("and success = 0 " ) .append("and loginTime like ? ") .append("order by logintime DESC ") .append("limit 3 "); Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String today = dateFormat.format(now); List<String> list = new ArrayList<String>(); try { conn = DBUtil.getConnection(); pstmt = conn.prepareStatement(sbSql.toString()); pstmt.setString(1, userID); pstmt.setString(2,"%"+today+"%"); rs = pstmt.executeQuery(); while(rs.next()){ list.add(rs.getString("LoginLogID")); list.add(rs.getString("userid")); list.add(rs.getString("logintime")); list.add(rs.getString("success")); } }catch(SQLException e) { e.printStackTrace(); }finally { DBUtil.close(rs); DBUtil.close(pstmt); DBUtil.close(conn); } //System.out.println(list); return list; } /** * 添加log记录到数据库 * @param client */ public void addUserLOG(Loginlog Loginlog) { StringBuffer sbsql = new StringBuffer(); sbsql.append("insert into loginlog ( ") .append("LoginLogID, userID, loginTime, ") .append("success) ") .append("values (? ,? ,?, ?) "); Connection conn = null; PreparedStatement pstmt = null; Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String createDate = dateFormat.format(now); try { conn = DBUtil.getConnection(); //开启事务 DBUtil.setAutoCommit(conn, false); pstmt = conn.prepareStatement(sbsql.toString()); pstmt.setInt(1, (int)IDGenerator.getInstance().newID("loginlog")); pstmt.setString(2, Loginlog.getUserId()); pstmt.setString(3, createDate); pstmt.setInt(4, Loginlog.getSuccess()); pstmt.executeUpdate(); //提交事务 DBUtil.commit(conn); }catch(Exception e) { e.printStackTrace(); //回滚事务 DBUtil.rollback(conn); }finally { DBUtil.close(pstmt); DBUtil.close(conn); } } }
3、LoginlogUtil.java
package com.marcellotest.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.marcellotest.basedata.domain.Loginlog; import com.marcellotest.basedata.manager.LoginlogManager; public class LoginlogUtil { private static LoginlogUtil instance = null; private LoginlogUtil() {} public static synchronized LoginlogUtil getInstance() { if (instance == null) { instance = new LoginlogUtil(); } return instance; } static Loginlog Loginlog = new Loginlog(); /** * 添加日志信息 * @param userid * @return */ public void ADDloginlogItem(Loginlog loginlog) { Loginlog.setUserId(loginlog.getUserId()); Loginlog.setSuccess(loginlog.getSuccess()); LoginlogManager.getInstance().addUserLOG(Loginlog); } /** * 判断该用户名是否符合登录要求 * 5分钟内输错三次锁住该用户 */ public boolean SelectloginlogItem(Loginlog loginlog){ //把查询出来的数据放入list中 List<String> list = new ArrayList<String>(); list= LoginlogManager.getInstance().findUserLOGById(loginlog.getUserId()); boolean flag = false; System.out.println("个数"+list.size()); //循环 //for(String str : list){ // System.out.println(str); // } //判断是否含有3行数据,如果没有直接返回true if(list.size()<12){ flag = true; } else{ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { //现状的时间 Date now = new Date(); //最后一次输错时间 Date ErrorOne= df.parse(list.get(2)); //前三次输错时间 Date ErrorTree = df.parse(list.get(10)); //最后一次输错时间和目前尝试登陆时间 long spaceTIME = now.getTime()-ErrorOne.getTime(); long spaceTIMEmin = spaceTIME/1000; //最后三次间隔时间 long DifferTime=ErrorOne.getTime()-ErrorTree.getTime(); //long day=l/(24*60*60*1000); //long hour=(l/(60*60*1000)-day*24); //long min=((l/(60*1000))-day*24*60-hour*60); // long s=(l/1000-day*24*60*60-hour*60*60-min*60); //转换成秒进行比较 long s1=DifferTime/1000; //System.out.println(""+day+"天"+hour+"小时"+min+"分"+s+"秒"); System.out.println(s1); //判断时间是否间隔一个小时 if(spaceTIMEmin>=3600) { flag=true; } else{ //判断是否5分钟内输入三次错误; if(s1<=300){ flag = true; } else{ flag = false; } } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } //String a = list.get(2); //System.out.println(a); //String b = list.get(10); //System.out.println(b); } return flag; } public static void main(String[] args) { } }
生成唯一ID:IDGenerator.java
package com.marcellotest.util.generator; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.marcellotest.util.DBUtil; /** * id生成器,采用单例模式 * @author Administrator * */ public class IDGenerator { private static IDGenerator instance = new IDGenerator(); private IDGenerator() {} public static IDGenerator getInstance() { return instance; } /** * 生成新id * @param tableName * @return */ //public synchronized long newID(String tableName) { //synchronized(this) { public long newID(String tableName) { String sql = "select value from t_table_id where table_name=? for update"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; long value = 0L; try { conn = DBUtil.getConnection(); ////开启事务 DBUtil.setAutoCommit(conn, false); pstmt = conn.prepareStatement(sql); pstmt.setString(1, tableName); rs = pstmt.executeQuery(); if (rs.next()) { value = rs.getLong("value"); }else { throw new RuntimeException("生成Id出错!"); } value = value + 1; //更新value modifyValueField(conn, tableName, value); //提交事务 DBUtil.commit(conn); }catch(Exception e) { e.printStackTrace(); //回滚事务 DBUtil.rollback(conn); throw new RuntimeException("生成Id出错!"); }finally { DBUtil.close(rs); DBUtil.close(pstmt); DBUtil.close(conn); } return value; } /** * 更新value * @param conn * @param tableName * @param value * @throws SQLException */ private void modifyValueField(Connection conn, String tableName, long value) throws SQLException { String sql = "update t_table_id set value=? where table_name=?"; PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement(sql); pstmt.setLong(1, value); pstmt.setString(2, tableName); pstmt.executeUpdate(); }finally { DBUtil.close(pstmt); } } public static void main(String[] args) { long newId = IDGenerator.getInstance().newID("t_client"); System.out.println(newId); } }
登陆时调用
/** * * 登录(采用非受控异常) * @param userId * @param password */ public User login(String userId, String password) { CipherUtil cipher = new CipherUtil(); Loginlog loginlog = new Loginlog(); loginlog.setUserId(userId); //throws UserNotFoundException, PasswordNotCorrectException{ //必须抛出 User user = findUserById(userId); if (user == null) { System.out.println(user); throw new UserNotFoundException("用户代码不能找到,代码=【" + userId +"】"); } //采用加密方式 if (!user.getPassword().equals(cipher.generatePassword(password))) { //调用记录日志函数 loginlog.setSuccess(0); LoginlogManager.getInstance().addUserLOG(loginlog); throw new PasswordNotCorrectException("密码不正确"); } if(!LoginlogUtil.getInstance().SelectloginlogItem(loginlog)){ throw new PasswordNotCorrectException("一小时后再试试"); } System.out.println("user"); //调用记录日志函数 loginlog.setSuccess(1); LoginlogManager.getInstance().addUserLOG(loginlog); return user; }
有些人会说写入日志时在调用时:
loginlog.setUserId(userId);
loginlog.setSuccess(1);
业务逻辑层又一次,为什么不直接登陆时候直接调用;这边是为了把这些都分开,如果大公司,业务层,逻辑层都是分开的,就是说你登陆只能调用逻辑层;
最后调用时候的抛出异常类我没有继续写了,如果有需要根据实际情况写抛出;